diff --git a/.gn b/.gn
index b16586d55..c1b812e 100644
--- a/.gn
+++ b/.gn
@@ -18,6 +18,7 @@
   #"//apps/*",  # Medium-hard.
   "//ash/*",
   "//base/*",
+  "//blimp/*",
   "//blink/*",
   "//breakpad/*",
   "//build/*",
diff --git a/BUILD.gn b/BUILD.gn
index 000751bf..1cad2ba 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -600,6 +600,11 @@
       "//crypto:crypto_unittests",  # TODO(GYP)
       "//net:net_unittests",  # TODO(GYP)
     ]
+
+    if (!(is_component_build && is_debug && target_cpu == "x86")) {
+      deps +=
+          [ "//chrome/installer/mini_installer:next_version_mini_installer" ]
+    }
   } else if (!is_android && !is_ios) {
     deps += [ "//breakpad:symupload($host_toolchain)" ]
   }
@@ -633,17 +638,34 @@
   testonly = true
 
   deps = []
+  data_deps = []
+  data = []
 
   if (is_win || is_linux) {
-    deps += [
-      "//components/resource_provider:resource_provider_unittests",
-      "//mash:mash_unittests",
-      "//media/mojo/services:tests",
-      "//ui/views/mus:tests",
+    deps += [ "//services/shell/standalone" ]
+    data_deps = [
+      "//media/mojo/services:media_apptests",
+    ]
+    if (is_linux) {
+      data_deps += [ "//tools/xdisplaycheck" ]
+    }
+    data += [
+      "//mojo/tools/apptest_runner.py",
+      "//mojo/tools/data/apptests",
+      "//mojo/tools/mopy/",
+      "//testing/xvfb.py",
+      "//tools/swarming_client/utils/subprocess42.py",
     ]
   }
 }
 
+group("mojo_apptests_run") {
+  testonly = true
+  deps = [
+    ":mojo_apptests",
+  ]
+}
+
 group("gn_only") {
   testonly = true
 
diff --git a/DEPS b/DEPS
index 13e40394..360705e9 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': '85def2e0673f3b75c4500440b95ab3dac7435702',
+  'skia_revision': '219ac2bc091d8f7b0fbf586ada24af9a55e9ca45',
   # 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': 'b914d669ee4ce4a3056bfe3437b28728cfada6db',
+  'v8_revision': 'f79101b0f22458cb42f2188db987004143b2fd0e',
   # 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.
@@ -67,7 +67,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': 'a08142380981b366fb4f5eb61f9888f49342d388',
+  'boringssl_revision': '0a63b96535dff86fc226e3a13e34252e702a45d0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -83,7 +83,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': '45cbcfeb189c340a87f022578a4337583489a21d',
+  'nacl_revision': 'eec7648b9878417ea4f9f9628cf3340bd584bb5d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling dEQP
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '14d685ddb5b4f7d14db1a40248c636269da6fc07',
+  'catapult_revision': 'ec3f320c2852476e0acacafb5311c8ae0b068a53',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -189,16 +189,16 @@
    Var('chromium_git') + '/webm/libvpx.git' + '@' +  '83f17eeede83f138f34177121019798719d5be1c',
 
   'src/third_party/ffmpeg':
-   Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '01464a5194f066a2ea2016b02ca3ea2aad4e6376',
+   Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '40ac6f0443064be7cd085baf538e70fe2a9afc19',
 
   'src/third_party/libjingle/source/talk':
-    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'a3dc305df4e8b44cda3569eb77238b2f8cc0ba20', # commit position 12534
+    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '34c4b322551fc9352218fe1a85125e613175f0e7', # commit position 12556
 
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + 'c60ec8b35c3fe6027d7a3faae89d1c8d7dd3ce98',
 
   'src/third_party/libsrtp':
-   Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + '8aa6248aec48a9cb81ea44c759ca427f777eff1e', # from svn revision 295151
+   Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + 'ea4ed36c8fbe9ea581140e6672c975e5ed23367d', # from svn revision 295151
 
   'src/third_party/yasm/source/patched-yasm':
    Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '7da28c6c7c6a1387217352ce02b31754deb54d2a',
@@ -216,7 +216,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' + '@' + '57f37afa99e3897f88029ae0edd3c89ddcb73e8e', # commit position 12543
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '0d62df917ff5505612636c1e62f3b9cb491bef59', # commit position 12556
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -255,7 +255,7 @@
     Var('chromium_git') + '/external/github.com/CLD2Owners/cld2.git' + '@' + '84b58a5d7690ebf05a91406f371ce00c3daf31c0',
 
   'src/third_party/libwebm/source':
-   Var('chromium_git') + '/webm/libwebm.git' + '@' + '75a6d2da8b63e0c446ec0ce1ac942c2962d959d7',
+   Var('chromium_git') + '/webm/libwebm.git' + '@' + '9a235e0bc94319c5f7184bd69cbe5468a74a025c',
 
   'src/third_party/pdfium':
    'https://pdfium.googlesource.com/pdfium.git' + '@' +  Var('pdfium_revision'),
diff --git a/WATCHLISTS b/WATCHLISTS
index 5f67144..82ea8945 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1720,12 +1720,10 @@
     'blink_scheduler': [ 'scheduler-bugs@chromium.org' ],
     'blink_track': [ 'vcarbune@chromium.org',
                      'silviapf@chromium.org',
-                     'philipj@opera.com',
                      'glenn@chromium.org',
                      'fs@opera.com',
                      'eric.carlson@apple.com' ],
     'blink_media': [ 'feature-media-reviews@chromium.org',
-                     'philipj@opera.com',
                      'eric.carlson@apple.com',
                      'mlamouri+watch-blink@chromium.org' ],
     'blink_media_queries': [ 'kenneth.christiansen@gmail.com',
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index ab2e3a8..6285ace 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -663,6 +663,7 @@
     "java/src/org/chromium/android_webview/OverScrollGlow.java",
     "java/src/org/chromium/android_webview/PlatformServiceBridge.java",
     "java/src/org/chromium/android_webview/PostMessageSender.java",
+    "java/src/org/chromium/android_webview/ResourcesContextWrapperFactory.java",
     "java/src/org/chromium/android_webview/ScrollAccessibilityHelper.java",
     "java/src/org/chromium/android_webview/SslUtil.java",
     "java/src/org/chromium/android_webview/permission/AwGeolocationCallback.java",
diff --git a/android_webview/android_webview_test_data.isolate b/android_webview/android_webview_test_data.isolate
index 7436aca..18a5825 100644
--- a/android_webview/android_webview_test_data.isolate
+++ b/android_webview/android_webview_test_data.isolate
@@ -2,13 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 {
-  'conditions': [
-    ['OS=="android"', {
-      'variables': {
-        'files': [
-          '<(DEPTH)/android_webview/test/data/',
-        ],
-      },
-    }],
-  ],
+  'variables': {
+    'files': [
+      '<(DEPTH)/android_webview/test/data/',
+    ],
+  },
 }
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index 30b7aca..263a3303 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -13,6 +13,7 @@
   "+components/autofill/core/browser",
   "+components/autofill/core/common",
   "+components/cdm/browser",
+  "+components/cdm/common",
   "+components/crash/content/browser",
   "+components/data_reduction_proxy/core/browser",
   "+components/navigation_interception",
diff --git a/android_webview/browser/aw_media_client_android.h b/android_webview/browser/aw_media_client_android.h
index a2a6718..5f08d5b 100644
--- a/android_webview/browser/aw_media_client_android.h
+++ b/android_webview/browser/aw_media_client_android.h
@@ -6,7 +6,7 @@
 #define ANDROID_WEBVIEW_BROWSER_AW_MEDIA_CLIENT_ANDROID_H_
 
 #include "base/macros.h"
-#include "components/cdm/browser/widevine_drm_delegate_android.h"
+#include "components/cdm/common/widevine_drm_delegate_android.h"
 #include "media/base/android/media_client_android.h"
 
 namespace android_webview {
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn
index ac732bd..65646186 100644
--- a/android_webview/glue/BUILD.gn
+++ b/android_webview/glue/BUILD.gn
@@ -63,7 +63,6 @@
     "java/src/com/android/webview/chromium/GraphicsUtils.java",
     "java/src/com/android/webview/chromium/LicenseActivity.java",
     "java/src/com/android/webview/chromium/LicenseContentProvider.java",
-    "java/src/com/android/webview/chromium/ResourcesContextWrapperFactory.java",
     "java/src/com/android/webview/chromium/WebBackForwardListChromium.java",
     "java/src/com/android/webview/chromium/WebHistoryItemChromium.java",
     "java/src/com/android/webview/chromium/WebIconDatabaseAdapter.java",
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
index 56da948..809beecfe 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -54,6 +54,7 @@
 import org.chromium.android_webview.AwContentsStatics;
 import org.chromium.android_webview.AwPrintDocumentAdapter;
 import org.chromium.android_webview.AwSettings;
+import org.chromium.android_webview.ResourcesContextWrapperFactory;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.SuppressFBWarnings;
 import org.chromium.content.browser.SmartClipProvider;
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
index 4269b3a..78bff6b 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -42,6 +42,7 @@
 import org.chromium.android_webview.AwResource;
 import org.chromium.android_webview.AwSettings;
 import org.chromium.android_webview.R;
+import org.chromium.android_webview.ResourcesContextWrapperFactory;
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.MemoryPressureListener;
@@ -86,6 +87,7 @@
     private WebStorageAdapter mWebStorage;
     private WebViewDatabaseAdapter mWebViewDatabase;
     private AwDevToolsServer mDevToolsServer;
+    private Context mWrappedAppContext;
 
     private ArrayList<WeakReference<WebViewChromium>> mWebViewsToStart =
             new ArrayList<WeakReference<WebViewChromium>>();
@@ -114,11 +116,6 @@
     @SuppressFBWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME")
     private void initialize(WebViewDelegate webViewDelegate) {
         mWebViewDelegate = webViewDelegate;
-
-        // WebView needs to make sure to always use the wrapped application context.
-        ContextUtils.initApplicationContext(
-                ResourcesContextWrapperFactory.get(mWebViewDelegate.getApplication()));
-
         if (isBuildDebuggable()) {
             // Suppress the StrictMode violation as this codepath is only hit on debugglable builds.
             StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
@@ -130,7 +127,7 @@
 
         ThreadUtils.setWillOverrideUiThread();
         // Load chromium library.
-        AwBrowserProcess.loadLibrary(ContextUtils.getApplicationContext());
+        AwBrowserProcess.loadLibrary(getWrappedCurrentApplicationContext());
 
         final PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo();
 
@@ -267,7 +264,7 @@
             return;
         }
 
-        Context context = ContextUtils.getApplicationContext();
+        Context context = getWrappedCurrentApplicationContext();
         try {
             LibraryLoader.get(LibraryProcessType.PROCESS_WEBVIEW).ensureInitialized(context);
         } catch (ProcessInitException e) {
@@ -325,6 +322,14 @@
         }
     }
 
+    private Context getWrappedCurrentApplicationContext() {
+        if (mWrappedAppContext == null) {
+            mWrappedAppContext = ResourcesContextWrapperFactory.get(
+                    mWebViewDelegate.getApplication());
+        }
+        return mWrappedAppContext;
+    }
+
     AwBrowserContext getBrowserContext() {
         synchronized (mLock) {
             return getBrowserContextLocked();
@@ -336,7 +341,7 @@
         assert mStarted;
         if (mBrowserContext == null) {
             mBrowserContext =
-                    new AwBrowserContext(mWebViewPrefs, ContextUtils.getApplicationContext());
+                    new AwBrowserContext(mWebViewPrefs, getWrappedCurrentApplicationContext());
         }
         return mBrowserContext;
     }
@@ -446,6 +451,13 @@
     public CookieManager getCookieManager() {
         synchronized (mLock) {
             if (mCookieManager == null) {
+                if (!mStarted) {
+                    // We can use CookieManager without starting Chromium; the native code
+                    // will bring up just the parts it needs to make this work on a temporary
+                    // basis until Chromium is started for real. The temporary cookie manager
+                    // needs the application context to have been set.
+                    ContextUtils.initApplicationContext(getWrappedCurrentApplicationContext());
+                }
                 mCookieManager = new CookieManagerAdapter(new AwCookieManager());
             }
         }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/ResourcesContextWrapperFactory.java b/android_webview/java/src/org/chromium/android_webview/ResourcesContextWrapperFactory.java
similarity index 97%
rename from android_webview/glue/java/src/com/android/webview/chromium/ResourcesContextWrapperFactory.java
rename to android_webview/java/src/org/chromium/android_webview/ResourcesContextWrapperFactory.java
index 510cfc4..8b986fb9 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/ResourcesContextWrapperFactory.java
+++ b/android_webview/java/src/org/chromium/android_webview/ResourcesContextWrapperFactory.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package com.android.webview.chromium;
+package org.chromium.android_webview;
 
 import android.content.ComponentCallbacks;
 import android.content.Context;
@@ -10,7 +10,6 @@
 import android.content.Intent;
 import android.view.LayoutInflater;
 
-import org.chromium.android_webview.AwContents;
 import org.chromium.base.annotations.SuppressFBWarnings;
 
 import java.lang.ref.WeakReference;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
index 61d9dd9..993e988 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
@@ -4,14 +4,14 @@
 
 package org.chromium.android_webview.test;
 
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
-
 import android.app.Instrumentation;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.os.Build;
 import android.util.Log;
 
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
 import org.chromium.android_webview.AwBrowserContext;
 import org.chromium.android_webview.AwBrowserProcess;
 import org.chromium.android_webview.AwContents;
@@ -20,7 +20,6 @@
 import org.chromium.android_webview.AwSwitches;
 import org.chromium.android_webview.test.util.GraphicsTestUtils;
 import org.chromium.android_webview.test.util.JSUtils;
-import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.BaseActivityInstrumentationTestCase;
 import org.chromium.base.test.util.CommandLineFlags;
@@ -80,11 +79,10 @@
 
     @Override
     protected void setUp() throws Exception {
-        Context appContext = getInstrumentation().getTargetContext().getApplicationContext();
-        mBrowserContext = new AwBrowserContext(new InMemorySharedPreferences(), appContext);
+        mBrowserContext = new AwBrowserContext(
+                new InMemorySharedPreferences(), getInstrumentation().getTargetContext());
 
         super.setUp();
-        ContextUtils.initApplicationContext(appContext);
         if (needsBrowserProcessStarted()) {
             startBrowserProcess();
         }
@@ -100,10 +98,8 @@
         });
     }
 
-    /**
-     * Override this to return false if the test doesn't want the browser startup sequence to
+    /* Override this to return false if the test doesn't want the browser startup sequence to
      * be run automatically.
-     * @return Whether the instrumentation test requires the browser process to already be started.
      */
     protected boolean needsBrowserProcessStarted() {
         return true;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
index 9cb017f..6505102 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
@@ -14,6 +14,7 @@
 import org.chromium.android_webview.AwWebResourceResponse;
 import org.chromium.android_webview.test.util.CommonResources;
 import org.chromium.android_webview.test.util.CookieUtils;
+import org.chromium.base.ContextUtils;
 import org.chromium.base.test.util.Feature;
 import org.chromium.net.test.util.TestWebServer;
 
@@ -29,10 +30,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        // CookeManager assumes that native is loaded, but webview browser should not be loaded for
-        // these tests as webview is not necessarily loaded when CookieManager is called.
-        AwBrowserProcess.loadLibrary(
-                getInstrumentation().getTargetContext().getApplicationContext());
+        ContextUtils.initApplicationContext(getActivity().getApplicationContext());
     }
 
     @Override
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
index 55083d0..ebde6683 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/HttpCacheTest.java
@@ -10,7 +10,6 @@
 import org.chromium.android_webview.AwBrowserProcess;
 import org.chromium.android_webview.AwContents;
 import org.chromium.android_webview.AwContentsStatics;
-import org.chromium.base.ContextUtils;
 import org.chromium.base.PathUtils;
 import org.chromium.base.test.util.Feature;
 import org.chromium.net.test.util.TestWebServer;
@@ -83,7 +82,6 @@
         assertTrue(dummyCacheFile.exists());
 
         // Set up JNI bindings.
-        ContextUtils.initApplicationContext(targetContext.getApplicationContext());
         AwBrowserProcess.loadLibrary(targetContext);
         // No delay before removing the legacy cache files.
         AwContentsStatics.setLegacyCacheRemovalDelayForTest(0);
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index d799c847..eaceec5 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -218,8 +218,8 @@
   return visited_link_slave_->IsVisited(link_hash);
 }
 
-void AwContentRendererClient::AddKeySystems(
-    std::vector<media::KeySystemInfo>* key_systems) {
+void AwContentRendererClient::AddSupportedKeySystems(
+    std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
   AwAddKeySystems(key_systems);
 }
 
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h
index e3a963a..91382420 100644
--- a/android_webview/renderer/aw_content_renderer_client.h
+++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -36,7 +36,9 @@
   unsigned long long VisitedLinkHash(const char* canonical_url,
                                      size_t length) override;
   bool IsLinkVisited(unsigned long long link_hash) override;
-  void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
+  void AddSupportedKeySystems(
+      std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
+      override;
 
   bool HandleNavigation(content::RenderFrame* render_frame,
                         bool is_content_initiated,
diff --git a/android_webview/renderer/aw_key_systems.cc b/android_webview/renderer/aw_key_systems.cc
index cc3059e..6a81cb1 100644
--- a/android_webview/renderer/aw_key_systems.cc
+++ b/android_webview/renderer/aw_key_systems.cc
@@ -7,10 +7,10 @@
 
 namespace android_webview {
 
-void AwAddKeySystems(
-    std::vector<media::KeySystemInfo>* key_systems_info) {
-  cdm::AddAndroidWidevine(key_systems_info);
-  cdm::AddAndroidPlatformKeySystems(key_systems_info);
+void AwAddKeySystems(std::vector<std::unique_ptr<media::KeySystemProperties>>*
+                         key_systems_properties) {
+  cdm::AddAndroidWidevine(key_systems_properties);
+  cdm::AddAndroidPlatformKeySystems(key_systems_properties);
 }
 
 }  // namespace android_webview
diff --git a/android_webview/renderer/aw_key_systems.h b/android_webview/renderer/aw_key_systems.h
index 4bed8b61..ea15f325 100644
--- a/android_webview/renderer/aw_key_systems.h
+++ b/android_webview/renderer/aw_key_systems.h
@@ -5,13 +5,15 @@
 #ifndef ANDROID_WEBVIEW_RENDERER_AW_KEY_SYSTEMS_H_
 #define ANDROID_WEBVIEW_RENDERER_AW_KEY_SYSTEMS_H_
 
+#include <memory>
 #include <vector>
 
-#include "media/base/key_system_info.h"
+#include "media/base/key_system_properties.h"
 
 namespace android_webview {
 
-void AwAddKeySystems(std::vector<media::KeySystemInfo>* key_systems_info);
+void AwAddKeySystems(std::vector<std::unique_ptr<media::KeySystemProperties>>*
+                         key_systems_properties);
 
 }  // namespace android_webview
 
diff --git a/android_webview/system_webview_shell_test_apk.isolate b/android_webview/system_webview_shell_test_apk.isolate
index 15f2a84897..dbea4bd 100644
--- a/android_webview/system_webview_shell_test_apk.isolate
+++ b/android_webview/system_webview_shell_test_apk.isolate
@@ -3,17 +3,13 @@
 # found in the LICENSE file.
 
 {
-  'conditions': [
-    ['OS=="android"', {
-      'variables': {
-        'files': [
-          '<(DEPTH)/android_webview/tools/system_webview_shell/test/data/',
-          '<(DEPTH)/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt',
-          '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/global-interface-listing.html',
-          '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt',
-          '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/resources/global-interface-listing.js',
-        ],
-      },
-    }],
-  ],
-}
\ No newline at end of file
+  'variables': {
+    'files': [
+      '<(DEPTH)/android_webview/tools/system_webview_shell/test/data/',
+      '<(DEPTH)/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt',
+      '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/global-interface-listing.html',
+      '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt',
+      '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/resources/global-interface-listing.js',
+    ],
+  },
+}
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java
index c3d4ccb..d87b6302 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestRunnerActivity.java
@@ -13,7 +13,6 @@
 
 import org.chromium.android_webview.AwBrowserProcess;
 import org.chromium.android_webview.shell.AwShellResourceProvider;
-import org.chromium.base.ContextUtils;
 
 /**
  * This is a lightweight activity for tests that only require WebView functionality.
@@ -29,7 +28,6 @@
         super.onCreate(savedInstanceState);
 
         AwShellResourceProvider.registerResources(this);
-        ContextUtils.initApplicationContext(getApplicationContext());
         AwBrowserProcess.loadLibrary(this);
 
         mLinearLayout = new LinearLayout(this);
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc
index 08343df8..1001727 100644
--- a/ash/accelerators/accelerator_controller.cc
+++ b/ash/accelerators/accelerator_controller.cc
@@ -44,7 +44,7 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/web_notification/web_notification_tray.h"
 #include "ash/touch/touch_hud_debug.h"
-#include "ash/utility/partial_screenshot_controller.h"
+#include "ash/utility/screenshot_controller.h"
 #include "ash/volume_control_delegate.h"
 #include "ash/wm/common/window_state.h"
 #include "ash/wm/common/wm_event.h"
@@ -460,22 +460,18 @@
   ime_control_delegate->HandleSwitchIme(accelerator);
 }
 
-void HandleTakeActiveWindowScreenshot(ScreenshotDelegate* screenshot_delegate) {
+void HandleTakeWindowScreenshot(ScreenshotDelegate* screenshot_delegate) {
   base::RecordAction(UserMetricsAction("Accel_Take_Window_Screenshot"));
-  aura::Window* active_window = wm::GetActiveWindow();
-  if (!active_window)
-    return;
   DCHECK(screenshot_delegate);
-  if (screenshot_delegate->CanTakeScreenshot())
-    screenshot_delegate->HandleTakeWindowScreenshot(active_window);
+  Shell::GetInstance()->screenshot_controller()->StartWindowScreenshotSession(
+      screenshot_delegate);
 }
 
 void HandleTakePartialScreenshot(ScreenshotDelegate* screenshot_delegate) {
   base::RecordAction(UserMetricsAction("Accel_Take_Partial_Screenshot"));
   DCHECK(screenshot_delegate);
-  Shell::GetInstance()
-      ->partial_screenshot_controller()
-      ->StartPartialScreenshotSession(screenshot_delegate);
+  Shell::GetInstance()->screenshot_controller()->StartPartialScreenshotSession(
+      screenshot_delegate);
 }
 
 void HandleTakeScreenshot(ScreenshotDelegate* screenshot_delegate) {
@@ -1090,7 +1086,7 @@
     case SHOW_KEYBOARD_OVERLAY:
     case SHOW_SYSTEM_TRAY_BUBBLE:
     case SHOW_TASK_MANAGER:
-    case TAKE_ACTIVE_WINDOW_SCREENSHOT:
+    case TAKE_WINDOW_SCREENSHOT:
     case TAKE_PARTIAL_SCREENSHOT:
     case TAKE_SCREENSHOT:
     case TOGGLE_FULLSCREEN:
@@ -1262,8 +1258,8 @@
     case SWITCH_IME:
       HandleSwitchIme(ime_control_delegate_.get(), accelerator);
       break;
-    case TAKE_ACTIVE_WINDOW_SCREENSHOT:
-      HandleTakeActiveWindowScreenshot(screenshot_delegate_.get());
+    case TAKE_WINDOW_SCREENSHOT:
+      HandleTakeWindowScreenshot(screenshot_delegate_.get());
       break;
     case TAKE_PARTIAL_SCREENSHOT:
       HandleTakePartialScreenshot(screenshot_delegate_.get());
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index 37b74e7..0c359a0 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -860,17 +860,6 @@
     EXPECT_TRUE(ProcessInController(ui::Accelerator(
         ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)));
     EXPECT_EQ(2, delegate->handle_take_screenshot_count());
-    // None active window test case.
-    EXPECT_TRUE(ProcessInController(ui::Accelerator(
-        ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN)));
-    EXPECT_EQ(0, delegate->handle_take_window_screenshot_count());
-    // Active window test case.
-    std::unique_ptr<aura::Window> window;
-    window.reset(CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20)));
-    wm::ActivateWindow(window.get());
-    EXPECT_TRUE(ProcessInController(ui::Accelerator(
-        ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN)));
-    EXPECT_EQ(1, delegate->handle_take_window_screenshot_count());
   }
   const ui::Accelerator volume_mute(ui::VKEY_VOLUME_MUTE, ui::EF_NONE);
   const ui::Accelerator volume_down(ui::VKEY_VOLUME_DOWN, ui::EF_NONE);
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index f31143a..fefa8e424 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -37,7 +37,7 @@
   { true, ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
     TAKE_PARTIAL_SCREENSHOT },
   { true, ui::VKEY_MEDIA_LAUNCH_APP1, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
-    TAKE_ACTIVE_WINDOW_SCREENSHOT },
+    TAKE_WINDOW_SCREENSHOT },
   { true, ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE, BRIGHTNESS_DOWN },
   { true, ui::VKEY_BRIGHTNESS_DOWN, ui::EF_ALT_DOWN, KEYBOARD_BRIGHTNESS_DOWN },
   { true, ui::VKEY_BRIGHTNESS_UP, ui::EF_NONE, BRIGHTNESS_UP },
@@ -350,7 +350,7 @@
   SCALE_UI_RESET,
   SHOW_SYSTEM_TRAY_BUBBLE,
   SWITCH_IME,  // Switch to another IME depending on the accelerator.
-  TAKE_ACTIVE_WINDOW_SCREENSHOT,
+  TAKE_WINDOW_SCREENSHOT,
   TAKE_PARTIAL_SCREENSHOT,
   TAKE_SCREENSHOT,
 #if defined(OS_CHROMEOS)
@@ -406,7 +406,7 @@
   SCALE_UI_RESET,
   SHOW_KEYBOARD_OVERLAY,
   SWITCH_IME,
-  TAKE_ACTIVE_WINDOW_SCREENSHOT,
+  TAKE_WINDOW_SCREENSHOT,
   TAKE_PARTIAL_SCREENSHOT,
   TAKE_SCREENSHOT,
 #if defined(OS_CHROMEOS)
@@ -447,7 +447,7 @@
     SCALE_UI_UP,
     SCALE_UI_DOWN,
     SCALE_UI_RESET,
-    TAKE_ACTIVE_WINDOW_SCREENSHOT,
+    TAKE_WINDOW_SCREENSHOT,
     TAKE_PARTIAL_SCREENSHOT,
     TAKE_SCREENSHOT,
     TOGGLE_FULLSCREEN,
@@ -531,7 +531,7 @@
     PREVIOUS_IME,
     PRINT_UI_HIERARCHIES,
     SWITCH_IME,
-    TAKE_ACTIVE_WINDOW_SCREENSHOT,
+    TAKE_WINDOW_SCREENSHOT,
     TAKE_PARTIAL_SCREENSHOT,
     TAKE_SCREENSHOT,
 #if defined(OS_CHROMEOS)
diff --git a/ash/accelerators/accelerator_table.h b/ash/accelerators/accelerator_table.h
index e89e707..8d38364 100644
--- a/ash/accelerators/accelerator_table.h
+++ b/ash/accelerators/accelerator_table.h
@@ -99,7 +99,7 @@
   SHOW_SYSTEM_TRAY_BUBBLE,
   SHOW_TASK_MANAGER,
   SWITCH_IME,  // Switch to another IME depending on the accelerator.
-  TAKE_ACTIVE_WINDOW_SCREENSHOT,
+  TAKE_WINDOW_SCREENSHOT,
   TAKE_PARTIAL_SCREENSHOT,
   TAKE_SCREENSHOT,
   TOGGLE_APP_LIST,
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 2612050f..48c0b2e3 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -519,8 +519,8 @@
       'touch/touch_uma.h',
       'touch/touchscreen_util.cc',
       'touch/touchscreen_util.h',
-      'utility/partial_screenshot_controller.cc',
-      'utility/partial_screenshot_controller.h',
+      'utility/screenshot_controller.cc',
+      'utility/screenshot_controller.h',
       'virtual_keyboard_controller.cc',
       'virtual_keyboard_controller.h',
       'volume_control_delegate.h',
@@ -562,6 +562,8 @@
       'wm/common/shelf/wm_shelf_constants.h',
       'wm/common/shelf/wm_shelf_observer.h',
       'wm/common/shelf/wm_shelf_types.h',
+      'wm/common/shelf/wm_shelf_util.cc',
+      'wm/common/shelf/wm_shelf_util.h',
       'wm/common/switchable_windows.cc',
       'wm/common/switchable_windows.h',
       'wm/common/window_animation_types.h',
@@ -595,6 +597,7 @@
       'wm/common/wm_snap_to_pixel_layout_manager.h',
       'wm/common/wm_types.cc',
       'wm/common/wm_types.h',
+      'wm/common/wm_user_metrics_action.h',
       'wm/common/wm_window.h',
       'wm/common/wm_window_observer.h',
       'wm/common/wm_window_property.h',
@@ -951,7 +954,7 @@
       'touch/touch_observer_hud_unittest.cc',
       'touch/touch_transformer_controller_unittest.cc',
       'touch/touchscreen_util_unittest.cc',
-      'utility/partial_screenshot_controller_unittest.cc',
+      'utility/screenshot_controller_unittest.cc',
       'virtual_keyboard_controller_unittest.cc',
       'wm/always_on_top_controller_unittest.cc',
       'wm/ash_focus_rules_unittest.cc',
@@ -1069,6 +1072,7 @@
           'dependencies': [
             '../build/linux/system.gyp:x11',
             '../build/linux/system.gyp:xfixes',
+            '../ui/base/x/ui_base_x.gyp:ui_base_x',
             '../ui/events/devices/x11/events_devices_x11.gyp:events_devices_x11',
             '../ui/gfx/x/gfx_x11.gyp:gfx_x11',
            ],
diff --git a/ash/display/display_manager.cc b/ash/display/display_manager.cc
index 4317cc17..08616aa 100644
--- a/ash/display/display_manager.cc
+++ b/ash/display/display_manager.cc
@@ -6,6 +6,8 @@
 
 #include <algorithm>
 #include <cmath>
+#include <limits>
+#include <map>
 #include <set>
 #include <string>
 #include <utility>
@@ -41,7 +43,7 @@
 #include "ui/gfx/geometry/size_conversions.h"
 
 #if defined(USE_X11)
-#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util.h"  // nogncheck
 #endif
 
 #if defined(OS_CHROMEOS)
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc
index 1c7103ef..b8a2a6e9 100644
--- a/ash/display/window_tree_host_manager.cc
+++ b/ash/display/window_tree_host_manager.cc
@@ -51,7 +51,7 @@
 #include "ui/wm/public/activation_client.h"
 
 #if defined(USE_X11)
-#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util.h"  // nogncheck
 #include "ui/gfx/x/x11_types.h"  // nogncheck
 
 // Including this at the bottom to avoid other
diff --git a/ash/metrics/user_metrics_recorder.cc b/ash/metrics/user_metrics_recorder.cc
index cadf7101..e07afe8 100644
--- a/ash/metrics/user_metrics_recorder.cc
+++ b/ash/metrics/user_metrics_recorder.cc
@@ -15,6 +15,7 @@
 #include "ash/shell_window_ids.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/wm/common/window_state.h"
+#include "ash/wm/common/wm_user_metrics_action.h"
 #include "ash/wm/window_state_aura.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/user_metrics.h"
@@ -242,12 +243,6 @@
       task_switch_metrics_recorder_.OnTaskSwitch(
           TaskSwitchMetricsRecorder::DESKTOP);
       break;
-    case ash::UMA_DRAG_MAXIMIZE_LEFT:
-      base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeLeft"));
-      break;
-    case ash::UMA_DRAG_MAXIMIZE_RIGHT:
-      base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeRight"));
-      break;
     case ash::UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE:
       base::RecordAction(
           base::UserMetricsAction("Launcher_ButtonPressed_Mouse"));
@@ -608,6 +603,18 @@
   }
 }
 
+void UserMetricsRecorder::RecordUserMetricsAction(
+    wm::WmUserMetricsAction action) {
+  switch (action) {
+    case wm::WmUserMetricsAction::DRAG_MAXIMIZE_LEFT:
+      base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeLeft"));
+      break;
+    case wm::WmUserMetricsAction::DRAG_MAXIMIZE_RIGHT:
+      base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeRight"));
+      break;
+  }
+}
+
 void UserMetricsRecorder::OnShellInitialized() {
   // Lazy creation of the DesktopTaskSwitchMetricRecorder because it accesses
   // Shell::GetInstance() which is not available when |this| is instantiated.
diff --git a/ash/metrics/user_metrics_recorder.h b/ash/metrics/user_metrics_recorder.h
index 35d6a9b..f372920 100644
--- a/ash/metrics/user_metrics_recorder.h
+++ b/ash/metrics/user_metrics_recorder.h
@@ -20,6 +20,10 @@
 class UserMetricsRecorderTestAPI;
 }
 
+namespace wm {
+enum class WmUserMetricsAction;
+}
+
 enum UserMetricsAction {
   UMA_ACCEL_EXIT_FIRST_Q,
   UMA_ACCEL_EXIT_SECOND_Q,
@@ -33,8 +37,6 @@
   UMA_ACCEL_SHUT_DOWN_POWER_BUTTON,
   UMA_CLOSE_THROUGH_CONTEXT_MENU,
   UMA_DESKTOP_SWITCH_TASK,
-  UMA_DRAG_MAXIMIZE_LEFT,
-  UMA_DRAG_MAXIMIZE_RIGHT,
   UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE,
   UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH,
   UMA_LAUNCHER_CLICK_ON_APP,
@@ -155,6 +157,7 @@
 
   // Records an Ash owned user action.
   void RecordUserMetricsAction(ash::UserMetricsAction action);
+  void RecordUserMetricsAction(wm::WmUserMetricsAction action);
 
   TaskSwitchMetricsRecorder& task_switch_metrics_recorder() {
     return task_switch_metrics_recorder_;
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 314d9cdb..7febc28 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -443,7 +443,7 @@
 
 void RootWindowController::OnShelfCreated() {
   if (panel_layout_manager_)
-    panel_layout_manager_->SetShelf(shelf_->shelf());
+    panel_layout_manager_->SetShelf(shelf_->shelf()->wm_shelf());
   if (docked_layout_manager_) {
     docked_layout_manager_->SetShelf(shelf_->shelf()->wm_shelf());
     if (shelf_->shelf_layout_manager())
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h
index 517de7f..e37ec6c 100644
--- a/ash/root_window_controller.h
+++ b/ash/root_window_controller.h
@@ -77,6 +77,10 @@
 // The RootWindowController for particular root window is stored in
 // its property (RootWindowSettings) and can be obtained using
 // |GetRootWindowController(aura::WindowEventDispatcher*)| function.
+//
+// NOTE: In classic ash there is one RootWindow per display, so every RootWindow
+// has a RootWindowController. In mus/mash there is one RootWindow per top-level
+// Widget, so not all RootWindows have a RootWindowController.
 class ASH_EXPORT RootWindowController : public ShellObserver {
  public:
   // Creates and Initialize the RootWindowController for primary display.
diff --git a/ash/shelf/overflow_bubble.cc b/ash/shelf/overflow_bubble.cc
index 226bf59a..19f460cf 100644
--- a/ash/shelf/overflow_bubble.cc
+++ b/ash/shelf/overflow_bubble.cc
@@ -4,13 +4,12 @@
 
 #include "ash/shelf/overflow_bubble.h"
 
-#include "ash/root_window_controller.h"
 #include "ash/shelf/overflow_bubble_view.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shelf/shelf_view.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
-#include "ash/system/tray/system_tray.h"
+#include "ash/system/tray/tray_background_view.h"
 #include "ui/aura/client/screen_position_client.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/events/event.h"
@@ -36,10 +35,10 @@
   shelf_view_ = shelf_view;
   anchor_ = anchor;
 
+  // TODO(jamescook): Change this to a PointerWatcher.
   Shell::GetInstance()->AddPreTargetHandler(this);
 
-  RootWindowController::ForWindow(anchor->GetWidget()->GetNativeView())->
-      GetSystemTray()->InitializeBubbleAnimations(bubble_->GetWidget());
+  TrayBackgroundView::InitializeBubbleAnimations(bubble_->GetWidget());
   bubble_->GetWidget()->AddObserver(this);
   bubble_->GetWidget()->Show();
 }
diff --git a/ash/shelf/shelf.cc b/ash/shelf/shelf.cc
index b564286..4124981 100644
--- a/ash/shelf/shelf.cc
+++ b/ash/shelf/shelf.cc
@@ -22,6 +22,7 @@
 #include "ash/shell_delegate.h"
 #include "ash/shell_window_ids.h"
 #include "ash/wm/aura/wm_shelf_aura.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ash/wm/window_properties.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
@@ -90,7 +91,7 @@
 }
 
 bool Shelf::IsHorizontalAlignment() const {
-  return ash::IsHorizontalAlignment(alignment_);
+  return wm::IsHorizontalAlignment(alignment_);
 }
 
 void Shelf::SetAutoHideBehavior(ShelfAutoHideBehavior auto_hide_behavior) {
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index efb1a93..a24e6a0 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -25,6 +25,7 @@
 #include "ash/shell_window_ids.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/wm/aura/wm_window_aura.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ash/wm/common/window_state.h"
 #include "ash/wm/common/wm_root_window_controller.h"
 #include "ash/wm/common/wm_root_window_controller_observer.h"
@@ -229,13 +230,16 @@
       gesture_drag_auto_hide_state_(SHELF_AUTO_HIDE_SHOWN),
       update_shelf_observer_(NULL),
       chromevox_panel_height_(0),
-      duration_override_in_ms_(0),
-      root_window_controller_observer_(
-          new RootWindowControllerObserverImpl(this)) {
+      duration_override_in_ms_(0) {
   Shell::GetInstance()->AddShellObserver(this);
-  wm::WmWindowAura::Get(root_window_)
-      ->GetRootWindowController()
-      ->AddObserver(root_window_controller_observer_.get());
+
+  if (!Shell::GetInstance()->in_mus()) {
+    root_window_controller_observer_.reset(
+        new RootWindowControllerObserverImpl(this));
+    wm::WmWindowAura::Get(root_window_)
+        ->GetRootWindowController()
+        ->AddObserver(root_window_controller_observer_.get());
+  }
   Shell::GetInstance()->lock_state_controller()->AddObserver(this);
   aura::client::GetActivationClient(root_window_)->AddObserver(this);
   Shell::GetInstance()->session_state_delegate()->AddSessionStateObserver(this);
@@ -250,9 +254,11 @@
   Shell::GetInstance()->lock_state_controller()->RemoveObserver(this);
   Shell::GetInstance()->
       session_state_delegate()->RemoveSessionStateObserver(this);
-  wm::WmWindowAura::Get(root_window_)
-      ->GetRootWindowController()
-      ->RemoveObserver(root_window_controller_observer_.get());
+  if (root_window_controller_observer_) {
+    wm::WmWindowAura::Get(root_window_)
+        ->GetRootWindowController()
+        ->RemoveObserver(root_window_controller_observer_.get());
+  }
 }
 
 void ShelfLayoutManager::PrepareForShutdown() {
@@ -528,7 +534,7 @@
 }
 
 bool ShelfLayoutManager::IsHorizontalAlignment() const {
-  return ash::IsHorizontalAlignment(GetAlignment());
+  return wm::IsHorizontalAlignment(GetAlignment());
 }
 
 void ShelfLayoutManager::SetChromeVoxPanelHeight(int height) {
diff --git a/ash/shelf/shelf_types.h b/ash/shelf/shelf_types.h
index d3b6a9a4..e680920 100644
--- a/ash/shelf/shelf_types.h
+++ b/ash/shelf/shelf_types.h
@@ -21,17 +21,6 @@
   SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
 };
 
-enum ShelfVisibilityState {
-  // Always visible.
-  SHELF_VISIBLE,
-
-  // A couple of pixels are reserved at the bottom for the shelf.
-  SHELF_AUTO_HIDE,
-
-  // Nothing is shown. Used for fullscreen windows.
-  SHELF_HIDDEN,
-};
-
 enum ShelfAutoHideState {
   SHELF_AUTO_HIDE_SHOWN,
   SHELF_AUTO_HIDE_HIDDEN,
diff --git a/ash/shelf/shelf_util.cc b/ash/shelf/shelf_util.cc
index 41c5000..70fa02b 100644
--- a/ash/shelf/shelf_util.cc
+++ b/ash/shelf/shelf_util.cc
@@ -58,9 +58,4 @@
   return window->GetProperty(kShelfItemDetailsKey);
 }
 
-bool IsHorizontalAlignment(wm::ShelfAlignment alignment) {
-  return alignment == wm::SHELF_ALIGNMENT_BOTTOM ||
-         alignment == wm::SHELF_ALIGNMENT_BOTTOM_LOCKED;
-}
-
 }  // namespace ash
diff --git a/ash/shelf/shelf_util.h b/ash/shelf/shelf_util.h
index 32dd9fa..a55b526 100644
--- a/ash/shelf/shelf_util.h
+++ b/ash/shelf/shelf_util.h
@@ -55,9 +55,6 @@
 ASH_EXPORT const ShelfItemDetails* GetShelfItemDetailsForWindow(
     aura::Window* window);
 
-// Returns true if the shelf |alignment| is horizontal.
-ASH_EXPORT bool IsHorizontalAlignment(wm::ShelfAlignment alignment);
-
 }  // namespace ash
 
 #endif  // ASH_SHELF_SHELF_UTIL_H_
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc
index 2bb1015..7ac803a2 100644
--- a/ash/shelf/shelf_widget.cc
+++ b/ash/shelf/shelf_widget.cc
@@ -20,6 +20,7 @@
 #include "ash/shell_window_ids.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/wm/common/shelf/wm_shelf_constants.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ash/wm/status_area_layout_manager.h"
 #include "ash/wm/window_properties.h"
 #include "ash/wm/workspace_controller.h"
@@ -181,7 +182,7 @@
   gfx::ImageSkia shelf_background =
       *rb->GetImageNamed(IDR_ASH_SHELF_DIMMING).ToImageSkia();
 
-  if (!IsHorizontalAlignment(shelf_->GetAlignment())) {
+  if (!wm::IsHorizontalAlignment(shelf_->GetAlignment())) {
     shelf_background = gfx::ImageSkiaOperations::CreateRotatedImage(
         shelf_background, shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_LEFT
                               ? SkBitmapOperations::ROTATION_90_CW
@@ -451,7 +452,7 @@
   ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
   gfx::ImageSkia shelf_background =
       *rb->GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND);
-  const bool horizontal = IsHorizontalAlignment(shelf_->GetAlignment());
+  const bool horizontal = wm::IsHorizontalAlignment(shelf_->GetAlignment());
   if (!horizontal) {
     shelf_background = gfx::ImageSkiaOperations::CreateRotatedImage(
         shelf_background, shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_LEFT
diff --git a/ash/shell.cc b/ash/shell.cc
index c558897d..5218bbc 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -57,7 +57,7 @@
 #include "ash/system/toast/toast_manager.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/utility/partial_screenshot_controller.h"
+#include "ash/utility/screenshot_controller.h"
 #include "ash/wm/ash_focus_rules.h"
 #include "ash/wm/ash_native_cursor_manager.h"
 #include "ash/wm/aura/wm_globals_aura.h"
@@ -810,7 +810,7 @@
   resolution_notification_controller_.reset();
 #endif
   desktop_background_controller_.reset();
-  partial_screenshot_controller_.reset();
+  screenshot_controller_.reset();
   mouse_cursor_filter_.reset();
 
 #if defined(OS_CHROMEOS)
@@ -1036,11 +1036,11 @@
   AddShellObserver(lock_state_controller_.get());
 
   drag_drop_controller_.reset(new DragDropController);
-  // |partial_screenshot_controller_| needs to be created (and prepended as a
+  // |screenshot_controller_| needs to be created (and prepended as a
   // pre-target handler) at this point, because |mouse_cursor_filter_| needs to
-  // process mouse events prior to partial screenshot session.
+  // process mouse events prior to screenshot session.
   // See http://crbug.com/459214
-  partial_screenshot_controller_.reset(new PartialScreenshotController());
+  screenshot_controller_.reset(new ScreenshotController());
   mouse_cursor_filter_.reset(new MouseCursorEventFilter());
   PrependPreTargetHandler(mouse_cursor_filter_.get());
 
diff --git a/ash/shell.h b/ash/shell.h
index ec2e2c1b..6a5894d 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -119,7 +119,6 @@
 class NewWindowDelegate;
 class OverlayEventFilter;
 class PartialMagnificationController;
-class PartialScreenshotController;
 class PointerWatcherDelegate;
 class PowerButtonController;
 class PowerEventObserver;
@@ -130,6 +129,7 @@
 class ScopedTargetRootWindow;
 class ScreenAsh;
 class ScreenOrientationController;
+class ScreenshotController;
 class ScreenPositionController;
 class SessionStateDelegate;
 class Shelf;
@@ -405,8 +405,8 @@
     return touch_transformer_controller_.get();
   }
 #endif  // defined(OS_CHROMEOS)
-  PartialScreenshotController* partial_screenshot_controller() {
-    return partial_screenshot_controller_.get();
+  ScreenshotController* screenshot_controller() {
+    return screenshot_controller_.get();
   }
   MouseCursorEventFilter* mouse_cursor_filter() {
     return mouse_cursor_filter_.get();
@@ -718,7 +718,7 @@
 
   aura::client::ActivationClient* activation_client_;
 
-  std::unique_ptr<PartialScreenshotController> partial_screenshot_controller_;
+  std::unique_ptr<ScreenshotController> screenshot_controller_;
 
   std::unique_ptr<MouseCursorEventFilter> mouse_cursor_filter_;
   std::unique_ptr<ScreenPositionController> screen_position_controller_;
diff --git a/ash/shell_window_ids.h b/ash/shell_window_ids.h
index 5b011f9..a94c681 100644
--- a/ash/shell_window_ids.h
+++ b/ash/shell_window_ids.h
@@ -47,8 +47,8 @@
 // wm_shell_window_ids.
 // kShellWindowId_DockedContainer = 8;
 
-// The container for the shelf.
-const int kShellWindowId_ShelfContainer = 9;
+// The container for the shelf. Defined in wm_shell_window_ids.
+// kShellWindowId_ShelfContainer = 9;
 
 // The container for bubbles which float over the shelf.
 const int kShellWindowId_ShelfBubbleContainer = 10;
@@ -94,7 +94,8 @@
 const int kShellWindowId_OverlayContainer = 22;
 
 // ID of the window created by PhantomWindowController or DragWindowController.
-const int kShellWindowId_PhantomWindow = 23;
+// Defined in wm_shell_window_ids.
+// kShellWindowId_PhantomWindow = 23;
 
 // The container for mouse cursor.
 const int kShellWindowId_MouseCursorContainer = 24;
@@ -120,6 +121,12 @@
                    kShellWindowId_ShelfContainer),
               "docked between always-on-top and shelf");
 
+static_assert((kShellWindowId_ShelfContainer - 1 ==
+               kShellWindowId_DockedContainer) &&
+                  (kShellWindowId_ShelfContainer + 1 ==
+                   kShellWindowId_ShelfBubbleContainer),
+              "shelf between docked and shelf-bubble");
+
 static_assert((kShellWindowId_PanelContainer - 1 ==
                kShellWindowId_ShelfBubbleContainer) &&
                   (kShellWindowId_PanelContainer + 1 ==
@@ -132,6 +139,12 @@
                    kShellWindowId_SystemModalContainer),
               "app-list between panel and system-modal");
 
+static_assert((kShellWindowId_PhantomWindow - 1 ==
+               kShellWindowId_OverlayContainer) &&
+                  (kShellWindowId_PhantomWindow + 1 ==
+                   kShellWindowId_MouseCursorContainer),
+              "phanton between overlay and mouse-cursor");
+
 }  // namespace ash
 
 #endif  // ASH_SHELL_WINDOW_IDS_H_
diff --git a/ash/system/cast/tray_cast.cc b/ash/system/cast/tray_cast.cc
index 102c864..9a7bcce 100644
--- a/ash/system/cast/tray_cast.cc
+++ b/ash/system/cast/tray_cast.cc
@@ -21,6 +21,7 @@
 #include "ash/system/tray/tray_item_more.h"
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_popup_label_button.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "base/bind.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
@@ -358,7 +359,7 @@
 
 void CastTrayView::UpdateAlignment(wm::ShelfAlignment alignment) {
   // Center the item dependent on the orientation of the shelf.
-  views::BoxLayout::Orientation layout = IsHorizontalAlignment(alignment)
+  views::BoxLayout::Orientation layout = wm::IsHorizontalAlignment(alignment)
                                              ? views::BoxLayout::kVertical
                                              : views::BoxLayout::kHorizontal;
   SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0));
diff --git a/ash/system/chromeos/network/tray_network.cc b/ash/system/chromeos/network/tray_network.cc
index eeb86d5a..27c735c 100644
--- a/ash/system/chromeos/network/tray_network.cc
+++ b/ash/system/chromeos/network/tray_network.cc
@@ -17,6 +17,7 @@
 #include "ash/system/tray/tray_item_more.h"
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_utils.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "base/command_line.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chromeos/network/network_state.h"
@@ -92,7 +93,7 @@
   }
 
   void UpdateAlignment(wm::ShelfAlignment alignment) {
-    SetLayoutManager(new views::BoxLayout(IsHorizontalAlignment(alignment)
+    SetLayoutManager(new views::BoxLayout(wm::IsHorizontalAlignment(alignment)
                                               ? views::BoxLayout::kHorizontal
                                               : views::BoxLayout::kVertical,
                                           0, 0, 0));
diff --git a/ash/system/chromeos/screen_security/screen_tray_item.cc b/ash/system/chromeos/screen_security/screen_tray_item.cc
index c1efaf1..6322824b 100644
--- a/ash/system/chromeos/screen_security/screen_tray_item.cc
+++ b/ash/system/chromeos/screen_security/screen_tray_item.cc
@@ -7,6 +7,7 @@
 #include "ash/shelf/shelf_util.h"
 #include "ash/system/tray/fixed_sized_image_view.h"
 #include "ash/system/tray/tray_constants.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/message_center/message_center.h"
 #include "ui/views/controls/label.h"
@@ -189,7 +190,7 @@
     return;
 
   // Center the item dependent on the orientation of the shelf.
-  views::BoxLayout::Orientation layout = IsHorizontalAlignment(alignment)
+  views::BoxLayout::Orientation layout = wm::IsHorizontalAlignment(alignment)
                                              ? views::BoxLayout::kHorizontal
                                              : views::BoxLayout::kVertical;
   tray_view_->SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0));
diff --git a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
index 93cefc8..09451cc 100644
--- a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
+++ b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
@@ -13,6 +13,7 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_utils.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -61,7 +62,7 @@
   // Square up the padding if horizontally aligned. Avoid extra padding when
   // vertically aligned as the button would violate the width constraint on the
   // shelf.
-  if (IsHorizontalAlignment(alignment)) {
+  if (wm::IsHorizontalAlignment(alignment)) {
     gfx::Insets insets = button_->GetInsets();
     int additional_padding = std::max(0, top_padding - left_padding);
     left_padding += additional_padding;
diff --git a/ash/system/date/tray_date.cc b/ash/system/date/tray_date.cc
index 052a1aed..9b7f5bc 100644
--- a/ash/system/date/tray_date.cc
+++ b/ash/system/date/tray_date.cc
@@ -11,6 +11,7 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/tray/tray_item_view.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 
 #if defined(OS_CHROMEOS)
 #include "ash/system/chromeos/system_clock_observer.h"
@@ -95,8 +96,9 @@
 
 void TrayDate::UpdateAfterShelfAlignmentChange(wm::ShelfAlignment alignment) {
   if (time_tray_) {
-    ClockLayout clock_layout =
-        IsHorizontalAlignment(alignment) ? HORIZONTAL_CLOCK : VERTICAL_CLOCK;
+    ClockLayout clock_layout = wm::IsHorizontalAlignment(alignment)
+                                   ? HORIZONTAL_CLOCK
+                                   : VERTICAL_CLOCK;
     time_tray_->UpdateClockLayout(clock_layout);
   }
 }
diff --git a/ash/system/overview/overview_button_tray.cc b/ash/system/overview/overview_button_tray.cc
index 8a77d68..4b152b3 100644
--- a/ash/system/overview/overview_button_tray.cc
+++ b/ash/system/overview/overview_button_tray.cc
@@ -10,6 +10,7 @@
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "ash/system/tray/tray_utils.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
 #include "ash/wm/overview/window_selector_controller.h"
 #include "grit/ash_resources.h"
@@ -104,7 +105,7 @@
 }
 
 void OverviewButtonTray::SetIconBorderForShelfAlignment() {
-  if (IsHorizontalAlignment(shelf_alignment())) {
+  if (wm::IsHorizontalAlignment(shelf_alignment())) {
     icon_->SetBorder(views::Border::CreateEmptyBorder(
         kHorizontalShelfVerticalPadding,
         kHorizontalShelfHorizontalPadding,
diff --git a/ash/system/status_area_widget_delegate.cc b/ash/system/status_area_widget_delegate.cc
index c87869a..322e68d 100644
--- a/ash/system/status_area_widget_delegate.cc
+++ b/ash/system/status_area_widget_delegate.cc
@@ -11,6 +11,7 @@
 #include "ash/shell.h"
 #include "ash/shell_window_ids.h"
 #include "ash/system/tray/tray_constants.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/compositor/layer.h"
@@ -113,7 +114,7 @@
   SetLayoutManager(layout);
 
   views::ColumnSet* columns = layout->AddColumnSet(0);
-  if (IsHorizontalAlignment(alignment_)) {
+  if (wm::IsHorizontalAlignment(alignment_)) {
     bool is_first_visible_child = true;
     for (int c = 0; c < child_count(); ++c) {
       views::View* child = child_at(c);
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc
index d77b65a..5e65db2 100644
--- a/ash/system/tray/system_tray.cc
+++ b/ash/system/tray/system_tray.cc
@@ -25,6 +25,7 @@
 #include "ash/system/user/tray_user.h"
 #include "ash/system/user/tray_user_separator.h"
 #include "ash/system/web_notification/web_notification_tray.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/timer/timer.h"
@@ -317,7 +318,7 @@
 
   // Items default to SHELF_ALIGNMENT_BOTTOM. Update them if the initial
   // position of the shelf differs.
-  if (!IsHorizontalAlignment(shelf_alignment()))
+  if (!wm::IsHorizontalAlignment(shelf_alignment()))
     UpdateAfterShelfAlignmentChange(shelf_alignment());
 
   SetVisible(true);
@@ -417,7 +418,7 @@
 
 int SystemTray::GetTrayXOffset(SystemTrayItem* item) const {
   // Don't attempt to align the arrow if the shelf is on the left or right.
-  if (!IsHorizontalAlignment(shelf_alignment()))
+  if (!wm::IsHorizontalAlignment(shelf_alignment()))
     return TrayBubbleView::InitParams::kArrowDefaultOffset;
 
   std::map<SystemTrayItem*, views::View*>::const_iterator it =
@@ -711,7 +712,7 @@
     if (event.IsMouseEvent() || event.type() == ui::ET_GESTURE_TAP) {
       const ui::LocatedEvent& located_event =
           static_cast<const ui::LocatedEvent&>(event);
-      if (IsHorizontalAlignment(shelf_alignment())) {
+      if (wm::IsHorizontalAlignment(shelf_alignment())) {
         gfx::Point point(located_event.x(), 0);
         ConvertPointToWidget(this, &point);
         arrow_offset = point.x();
diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc
index a36c3ad..1f2cf262 100644
--- a/ash/system/tray/tray_background_view.cc
+++ b/ash/system/tray/tray_background_view.cc
@@ -16,6 +16,7 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_event_filter.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ash/wm/window_animations.h"
 #include "base/command_line.h"
 #include "grit/ash_resources.h"
@@ -193,7 +194,7 @@
 void TrayBackgroundView::TrayContainer::UpdateLayout() {
   // Adjust the size of status tray dark background by adding additional
   // empty border.
-  if (IsHorizontalAlignment(alignment_)) {
+  if (wm::IsHorizontalAlignment(alignment_)) {
     SetBorder(views::Border::CreateEmptyBorder(
         kPaddingFromEdgeOfShelf,
         kPaddingFromEdgeOfShelf,
@@ -264,6 +265,17 @@
   SetTrayBorder();
 }
 
+// static
+void TrayBackgroundView::InitializeBubbleAnimations(
+    views::Widget* bubble_widget) {
+  aura::Window* window = bubble_widget->GetNativeWindow();
+  ::wm::SetWindowVisibilityAnimationType(
+      window, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
+  ::wm::SetWindowVisibilityAnimationTransition(window, ::wm::ANIMATE_HIDE);
+  ::wm::SetWindowVisibilityAnimationDuration(
+      window, base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs));
+}
+
 void TrayBackgroundView::SetVisible(bool visible) {
   if (visible == layer()->GetTargetVisibility())
     return;
@@ -404,7 +416,7 @@
   // Tray views are laid out right-to-left or bottom-to-top
   bool on_edge = (this == parent->child_at(0));
   int left_edge, top_edge, right_edge, bottom_edge;
-  if (IsHorizontalAlignment(shelf_alignment())) {
+  if (wm::IsHorizontalAlignment(shelf_alignment())) {
     top_edge = ShelfLayoutManager::kShelfItemInset;
     left_edge = 0;
     bottom_edge = kShelfSize -
@@ -451,25 +463,13 @@
 
 void TrayBackgroundView::HideTransformation() {
   gfx::Transform transform;
-  if (IsHorizontalAlignment(shelf_alignment_))
+  if (wm::IsHorizontalAlignment(shelf_alignment_))
     transform.Translate(width(), 0.0f);
   else
     transform.Translate(0.0f, height());
   layer()->SetTransform(transform);
 }
 
-void TrayBackgroundView::InitializeBubbleAnimations(
-    views::Widget* bubble_widget) {
-  ::wm::SetWindowVisibilityAnimationType(
-      bubble_widget->GetNativeWindow(),
-      ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
-  ::wm::SetWindowVisibilityAnimationTransition(bubble_widget->GetNativeWindow(),
-                                               ::wm::ANIMATE_HIDE);
-  ::wm::SetWindowVisibilityAnimationDuration(
-      bubble_widget->GetNativeWindow(),
-      base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs));
-}
-
 aura::Window* TrayBackgroundView::GetBubbleWindowContainer() const {
   return ash::Shell::GetContainer(
       tray_container()->GetWidget()->GetNativeWindow()->GetRootWindow(),
diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h
index ecf84044..2aecdd5 100644
--- a/ash/system/tray/tray_background_view.h
+++ b/ash/system/tray/tray_background_view.h
@@ -68,6 +68,9 @@
   // Called after the tray has been added to the widget containing it.
   virtual void Initialize();
 
+  // Initializes animations for the bubble.
+  static void InitializeBubbleAnimations(views::Widget* bubble_widget);
+
   // views::View:
   void SetVisible(bool visible) override;
   const char* GetClassName() const override;
@@ -116,9 +119,6 @@
   void SetPaintsBackground(bool value,
                            BackgroundAnimatorChangeType change_type);
 
-  // Initializes animations for the bubble.
-  void InitializeBubbleAnimations(views::Widget* bubble_widget);
-
   // Returns the window hosting the bubble.
   aura::Window* GetBubbleWindowContainer() const;
 
diff --git a/ash/system/tray/tray_bubble_wrapper.cc b/ash/system/tray/tray_bubble_wrapper.cc
index 6b6eb4b..f904cb2 100644
--- a/ash/system/tray/tray_bubble_wrapper.cc
+++ b/ash/system/tray/tray_bubble_wrapper.cc
@@ -22,7 +22,7 @@
   bubble_widget_ = views::BubbleDialogDelegateView::CreateBubble(bubble_view_);
   bubble_widget_->AddObserver(this);
 
-  tray_->InitializeBubbleAnimations(bubble_widget_);
+  TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
   tray_->UpdateBubbleViewArrow(bubble_view_);
   bubble_view_->InitializeAndShowBubble();
 
diff --git a/ash/system/tray/tray_image_item.cc b/ash/system/tray/tray_image_item.cc
index fc5d750d6..5a4475ac 100644
--- a/ash/system/tray/tray_image_item.cc
+++ b/ash/system/tray/tray_image_item.cc
@@ -8,6 +8,7 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/tray_item_view.h"
 #include "ash/system/tray/tray_utils.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/image/image.h"
 #include "ui/views/controls/image_view.h"
@@ -75,7 +76,7 @@
 
 void TrayImageItem::SetItemAlignment(wm::ShelfAlignment alignment) {
   // Center the item dependent on the orientation of the shelf.
-  views::BoxLayout::Orientation layout = IsHorizontalAlignment(alignment)
+  views::BoxLayout::Orientation layout = wm::IsHorizontalAlignment(alignment)
                                              ? views::BoxLayout::kHorizontal
                                              : views::BoxLayout::kVertical;
   tray_view_->SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0));
diff --git a/ash/system/tray/tray_item_view.cc b/ash/system/tray/tray_item_view.cc
index 829360f..0897e96 100644
--- a/ash/system/tray/tray_item_view.cc
+++ b/ash/system/tray/tray_item_view.cc
@@ -8,6 +8,7 @@
 #include "ash/shelf/shelf_util.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_item.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/animation/slide_animation.h"
 #include "ui/views/controls/image_view.h"
@@ -86,13 +87,13 @@
 
 gfx::Size TrayItemView::GetPreferredSize() const {
   gfx::Size size = DesiredSize();
-  if (IsHorizontalAlignment(owner()->system_tray()->shelf_alignment()))
+  if (wm::IsHorizontalAlignment(owner()->system_tray()->shelf_alignment()))
     size.set_height(kTrayIconHeight);
   else
     size.set_width(kTrayIconWidth);
   if (!animation_.get() || !animation_->is_animating())
     return size;
-  if (IsHorizontalAlignment(owner()->system_tray()->shelf_alignment())) {
+  if (wm::IsHorizontalAlignment(owner()->system_tray()->shelf_alignment())) {
     size.set_width(std::max(1,
         static_cast<int>(size.width() * animation_->GetCurrentValue())));
   } else {
@@ -112,7 +113,7 @@
 
 void TrayItemView::AnimationProgressed(const gfx::Animation* animation) {
   gfx::Transform transform;
-  if (IsHorizontalAlignment(owner()->system_tray()->shelf_alignment())) {
+  if (wm::IsHorizontalAlignment(owner()->system_tray()->shelf_alignment())) {
     transform.Translate(0, animation->CurrentValueBetween(
         static_cast<double>(height()) / 2, 0.));
   } else {
diff --git a/ash/system/tray/tray_utils.cc b/ash/system/tray/tray_utils.cc
index 35252946..bd6009d8 100644
--- a/ash/system/tray/tray_utils.cc
+++ b/ash/system/tray/tray_utils.cc
@@ -7,6 +7,7 @@
 #include "ash/shelf/shelf_util.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_item_view.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ui/accessibility/ax_view_state.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/geometry/vector2d.h"
@@ -27,7 +28,7 @@
 
 void SetTrayImageItemBorder(views::View* tray_view,
                             wm::ShelfAlignment alignment) {
-  if (IsHorizontalAlignment(alignment)) {
+  if (wm::IsHorizontalAlignment(alignment)) {
     tray_view->SetBorder(views::Border::CreateEmptyBorder(
         0, kTrayImageItemHorizontalPaddingBottomAlignment, 0,
         kTrayImageItemHorizontalPaddingBottomAlignment));
@@ -42,7 +43,7 @@
 
 void SetTrayLabelItemBorder(TrayItemView* tray_view,
                             wm::ShelfAlignment alignment) {
-  if (IsHorizontalAlignment(alignment)) {
+  if (wm::IsHorizontalAlignment(alignment)) {
     tray_view->SetBorder(views::Border::CreateEmptyBorder(
         0, kTrayLabelItemHorizontalPaddingBottomAlignment, 0,
         kTrayLabelItemHorizontalPaddingBottomAlignment));
diff --git a/ash/system/user/tray_user.cc b/ash/system/user/tray_user.cc
index 9ec90db..ac9691b 100644
--- a/ash/system/user/tray_user.cc
+++ b/ash/system/user/tray_user.cc
@@ -18,6 +18,7 @@
 #include "ash/system/tray/tray_utils.h"
 #include "ash/system/user/rounded_image_view.h"
 #include "ash/system/user/user_view.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "base/logging.h"
 #include "base/strings/string16.h"
 #include "components/signin/core/account_id/account_id.h"
@@ -192,7 +193,7 @@
   // Inactive users won't have a layout.
   if (!layout_view_)
     return;
-  if (IsHorizontalAlignment(alignment)) {
+  if (wm::IsHorizontalAlignment(alignment)) {
     if (avatar_) {
       avatar_->SetBorder(views::Border::NullBorder());
       avatar_->SetCornerRadii(
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc
index 91ae20c3..52504ed 100644
--- a/ash/system/web_notification/web_notification_tray.cc
+++ b/ash/system/web_notification/web_notification_tray.cc
@@ -19,6 +19,7 @@
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_utils.h"
 #include "ash/system/web_notification/ash_popup_alignment_delegate.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "base/auto_reset.h"
 #include "base/i18n/number_formatting.h"
 #include "base/i18n/rtl.h"
@@ -223,7 +224,7 @@
   // Assume the status area and bubble bottoms are aligned when vertical.
   aura::Window* status_area_window = status_area_widget()->GetNativeView();
   const int max_height =
-      IsHorizontalAlignment(GetShelfLayoutManager()->GetAlignment())
+      wm::IsHorizontalAlignment(GetShelfLayoutManager()->GetAlignment())
           ? GetShelfLayoutManager()->GetIdealBounds().y()
           : status_area_window->GetBoundsInRootWindow().bottom();
 
diff --git a/ash/test/test_screenshot_delegate.cc b/ash/test/test_screenshot_delegate.cc
index a5d86ae..6a11b9f 100644
--- a/ash/test/test_screenshot_delegate.cc
+++ b/ash/test/test_screenshot_delegate.cc
@@ -10,8 +10,8 @@
 TestScreenshotDelegate::TestScreenshotDelegate()
     : handle_take_screenshot_count_(0),
       handle_take_partial_screenshot_count_(0),
-      handle_take_window_screenshot_count_(0),
-      can_take_screenshot_(true) {
+      can_take_screenshot_(true),
+      selected_window_(nullptr) {
 }
 
 TestScreenshotDelegate::~TestScreenshotDelegate() {
@@ -28,12 +28,18 @@
 }
 
 void TestScreenshotDelegate::HandleTakeWindowScreenshot(aura::Window* window) {
-  handle_take_window_screenshot_count_++;
+  selected_window_ = window;
 }
 
 bool TestScreenshotDelegate::CanTakeScreenshot() {
   return can_take_screenshot_;
 }
 
+const aura::Window* TestScreenshotDelegate::GetSelectedWindowAndReset() {
+  aura::Window* result = selected_window_;
+  selected_window_ = nullptr;
+  return result;
+}
+
 }  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_screenshot_delegate.h b/ash/test/test_screenshot_delegate.h
index 6b94940..1db8072 100644
--- a/ash/test/test_screenshot_delegate.h
+++ b/ash/test/test_screenshot_delegate.h
@@ -33,12 +33,10 @@
     return handle_take_partial_screenshot_count_;
   }
 
-  int handle_take_window_screenshot_count() const {
-    return handle_take_window_screenshot_count_;
-  }
-
   const gfx::Rect& last_rect() const { return last_rect_; }
 
+  const aura::Window* GetSelectedWindowAndReset();
+
   void set_can_take_screenshot(bool can_take_screenshot) {
     can_take_screenshot_ = can_take_screenshot;
   }
@@ -46,9 +44,9 @@
  private:
   int handle_take_screenshot_count_;
   int handle_take_partial_screenshot_count_;
-  int handle_take_window_screenshot_count_;
   gfx::Rect last_rect_;
   bool can_take_screenshot_;
+  aura::Window* selected_window_;
 
   DISALLOW_COPY_AND_ASSIGN(TestScreenshotDelegate);
 };
diff --git a/ash/utility/partial_screenshot_controller.cc b/ash/utility/partial_screenshot_controller.cc
deleted file mode 100644
index 0d5c6b7..0000000
--- a/ash/utility/partial_screenshot_controller.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/utility/partial_screenshot_controller.h"
-
-#include <cmath>
-
-#include "ash/display/mouse_cursor_event_filter.h"
-#include "ash/screenshot_delegate.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "base/stl_util.h"
-#include "ui/compositor/paint_recorder.h"
-#include "ui/display/screen.h"
-#include "ui/events/event.h"
-#include "ui/events/event_handler.h"
-#include "ui/gfx/canvas.h"
-#include "ui/wm/core/cursor_manager.h"
-
-namespace ash {
-
-namespace {
-
-// The size to increase the invalidated area in the layer to repaint. The area
-// should be slightly bigger than the actual region because the region indicator
-// rectangles are drawn outside of the selected region.
-const int kInvalidateRegionAdditionalSize = 3;
-
-// This will prevent the user from taking a screenshot across multiple
-// monitors. it will stop the mouse at the any edge of the screen. must
-// swtich back on when the screenshot is complete.
-void EnableMouseWarp(bool enable) {
-  Shell::GetInstance()->mouse_cursor_filter()->set_mouse_warp_enabled(enable);
-}
-
-}  // namespace
-
-class PartialScreenshotController::PartialScreenshotLayer
-    : public ui::LayerOwner,
-      public ui::LayerDelegate {
- public:
-  PartialScreenshotLayer(ui::Layer* parent) {
-    SetLayer(new ui::Layer(ui::LAYER_TEXTURED));
-    layer()->SetFillsBoundsOpaquely(false);
-    layer()->SetBounds(parent->bounds());
-    parent->Add(layer());
-    parent->StackAtTop(layer());
-    layer()->SetVisible(true);
-    layer()->set_delegate(this);
-  }
-  ~PartialScreenshotLayer() override {}
-
-  const gfx::Rect& region() const { return region_; }
-
-  void SetRegion(const gfx::Rect& region) {
-    // Invalidates the region which covers the current and new region.
-    gfx::Rect union_rect(region_);
-    union_rect.Union(region);
-    union_rect.Inset(-kInvalidateRegionAdditionalSize,
-                     -kInvalidateRegionAdditionalSize);
-    union_rect.Intersects(layer()->bounds());
-
-    region_ = region;
-    layer()->SchedulePaint(union_rect);
-  }
-
- private:
-  // ui::LayerDelegate:
-  void OnPaintLayer(const ui::PaintContext& context) override {
-    if (region_.IsEmpty())
-      return;
-
-    // Screenshot area representation: black rectangle with white
-    // rectangle inside.  To avoid capturing these rectangles when mouse
-    // release, they should be outside of the actual capturing area.
-    gfx::Rect rect(region_);
-    ui::PaintRecorder recorder(context, layer()->size());
-    rect.Inset(-1, -1);
-    recorder.canvas()->DrawRect(rect, SK_ColorWHITE);
-    rect.Inset(-1, -1);
-    recorder.canvas()->DrawRect(rect, SK_ColorBLACK);
-  }
-
-  void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
-
-  void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
-
-  base::Closure PrepareForLayerBoundsChange() override {
-    return base::Closure();
-  }
-
-  gfx::Rect region_;
-
-  DISALLOW_COPY_AND_ASSIGN(PartialScreenshotLayer);
-};
-
-class PartialScreenshotController::ScopedCursorSetter {
- public:
-  ScopedCursorSetter(::wm::CursorManager* cursor_manager,
-                     gfx::NativeCursor cursor)
-      : cursor_manager_(nullptr) {
-    if (cursor_manager->IsCursorLocked())
-      return;
-    gfx::NativeCursor original_cursor = cursor_manager->GetCursor();
-    cursor_manager_ = cursor_manager;
-    cursor_manager_->SetCursor(cursor);
-    if (!cursor_manager_->IsCursorVisible())
-      cursor_manager_->ShowCursor();
-    cursor_manager_->LockCursor();
-    // SetCursor does not make any effects at this point but it sets back to
-    // the original cursor when unlocked.
-    cursor_manager_->SetCursor(original_cursor);
-  }
-
-  ~ScopedCursorSetter() {
-    if (cursor_manager_)
-      cursor_manager_->UnlockCursor();
-  }
-
- private:
-  ::wm::CursorManager* cursor_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedCursorSetter);
-};
-
-PartialScreenshotController::PartialScreenshotController()
-    : root_window_(nullptr), screenshot_delegate_(nullptr) {
-  // Keep this here and don't move it to StartPartialScreenshotSession(), as it
-  // needs to be pre-pended by MouseCursorEventFilter in Shell::Init().
-  Shell::GetInstance()->PrependPreTargetHandler(this);
-}
-
-PartialScreenshotController::~PartialScreenshotController() {
-  if (screenshot_delegate_)
-    Cancel();
-  Shell::GetInstance()->RemovePreTargetHandler(this);
-}
-
-void PartialScreenshotController::StartPartialScreenshotSession(
-    ScreenshotDelegate* screenshot_delegate) {
-  // Already in a screenshot session.
-  if (screenshot_delegate_) {
-    DCHECK_EQ(screenshot_delegate_, screenshot_delegate);
-    return;
-  }
-
-  screenshot_delegate_ = screenshot_delegate;
-  display::Screen::GetScreen()->AddObserver(this);
-  for (aura::Window* root : Shell::GetAllRootWindows()) {
-    layers_[root] = new PartialScreenshotLayer(
-        Shell::GetContainer(root, kShellWindowId_OverlayContainer)->layer());
-  }
-
-  cursor_setter_.reset(new ScopedCursorSetter(
-      Shell::GetInstance()->cursor_manager(), ui::kCursorCross));
-
-  EnableMouseWarp(false);
-}
-
-void PartialScreenshotController::MaybeStart(const ui::LocatedEvent& event) {
-  aura::Window* current_root =
-      static_cast<aura::Window*>(event.target())->GetRootWindow();
-  if (root_window_) {
-    // It's already started. This can happen when the second finger touches
-    // the screen, or combination of the touch and mouse. We should grab the
-    // partial screenshot instead of restarting.
-    if (current_root == root_window_) {
-      Update(event);
-      Complete();
-    }
-  } else {
-    root_window_ = current_root;
-    start_position_ = event.root_location();
-  }
-}
-
-void PartialScreenshotController::Complete() {
-  if (!root_window_) {
-    // If we received a released event before we ever got a pressed event
-    // (resulting in setting |root_window_|), we just return without canceling
-    // to keep the screenshot session active waiting for the next press.
-    //
-    // This is to avoid a crash that used to happen when we start the screenshot
-    // session while the mouse is pressed and then release without moving the
-    // mouse. crbug.com/581432.
-    return;
-  }
-
-  DCHECK(layers_.count(root_window_));
-  const gfx::Rect& region = layers_.at(root_window_)->region();
-  if (!region.IsEmpty()) {
-    screenshot_delegate_->HandleTakePartialScreenshot(
-        root_window_, gfx::IntersectRects(root_window_->bounds(), region));
-  }
-  Cancel();
-}
-
-void PartialScreenshotController::Cancel() {
-  root_window_ = nullptr;
-  screenshot_delegate_ = nullptr;
-  display::Screen::GetScreen()->RemoveObserver(this);
-  STLDeleteValues(&layers_);
-  cursor_setter_.reset();
-  EnableMouseWarp(true);
-}
-
-void PartialScreenshotController::Update(const ui::LocatedEvent& event) {
-  // Update may happen without MaybeStart() if the partial screenshot session
-  // starts when dragging.
-  if (!root_window_)
-    MaybeStart(event);
-
-  DCHECK(layers_.find(root_window_) != layers_.end());
-  layers_.at(root_window_)
-      ->SetRegion(
-          gfx::Rect(std::min(start_position_.x(), event.root_location().x()),
-                    std::min(start_position_.y(), event.root_location().y()),
-                    ::abs(start_position_.x() - event.root_location().x()),
-                    ::abs(start_position_.y() - event.root_location().y())));
-}
-
-void PartialScreenshotController::OnKeyEvent(ui::KeyEvent* event) {
-  if (!screenshot_delegate_)
-    return;
-  if (event->type() == ui::ET_KEY_RELEASED &&
-      event->key_code() == ui::VKEY_ESCAPE) {
-    Cancel();
-  }
-
-  // Intercepts all key events.
-  event->StopPropagation();
-}
-
-void PartialScreenshotController::OnMouseEvent(ui::MouseEvent* event) {
-  if (!screenshot_delegate_)
-    return;
-  switch (event->type()) {
-    case ui::ET_MOUSE_PRESSED:
-      MaybeStart(*event);
-      break;
-    case ui::ET_MOUSE_DRAGGED:
-      Update(*event);
-      break;
-    case ui::ET_MOUSE_RELEASED:
-      Complete();
-      break;
-    default:
-      // Do nothing.
-      break;
-  }
-  event->StopPropagation();
-}
-
-void PartialScreenshotController::OnTouchEvent(ui::TouchEvent* event) {
-  if (!screenshot_delegate_)
-    return;
-  switch (event->type()) {
-    case ui::ET_TOUCH_PRESSED:
-      MaybeStart(*event);
-      break;
-    case ui::ET_TOUCH_MOVED:
-      Update(*event);
-      break;
-    case ui::ET_TOUCH_RELEASED:
-      Complete();
-      break;
-    default:
-      // Do nothing.
-      break;
-  }
-  event->StopPropagation();
-}
-
-void PartialScreenshotController::OnDisplayAdded(
-    const display::Display& new_display) {
-  if (!screenshot_delegate_)
-    return;
-  Cancel();
-}
-
-void PartialScreenshotController::OnDisplayRemoved(
-    const display::Display& old_display) {
-  if (!screenshot_delegate_)
-    return;
-  Cancel();
-}
-
-void PartialScreenshotController::OnDisplayMetricsChanged(
-    const display::Display& display,
-    uint32_t changed_metrics) {}
-
-}  // namespace ash
diff --git a/ash/utility/partial_screenshot_controller.h b/ash/utility/partial_screenshot_controller.h
deleted file mode 100644
index 6f2ca36..0000000
--- a/ash/utility/partial_screenshot_controller.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_UTILITY_PARTIAL_SCREENSHOT_CONTROLLER_H_
-#define ASH_UTILITY_PARTIAL_SCREENSHOT_CONTROLLER_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-
-#include "ash/ash_export.h"
-#include "ash/shell_observer.h"
-#include "base/macros.h"
-#include "ui/display/display_observer.h"
-#include "ui/events/event_handler.h"
-#include "ui/gfx/geometry/point.h"
-
-namespace aura {
-class Window;
-}
-
-namespace ui {
-class LocatedEvent;
-}
-
-namespace ash {
-class ScreenshotDelegate;
-
-// This class controls a session of taking partial screenshot, i.e.: drawing
-// region rectangles during drag, and changing the mouse cursor to indicate
-// the current mode.
-// This class does not use aura::Window / views::Widget intentionally to avoid
-// the conflicts of window manager features like mouse captures or window focus.
-class ASH_EXPORT PartialScreenshotController : public ui::EventHandler,
-                                               public display::DisplayObserver {
- public:
-  PartialScreenshotController();
-  ~PartialScreenshotController() override;
-
-  // Starts the UI for taking partial screenshot; dragging to select a region.
-  // PartialScreenshotController manage their own lifetime so caller must not
-  // delete the returned values.
-  void StartPartialScreenshotSession(ScreenshotDelegate* screenshot_delegate);
-
- private:
-  friend class PartialScreenshotControllerTest;
-
-  class ScopedCursorSetter;
-  class PartialScreenshotLayer;
-
-  // Starts, ends, cancels, or updates the region selection.
-  void MaybeStart(const ui::LocatedEvent& event);
-  void Complete();
-  void Cancel();
-  void Update(const ui::LocatedEvent& event);
-
-  // ui::EventHandler:
-  void OnKeyEvent(ui::KeyEvent* event) override;
-  void OnMouseEvent(ui::MouseEvent* event) override;
-  void OnTouchEvent(ui::TouchEvent* event) override;
-
-  // display::DisplayObserver:
-  void OnDisplayAdded(const display::Display& new_display) override;
-  void OnDisplayRemoved(const display::Display& old_display) override;
-  void OnDisplayMetricsChanged(const display::Display& display,
-                               uint32_t changed_metrics) override;
-
-  // The data to build the screenshot region.
-  gfx::Point start_position_;
-  aura::Window* root_window_;
-
-  // Layers to create the visual effect of region selection.
-  std::map<aura::Window*, PartialScreenshotLayer*> layers_;
-
-  // The object to specify the crosshair cursor.
-  std::unique_ptr<ScopedCursorSetter> cursor_setter_;
-
-  // ScreenshotDelegate to take the actual screenshot. No ownership.
-  ScreenshotDelegate* screenshot_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(PartialScreenshotController);
-};
-
-}  // namespace ash
-
-#endif  // #ifndef ASH_WM_PARTIAL_SCREENSHOT_VIEW_H_
diff --git a/ash/utility/partial_screenshot_controller_unittest.cc b/ash/utility/partial_screenshot_controller_unittest.cc
deleted file mode 100644
index d0ef2c3..0000000
--- a/ash/utility/partial_screenshot_controller_unittest.cc
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/utility/partial_screenshot_controller.h"
-
-#include "ash/display/cursor_window_controller.h"
-#include "ash/display/mouse_cursor_event_filter.h"
-#include "ash/display/window_tree_host_manager.h"
-#include "ash/screenshot_delegate.h"
-#include "ash/shell.h"
-#include "ash/test/ash_test_base.h"
-#include "ash/test/display_manager_test_api.h"
-#include "ash/test/mirror_window_test_api.h"
-#include "ash/test/test_screenshot_delegate.h"
-#include "ui/aura/env.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/base/cursor/cursor.h"
-#include "ui/events/test/event_generator.h"
-#include "ui/wm/core/cursor_manager.h"
-
-namespace ash {
-
-class PartialScreenshotControllerTest : public test::AshTestBase {
- public:
-  PartialScreenshotControllerTest() {}
-  ~PartialScreenshotControllerTest() override {}
-
- protected:
-  PartialScreenshotController* partial_screenshot_controller() {
-    return Shell::GetInstance()->partial_screenshot_controller();
-  }
-
-  bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
-    return test::DisplayManagerTestApi::TestIfMouseWarpsAt(GetEventGenerator(),
-                                                           point_in_screen);
-  }
-
-  void StartPartialScreenshotSession() {
-    partial_screenshot_controller()->StartPartialScreenshotSession(
-        GetScreenshotDelegate());
-  }
-
-  void Cancel() { partial_screenshot_controller()->Cancel(); }
-
-  bool IsActive() {
-    return partial_screenshot_controller()->screenshot_delegate_ != nullptr;
-  }
-
-  const gfx::Point& GetStartPosition() const {
-    return Shell::GetInstance()
-        ->partial_screenshot_controller()
-        ->start_position_;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PartialScreenshotControllerTest);
-};
-
-TEST_F(PartialScreenshotControllerTest, BasicMouse) {
-  StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
-  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-
-  generator.MoveMouseTo(100, 100);
-  generator.PressLeftButton();
-  EXPECT_EQ("100,100", GetStartPosition().ToString());
-  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
-
-  generator.MoveMouseTo(200, 200);
-  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
-
-  generator.ReleaseLeftButton();
-  EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
-  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
-
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(IsActive());
-}
-
-// Starting the screenshot session while mouse is pressed, releasing the mouse
-// without moving it used to cause a crash. Make sure this doesn't happen again.
-// crbug.com/581432.
-TEST_F(PartialScreenshotControllerTest, StartSessionWhileMousePressed) {
-  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
-
-  generator.MoveMouseTo(100, 100);
-  generator.PressLeftButton();
-
-  // The following used to cause a crash. Now it should remain in the
-  // screenshot session.
-  StartPartialScreenshotSession();
-  generator.ReleaseLeftButton();
-  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
-  EXPECT_TRUE(IsActive());
-
-  // Pressing again, moving, and releasing should take a screenshot.
-  generator.PressLeftButton();
-  generator.MoveMouseTo(200, 200);
-  generator.ReleaseLeftButton();
-  EXPECT_EQ(1, test_delegate->handle_take_partial_screenshot_count());
-  EXPECT_FALSE(IsActive());
-
-  // Starting the screenshot session while mouse is pressed, moving the mouse
-  // and releasing should take a screenshot normally.
-  generator.MoveMouseTo(100, 100);
-  generator.PressLeftButton();
-  StartPartialScreenshotSession();
-  generator.MoveMouseTo(150, 150);
-  generator.MoveMouseTo(200, 200);
-  EXPECT_TRUE(IsActive());
-  generator.ReleaseLeftButton();
-  EXPECT_EQ(2, test_delegate->handle_take_partial_screenshot_count());
-  EXPECT_FALSE(IsActive());
-}
-
-TEST_F(PartialScreenshotControllerTest, JustClick) {
-  StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
-  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-
-  generator.MoveMouseTo(100, 100);
-
-  // No moves, just clicking at the same position.
-  generator.ClickLeftButton();
-  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
-
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(IsActive());
-}
-
-TEST_F(PartialScreenshotControllerTest, BasicTouch) {
-  StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
-  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-
-  generator.set_current_location(gfx::Point(100, 100));
-  generator.PressTouch();
-  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
-  EXPECT_EQ("100,100", GetStartPosition().ToString());
-
-  generator.MoveTouch(gfx::Point(200, 200));
-  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
-
-  generator.ReleaseTouch();
-  EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
-  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
-
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(IsActive());
-}
-
-TEST_F(PartialScreenshotControllerTest, TwoFingerTouch) {
-  StartPartialScreenshotSession();
-  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
-  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
-
-  generator.set_current_location(gfx::Point(100, 100));
-  generator.PressTouch();
-  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
-  EXPECT_EQ("100,100", GetStartPosition().ToString());
-
-  generator.set_current_location(gfx::Point(200, 200));
-  generator.PressTouchId(1);
-  EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
-  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
-
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(IsActive());
-}
-
-TEST_F(PartialScreenshotControllerTest, MultipleDisplays) {
-  if (!SupportsMultipleDisplays())
-    return;
-
-  StartPartialScreenshotSession();
-  EXPECT_TRUE(IsActive());
-  UpdateDisplay("400x400,500x500");
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(IsActive());
-
-  StartPartialScreenshotSession();
-  EXPECT_TRUE(IsActive());
-  UpdateDisplay("400x400");
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(IsActive());
-}
-
-// Make sure PartialScreenshotController doesn't allow taking screenshot
-// across multiple monitors
-// cursor. See http://crbug.com/462229
-#if defined(OS_CHROMEOS)
-TEST_F(PartialScreenshotControllerTest, MouseWarpTest) {
-  if (!SupportsMultipleDisplays())
-    return;
-
-  // Create two displays.
-  Shell* shell = Shell::GetInstance();
-  UpdateDisplay("500x500,500x500");
-  EXPECT_EQ(2U, shell->display_manager()->GetNumDisplays());
-
-  StartPartialScreenshotSession();
-  EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
-  EXPECT_EQ("499,11",
-            aura::Env::GetInstance()->last_mouse_location().ToString());
-
-  Cancel();
-  EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
-  EXPECT_EQ("501,11",
-            aura::Env::GetInstance()->last_mouse_location().ToString());
-}
-
-TEST_F(PartialScreenshotControllerTest, VisibilityTest) {
-  aura::client::CursorClient* client = Shell::GetInstance()->cursor_manager();
-
-  GetEventGenerator().PressKey(ui::VKEY_A, 0);
-  GetEventGenerator().ReleaseKey(ui::VKEY_A, 0);
-
-  EXPECT_FALSE(client->IsCursorVisible());
-
-  StartPartialScreenshotSession();
-  EXPECT_TRUE(IsActive());
-  EXPECT_TRUE(client->IsCursorVisible());
-
-  Cancel();
-  EXPECT_TRUE(client->IsCursorVisible());
-}
-
-// Make sure PartialScreenshotController doesn't prevent handling of large
-// cursor. See http://crbug.com/459214
-TEST_F(PartialScreenshotControllerTest, LargeCursor) {
-  Shell::GetInstance()->cursor_manager()->SetCursorSet(ui::CURSOR_SET_LARGE);
-  Shell::GetInstance()
-      ->window_tree_host_manager()
-      ->cursor_window_controller()
-      ->SetCursorCompositingEnabled(true);
-
-  // Large cursor is represented as cursor window.
-  test::MirrorWindowTestApi test_api;
-  ASSERT_NE(nullptr, test_api.GetCursorWindow());
-
-  ui::test::EventGenerator event_generator(Shell::GetPrimaryRootWindow());
-  gfx::Point cursor_location;
-  event_generator.MoveMouseTo(cursor_location);
-  EXPECT_EQ(cursor_location.ToString(),
-            test_api.GetCursorLocation().ToString());
-
-  StartPartialScreenshotSession();
-  EXPECT_TRUE(IsActive());
-
-  cursor_location += gfx::Vector2d(1, 1);
-  event_generator.MoveMouseTo(cursor_location);
-  EXPECT_EQ(cursor_location.ToString(),
-            test_api.GetCursorLocation().ToString());
-
-  event_generator.PressLeftButton();
-  cursor_location += gfx::Vector2d(5, 5);
-  event_generator.MoveMouseTo(cursor_location);
-  EXPECT_EQ(cursor_location.ToString(),
-            test_api.GetCursorLocation().ToString());
-
-  event_generator.ReleaseLeftButton();
-
-  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
-  EXPECT_EQ("1,1 5x5", GetScreenshotDelegate()->last_rect().ToString());
-  RunAllPendingInMessageLoop();
-  EXPECT_FALSE(IsActive());
-}
-#endif
-
-}  // namespace ash
diff --git a/ash/utility/screenshot_controller.cc b/ash/utility/screenshot_controller.cc
new file mode 100644
index 0000000..cd1192f
--- /dev/null
+++ b/ash/utility/screenshot_controller.cc
@@ -0,0 +1,457 @@
+// Copyright 2014 The Chromium 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 "ash/utility/screenshot_controller.h"
+
+#include <cmath>
+
+#include "ash/display/mouse_cursor_event_filter.h"
+#include "ash/screenshot_delegate.h"
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "ash/wm/window_util.h"
+#include "base/stl_util.h"
+#include "ui/aura/client/capture_client.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/aura/window_targeter.h"
+#include "ui/compositor/paint_recorder.h"
+#include "ui/events/event.h"
+#include "ui/events/event_handler.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/screen.h"
+#include "ui/views/widget/widget.h"
+#include "ui/wm/core/cursor_manager.h"
+
+namespace ash {
+
+namespace {
+
+// The size to increase the invalidated area in the layer to repaint. The area
+// should be slightly bigger than the actual region because the region indicator
+// rectangles are drawn outside of the selected region.
+const int kInvalidateRegionAdditionalSize = 3;
+
+// This will prevent the user from taking a screenshot across multiple
+// monitors. it will stop the mouse at the any edge of the screen. must
+// swtich back on when the screenshot is complete.
+void EnableMouseWarp(bool enable) {
+  Shell::GetInstance()->mouse_cursor_filter()->set_mouse_warp_enabled(enable);
+}
+
+class ScreenshotWindowTargeter : public aura::WindowTargeter {
+ public:
+  ScreenshotWindowTargeter() = default;
+  ~ScreenshotWindowTargeter() override = default;
+
+  aura::Window* FindWindowForEvent(ui::LocatedEvent* event) {
+    aura::Window* target = static_cast<aura::Window*>(event->target());
+    aura::Window* target_root = target->GetRootWindow();
+
+    aura::client::ScreenPositionClient* position_client =
+        aura::client::GetScreenPositionClient(target_root);
+    gfx::Point location = event->location();
+    position_client->ConvertPointToScreen(target, &location);
+
+    gfx::Display display =
+        gfx::Screen::GetScreen()->GetDisplayNearestPoint(location);
+
+    aura::Window* root_window = Shell::GetInstance()
+                                    ->window_tree_host_manager()
+                                    ->GetRootWindowForDisplayId(display.id());
+
+    position_client->ConvertPointFromScreen(root_window, &location);
+
+    gfx::Point target_location = event->location();
+    event->set_location(location);
+
+    // Ignore capture window when finding the target for located event.
+    aura::client::CaptureClient* original_capture_client =
+        aura::client::GetCaptureClient(root_window);
+    aura::client::SetCaptureClient(root_window, nullptr);
+
+    aura::Window* selected =
+        static_cast<aura::Window*>(FindTargetForEvent(root_window, event));
+
+    // Restore State.
+    aura::client::SetCaptureClient(root_window, original_capture_client);
+    event->set_location(target_location);
+    return selected;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ScreenshotWindowTargeter);
+};
+
+}  // namespace
+
+class ScreenshotController::ScreenshotLayer : public ui::LayerOwner,
+                                              public ui::LayerDelegate {
+ public:
+  ScreenshotLayer(ui::Layer* parent) {
+    SetLayer(new ui::Layer(ui::LAYER_TEXTURED));
+    layer()->SetFillsBoundsOpaquely(false);
+    layer()->SetBounds(parent->bounds());
+    parent->Add(layer());
+    parent->StackAtTop(layer());
+    layer()->SetVisible(true);
+    layer()->set_delegate(this);
+  }
+  ~ScreenshotLayer() override {}
+
+  const gfx::Rect& region() const { return region_; }
+
+  void SetRegion(const gfx::Rect& region) {
+    // Invalidates the region which covers the current and new region.
+    gfx::Rect union_rect(region_);
+    union_rect.Union(region);
+    union_rect.Inset(-kInvalidateRegionAdditionalSize,
+                     -kInvalidateRegionAdditionalSize);
+    union_rect.Intersects(layer()->bounds());
+    region_ = region;
+    layer()->SchedulePaint(union_rect);
+  }
+
+ private:
+  // ui::LayerDelegate:
+  void OnPaintLayer(const ui::PaintContext& context) override {
+    const SkColor kSelectedAreaOverlayColor = 0x40000000;
+    if (region_.IsEmpty())
+      return;
+    // Screenshot area representation: black rectangle with white
+    // rectangle inside.  To avoid capturing these rectangles when mouse
+    // release, they should be outside of the actual capturing area.
+    gfx::Rect rect(region_);
+    ui::PaintRecorder recorder(context, layer()->size());
+
+    recorder.canvas()->FillRect(region_, kSelectedAreaOverlayColor);
+
+    rect.Inset(-1, -1);
+    recorder.canvas()->DrawRect(rect, SK_ColorWHITE);
+    rect.Inset(-1, -1);
+    recorder.canvas()->DrawRect(rect, SK_ColorBLACK);
+  }
+
+  void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
+
+  void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
+
+  base::Closure PrepareForLayerBoundsChange() override {
+    return base::Closure();
+  }
+
+  gfx::Rect region_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScreenshotLayer);
+};
+
+class ScreenshotController::ScopedCursorSetter {
+ public:
+  ScopedCursorSetter(::wm::CursorManager* cursor_manager,
+                     gfx::NativeCursor cursor)
+      : cursor_manager_(nullptr) {
+    if (cursor_manager->IsCursorLocked())
+      return;
+    gfx::NativeCursor original_cursor = cursor_manager->GetCursor();
+    cursor_manager_ = cursor_manager;
+    cursor_manager_->SetCursor(cursor);
+    if (!cursor_manager_->IsCursorVisible())
+      cursor_manager_->ShowCursor();
+    cursor_manager_->LockCursor();
+    // SetCursor does not make any effects at this point but it sets back to
+    // the original cursor when unlocked.
+    cursor_manager_->SetCursor(original_cursor);
+  }
+
+  ~ScopedCursorSetter() {
+    if (cursor_manager_)
+      cursor_manager_->UnlockCursor();
+  }
+
+ private:
+  ::wm::CursorManager* cursor_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedCursorSetter);
+};
+
+ScreenshotController::ScreenshotController()
+    : mode_(NONE),
+      root_window_(nullptr),
+      selected_(nullptr),
+      screenshot_delegate_(nullptr) {
+  // Keep this here and don't move it to StartPartialScreenshotSession(), as it
+  // needs to be pre-pended by MouseCursorEventFilter in Shell::Init().
+  Shell::GetInstance()->PrependPreTargetHandler(this);
+}
+
+ScreenshotController::~ScreenshotController() {
+  if (screenshot_delegate_)
+    Cancel();
+  Shell::GetInstance()->RemovePreTargetHandler(this);
+}
+
+void ScreenshotController::StartWindowScreenshotSession(
+    ScreenshotDelegate* screenshot_delegate) {
+  if (screenshot_delegate_) {
+    DCHECK_EQ(screenshot_delegate_, screenshot_delegate);
+    return;
+  }
+  screenshot_delegate_ = screenshot_delegate;
+  mode_ = WINDOW;
+
+  gfx::Screen::GetScreen()->AddObserver(this);
+  for (aura::Window* root : Shell::GetAllRootWindows()) {
+    layers_[root] = new ScreenshotLayer(
+        Shell::GetContainer(root, kShellWindowId_OverlayContainer)->layer());
+  }
+  SetSelectedWindow(wm::GetActiveWindow());
+
+  cursor_setter_.reset(new ScopedCursorSetter(
+      Shell::GetInstance()->cursor_manager(), ui::kCursorCross));
+
+  EnableMouseWarp(true);
+}
+
+void ScreenshotController::StartPartialScreenshotSession(
+    ScreenshotDelegate* screenshot_delegate) {
+  // Already in a screenshot session.
+  if (screenshot_delegate_) {
+    DCHECK_EQ(screenshot_delegate_, screenshot_delegate);
+    return;
+  }
+
+  screenshot_delegate_ = screenshot_delegate;
+  mode_ = PARTIAL;
+  gfx::Screen::GetScreen()->AddObserver(this);
+  for (aura::Window* root : Shell::GetAllRootWindows()) {
+    layers_[root] = new ScreenshotLayer(
+        Shell::GetContainer(root, kShellWindowId_OverlayContainer)->layer());
+  }
+
+  cursor_setter_.reset(new ScopedCursorSetter(
+      Shell::GetInstance()->cursor_manager(), ui::kCursorCross));
+
+  EnableMouseWarp(false);
+}
+
+void ScreenshotController::MaybeStart(const ui::LocatedEvent& event) {
+  aura::Window* current_root =
+      static_cast<aura::Window*>(event.target())->GetRootWindow();
+  if (root_window_) {
+    // It's already started. This can happen when the second finger touches
+    // the screen, or combination of the touch and mouse. We should grab the
+    // partial screenshot instead of restarting.
+    if (current_root == root_window_) {
+      Update(event);
+      CompletePartialScreenshot();
+    }
+  } else {
+    root_window_ = current_root;
+    start_position_ = event.root_location();
+  }
+}
+
+void ScreenshotController::CompleteWindowScreenshot() {
+  if (selected_)
+    screenshot_delegate_->HandleTakeWindowScreenshot(selected_);
+  Cancel();
+}
+
+void ScreenshotController::CompletePartialScreenshot() {
+  if (!root_window_) {
+    // If we received a released event before we ever got a pressed event
+    // (resulting in setting |root_window_|), we just return without canceling
+    // to keep the screenshot session active waiting for the next press.
+    //
+    // This is to avoid a crash that used to happen when we start the screenshot
+    // session while the mouse is pressed and then release without moving the
+    // mouse. crbug.com/581432.
+    return;
+  }
+
+  DCHECK(layers_.count(root_window_));
+  const gfx::Rect& region = layers_.at(root_window_)->region();
+  if (!region.IsEmpty()) {
+    screenshot_delegate_->HandleTakePartialScreenshot(
+        root_window_, gfx::IntersectRects(root_window_->bounds(), region));
+  }
+  Cancel();
+}
+
+void ScreenshotController::Cancel() {
+  mode_ = NONE;
+  root_window_ = nullptr;
+  SetSelectedWindow(nullptr);
+  screenshot_delegate_ = nullptr;
+  gfx::Screen::GetScreen()->RemoveObserver(this);
+  STLDeleteValues(&layers_);
+  cursor_setter_.reset();
+  EnableMouseWarp(true);
+}
+
+void ScreenshotController::Update(const ui::LocatedEvent& event) {
+  // Update may happen without MaybeStart() if the partial screenshot session
+  // starts when dragging.
+  if (!root_window_)
+    MaybeStart(event);
+
+  DCHECK(layers_.find(root_window_) != layers_.end());
+  layers_.at(root_window_)
+      ->SetRegion(
+          gfx::Rect(std::min(start_position_.x(), event.root_location().x()),
+                    std::min(start_position_.y(), event.root_location().y()),
+                    ::abs(start_position_.x() - event.root_location().x()),
+                    ::abs(start_position_.y() - event.root_location().y())));
+}
+
+void ScreenshotController::UpdateSelectedWindow(ui::LocatedEvent* event) {
+  aura::Window* selected = ScreenshotWindowTargeter().FindWindowForEvent(event);
+
+  // Find a window that is backed with a widget.
+  while (selected && (selected->type() == ui::wm::WINDOW_TYPE_CONTROL ||
+                      !selected->delegate())) {
+    selected = selected->parent();
+  }
+
+  if (selected->parent()->id() == kShellWindowId_DesktopBackgroundContainer ||
+      selected->parent()->id() == kShellWindowId_LockScreenBackgroundContainer)
+    selected = nullptr;
+
+  SetSelectedWindow(selected);
+}
+
+void ScreenshotController::SetSelectedWindow(aura::Window* selected) {
+  if (selected_ == selected)
+    return;
+
+  if (selected_) {
+    selected_->RemoveObserver(this);
+    layers_.at(selected_->GetRootWindow())->SetRegion(gfx::Rect());
+  }
+
+  selected_ = selected;
+
+  if (selected_) {
+    selected_->AddObserver(this);
+    layers_.at(selected_->GetRootWindow())->SetRegion(selected_->bounds());
+  }
+}
+
+void ScreenshotController::OnKeyEvent(ui::KeyEvent* event) {
+  if (!screenshot_delegate_)
+    return;
+
+  if (event->type() == ui::ET_KEY_RELEASED) {
+    if (event->key_code() == ui::VKEY_ESCAPE) {
+      Cancel();
+    } else if (event->key_code() == ui::VKEY_RETURN && mode_ == WINDOW) {
+      CompleteWindowScreenshot();
+    }
+  }
+
+  // Intercepts all key events.
+  event->StopPropagation();
+}
+
+void ScreenshotController::OnMouseEvent(ui::MouseEvent* event) {
+  if (!screenshot_delegate_)
+    return;
+  switch (mode_) {
+    case NONE:
+      NOTREACHED();
+      break;
+    case WINDOW:
+      switch (event->type()) {
+        case ui::ET_MOUSE_MOVED:
+        case ui::ET_MOUSE_DRAGGED:
+          UpdateSelectedWindow(event);
+          break;
+        case ui::ET_MOUSE_RELEASED:
+          CompleteWindowScreenshot();
+          break;
+        default:
+          // Do nothing.
+          break;
+      }
+      break;
+    case PARTIAL:
+      switch (event->type()) {
+        case ui::ET_MOUSE_PRESSED:
+          MaybeStart(*event);
+          break;
+        case ui::ET_MOUSE_DRAGGED:
+          Update(*event);
+          break;
+        case ui::ET_MOUSE_RELEASED:
+          CompletePartialScreenshot();
+          break;
+        default:
+          // Do nothing.
+          break;
+      }
+      break;
+  }
+  event->StopPropagation();
+}
+
+void ScreenshotController::OnTouchEvent(ui::TouchEvent* event) {
+  if (!screenshot_delegate_)
+    return;
+  switch (mode_) {
+    case NONE:
+      NOTREACHED();
+      break;
+    case WINDOW:
+      switch (event->type()) {
+        case ui::ET_TOUCH_PRESSED:
+        case ui::ET_TOUCH_MOVED:
+          UpdateSelectedWindow(event);
+          break;
+        case ui::ET_TOUCH_RELEASED:
+          CompleteWindowScreenshot();
+          break;
+        default:
+          // Do nothing.
+          break;
+      }
+      break;
+    case PARTIAL:
+      switch (event->type()) {
+        case ui::ET_TOUCH_PRESSED:
+          MaybeStart(*event);
+          break;
+        case ui::ET_TOUCH_MOVED:
+          Update(*event);
+          break;
+        case ui::ET_TOUCH_RELEASED:
+          CompletePartialScreenshot();
+          break;
+        default:
+          // Do nothing.
+          break;
+      }
+      break;
+  }
+  event->StopPropagation();
+}
+
+void ScreenshotController::OnDisplayAdded(const gfx::Display& new_display) {
+  if (!screenshot_delegate_)
+    return;
+  Cancel();
+}
+
+void ScreenshotController::OnDisplayRemoved(const gfx::Display& old_display) {
+  if (!screenshot_delegate_)
+    return;
+  Cancel();
+}
+
+void ScreenshotController::OnDisplayMetricsChanged(const gfx::Display& display,
+                                                   uint32_t changed_metrics) {}
+
+void ScreenshotController::OnWindowDestroying(aura::Window* window) {
+  SetSelectedWindow(nullptr);
+}
+
+}  // namespace ash
diff --git a/ash/utility/screenshot_controller.h b/ash/utility/screenshot_controller.h
new file mode 100644
index 0000000..3f13f76
--- /dev/null
+++ b/ash/utility/screenshot_controller.h
@@ -0,0 +1,110 @@
+// Copyright 2014 The Chromium 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 ASH_UTILITY_SCREENSHOT_CONTROLLER_H_
+#define ASH_UTILITY_SCREENSHOT_CONTROLLER_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+
+#include "ash/ash_export.h"
+#include "ash/shell_observer.h"
+#include "base/macros.h"
+#include "ui/aura/window_observer.h"
+#include "ui/display/display_observer.h"
+#include "ui/events/event_handler.h"
+#include "ui/gfx/geometry/point.h"
+
+namespace aura {
+class Window;
+}
+
+namespace ui {
+class LocatedEvent;
+}
+
+namespace ash {
+class ScreenshotDelegate;
+
+// This class controls a session of taking partial/window screenshot, i.e.:
+// drawing
+// region rectangles during selection, and changing the mouse cursor to indicate
+// the current mode.
+// This class does not use aura::Window / views::Widget intentionally to avoid
+class ASH_EXPORT ScreenshotController : public ui::EventHandler,
+                                        public display::DisplayObserver,
+                                        public aura::WindowObserver {
+ public:
+  ScreenshotController();
+  ~ScreenshotController() override;
+
+  // Starts the UI for taking partial screenshot; dragging to select a region.
+  // ScreenshotController manage their own lifetime so caller must not
+  // delete the returned values.
+  void StartPartialScreenshotSession(ScreenshotDelegate* screenshot_delegate);
+
+  // Starts the UI for taking a window screenshot;
+  void StartWindowScreenshotSession(ScreenshotDelegate* screenshot_delegate);
+
+ private:
+  enum Mode {
+    NONE,
+    PARTIAL,
+    WINDOW,
+  };
+
+  friend class ScreenshotControllerTest;
+
+  class ScopedCursorSetter;
+  class ScreenshotLayer;
+
+  // Starts, ends, cancels, or updates the region selection.
+  void MaybeStart(const ui::LocatedEvent& event);
+  void CompleteWindowScreenshot();
+  void CompletePartialScreenshot();
+  void Cancel();
+  void Update(const ui::LocatedEvent& event);
+  void UpdateSelectedWindow(ui::LocatedEvent* event);
+  void SetSelectedWindow(aura::Window* window);
+
+  // ui::EventHandler:
+  void OnKeyEvent(ui::KeyEvent* event) override;
+  void OnMouseEvent(ui::MouseEvent* event) override;
+  void OnTouchEvent(ui::TouchEvent* event) override;
+
+  // display::DisplayObserver:
+  void OnDisplayAdded(const display::Display& new_display) override;
+  void OnDisplayRemoved(const display::Display& old_display) override;
+  void OnDisplayMetricsChanged(const display::Display& display,
+                               uint32_t changed_metrics) override;
+
+  // aura::WindowObserver:
+  void OnWindowDestroying(aura::Window* window) override;
+
+  Mode mode_;
+
+  // The data to build the screenshot region.
+  gfx::Point start_position_;
+  aura::Window* root_window_;
+
+  // Currently selected window in WINDOW mode.
+  aura::Window* selected_;
+
+  // Layers to create the visual effect of region selection or selected window.
+  std::map<aura::Window*, ScreenshotLayer*> layers_;
+
+  // The object to specify the crosshair cursor.
+  std::unique_ptr<ScopedCursorSetter> cursor_setter_;
+
+  // ScreenshotDelegate to take the actual screenshot. No ownership.
+  ScreenshotDelegate* screenshot_delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScreenshotController);
+};
+
+}  // namespace ash
+
+#endif  // ASH_UTILITY_SCREENSHOT_CONTROLLER_H_
diff --git a/ash/utility/screenshot_controller_unittest.cc b/ash/utility/screenshot_controller_unittest.cc
new file mode 100644
index 0000000..153cf1e
--- /dev/null
+++ b/ash/utility/screenshot_controller_unittest.cc
@@ -0,0 +1,414 @@
+// Copyright 2014 The Chromium 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 "ash/utility/screenshot_controller.h"
+
+#include "ash/display/cursor_window_controller.h"
+#include "ash/display/mouse_cursor_event_filter.h"
+#include "ash/display/window_tree_host_manager.h"
+#include "ash/screenshot_delegate.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/display_manager_test_api.h"
+#include "ash/test/mirror_window_test_api.h"
+#include "ash/test/test_screenshot_delegate.h"
+#include "ash/wm/window_util.h"
+#include "ui/aura/env.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/events/test/event_generator.h"
+#include "ui/wm/core/cursor_manager.h"
+
+namespace ash {
+
+class ScreenshotControllerTest : public test::AshTestBase {
+ public:
+  ScreenshotControllerTest() {}
+  ~ScreenshotControllerTest() override {}
+
+ protected:
+  ScreenshotController* screenshot_controller() {
+    return Shell::GetInstance()->screenshot_controller();
+  }
+
+  bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
+    return test::DisplayManagerTestApi::TestIfMouseWarpsAt(GetEventGenerator(),
+                                                           point_in_screen);
+  }
+
+  void StartPartialScreenshotSession() {
+    screenshot_controller()->StartPartialScreenshotSession(
+        GetScreenshotDelegate());
+  }
+
+  void StartWindowScreenshotSession() {
+    screenshot_controller()->StartWindowScreenshotSession(
+        GetScreenshotDelegate());
+  }
+
+  void Cancel() { screenshot_controller()->Cancel(); }
+
+  bool IsActive() {
+    return screenshot_controller()->screenshot_delegate_ != nullptr;
+  }
+
+  const gfx::Point& GetStartPosition() const {
+    return Shell::GetInstance()->screenshot_controller()->start_position_;
+  }
+
+  const aura::Window* GetCurrentSelectedWindow() const {
+    return Shell::GetInstance()->screenshot_controller()->selected_;
+  }
+
+  aura::Window* CreateSelectableWindow(const gfx::Rect& rect) {
+    return CreateTestWindowInShell(SK_ColorGRAY, 0, rect);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ScreenshotControllerTest);
+};
+
+using WindowScreenshotControllerTest = ScreenshotControllerTest;
+using PartialScreenshotControllerTest = ScreenshotControllerTest;
+
+TEST_F(PartialScreenshotControllerTest, BasicMouse) {
+  StartPartialScreenshotSession();
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+  generator.MoveMouseTo(100, 100);
+  generator.PressLeftButton();
+  EXPECT_EQ("100,100", GetStartPosition().ToString());
+  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+  generator.MoveMouseTo(200, 200);
+  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+  generator.ReleaseLeftButton();
+  EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
+  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
+
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+}
+
+// Starting the screenshot session while mouse is pressed, releasing the mouse
+// without moving it used to cause a crash. Make sure this doesn't happen again.
+// crbug.com/581432.
+TEST_F(PartialScreenshotControllerTest, StartSessionWhileMousePressed) {
+  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+
+  generator.MoveMouseTo(100, 100);
+  generator.PressLeftButton();
+
+  // The following used to cause a crash. Now it should remain in the
+  // screenshot session.
+  StartPartialScreenshotSession();
+  generator.ReleaseLeftButton();
+  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+  EXPECT_TRUE(IsActive());
+
+  // Pressing again, moving, and releasing should take a screenshot.
+  generator.PressLeftButton();
+  generator.MoveMouseTo(200, 200);
+  generator.ReleaseLeftButton();
+  EXPECT_EQ(1, test_delegate->handle_take_partial_screenshot_count());
+  EXPECT_FALSE(IsActive());
+
+  // Starting the screenshot session while mouse is pressed, moving the mouse
+  // and releasing should take a screenshot normally.
+  generator.MoveMouseTo(100, 100);
+  generator.PressLeftButton();
+  StartPartialScreenshotSession();
+  generator.MoveMouseTo(150, 150);
+  generator.MoveMouseTo(200, 200);
+  EXPECT_TRUE(IsActive());
+  generator.ReleaseLeftButton();
+  EXPECT_EQ(2, test_delegate->handle_take_partial_screenshot_count());
+  EXPECT_FALSE(IsActive());
+}
+
+TEST_F(PartialScreenshotControllerTest, JustClick) {
+  StartPartialScreenshotSession();
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+  generator.MoveMouseTo(100, 100);
+
+  // No moves, just clicking at the same position.
+  generator.ClickLeftButton();
+  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+}
+
+TEST_F(PartialScreenshotControllerTest, BasicTouch) {
+  StartPartialScreenshotSession();
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+  generator.set_current_location(gfx::Point(100, 100));
+  generator.PressTouch();
+  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+  EXPECT_EQ("100,100", GetStartPosition().ToString());
+
+  generator.MoveTouch(gfx::Point(200, 200));
+  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+
+  generator.ReleaseTouch();
+  EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
+  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
+
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+}
+
+TEST_F(PartialScreenshotControllerTest, TwoFingerTouch) {
+  StartPartialScreenshotSession();
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
+
+  generator.set_current_location(gfx::Point(100, 100));
+  generator.PressTouch();
+  EXPECT_EQ(0, test_delegate->handle_take_partial_screenshot_count());
+  EXPECT_EQ("100,100", GetStartPosition().ToString());
+
+  generator.set_current_location(gfx::Point(200, 200));
+  generator.PressTouchId(1);
+  EXPECT_EQ("100,100 100x100", GetScreenshotDelegate()->last_rect().ToString());
+  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
+
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+}
+
+// Make sure ScreenshotController doesn't allow taking screenshot
+// across multiple monitors
+// cursor. See http://crbug.com/462229
+TEST_F(PartialScreenshotControllerTest, MouseWarpTest) {
+  if (!SupportsMultipleDisplays())
+    return;
+
+  // Create two displays.
+  Shell* shell = Shell::GetInstance();
+  UpdateDisplay("500x500,500x500");
+  EXPECT_EQ(2U, shell->display_manager()->GetNumDisplays());
+
+  StartPartialScreenshotSession();
+  EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
+  EXPECT_EQ("499,11",
+            aura::Env::GetInstance()->last_mouse_location().ToString());
+
+  Cancel();
+  EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(499, 11)));
+  EXPECT_EQ("501,11",
+            aura::Env::GetInstance()->last_mouse_location().ToString());
+}
+
+#if defined(OS_CHROMEOS)
+TEST_F(PartialScreenshotControllerTest, VisibilityTest) {
+  aura::client::CursorClient* client = Shell::GetInstance()->cursor_manager();
+
+  GetEventGenerator().PressKey(ui::VKEY_A, 0);
+  GetEventGenerator().ReleaseKey(ui::VKEY_A, 0);
+
+  EXPECT_FALSE(client->IsCursorVisible());
+
+  StartPartialScreenshotSession();
+  EXPECT_TRUE(IsActive());
+  EXPECT_TRUE(client->IsCursorVisible());
+
+  Cancel();
+  EXPECT_TRUE(client->IsCursorVisible());
+}
+
+// Make sure ScreenshotController doesn't prevent handling of large
+// cursor. See http://crbug.com/459214
+TEST_F(PartialScreenshotControllerTest, LargeCursor) {
+  Shell::GetInstance()->cursor_manager()->SetCursorSet(ui::CURSOR_SET_LARGE);
+  Shell::GetInstance()
+      ->window_tree_host_manager()
+      ->cursor_window_controller()
+      ->SetCursorCompositingEnabled(true);
+
+  // Large cursor is represented as cursor window.
+  test::MirrorWindowTestApi test_api;
+  ASSERT_NE(nullptr, test_api.GetCursorWindow());
+
+  ui::test::EventGenerator event_generator(Shell::GetPrimaryRootWindow());
+  gfx::Point cursor_location;
+  event_generator.MoveMouseTo(cursor_location);
+  EXPECT_EQ(cursor_location.ToString(),
+            test_api.GetCursorLocation().ToString());
+
+  StartPartialScreenshotSession();
+  EXPECT_TRUE(IsActive());
+
+  cursor_location += gfx::Vector2d(1, 1);
+  event_generator.MoveMouseTo(cursor_location);
+  EXPECT_EQ(cursor_location.ToString(),
+            test_api.GetCursorLocation().ToString());
+
+  event_generator.PressLeftButton();
+  cursor_location += gfx::Vector2d(5, 5);
+  event_generator.MoveMouseTo(cursor_location);
+  EXPECT_EQ(cursor_location.ToString(),
+            test_api.GetCursorLocation().ToString());
+
+  event_generator.ReleaseLeftButton();
+
+  EXPECT_EQ(1, GetScreenshotDelegate()->handle_take_partial_screenshot_count());
+  EXPECT_EQ("1,1 5x5", GetScreenshotDelegate()->last_rect().ToString());
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+}
+#endif
+
+TEST_F(WindowScreenshotControllerTest, KeyboardOperation) {
+  ui::test::EventGenerator& generator(GetEventGenerator());
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+
+  StartWindowScreenshotSession();
+  generator.PressKey(ui::VKEY_ESCAPE, 0);
+  generator.ReleaseKey(ui::VKEY_ESCAPE, 0);
+  EXPECT_FALSE(IsActive());
+  EXPECT_FALSE(test_delegate->GetSelectedWindowAndReset());
+
+  StartWindowScreenshotSession();
+  generator.PressKey(ui::VKEY_RETURN, 0);
+  generator.ReleaseKey(ui::VKEY_RETURN, 0);
+  EXPECT_FALSE(IsActive());
+  EXPECT_FALSE(test_delegate->GetSelectedWindowAndReset());
+
+  std::unique_ptr<aura::Window> window1(
+      CreateSelectableWindow(gfx::Rect(5, 5, 20, 20)));
+  wm::ActivateWindow(window1.get());
+  StartWindowScreenshotSession();
+  generator.PressKey(ui::VKEY_ESCAPE, 0);
+  generator.ReleaseKey(ui::VKEY_ESCAPE, 0);
+  EXPECT_FALSE(IsActive());
+  EXPECT_FALSE(test_delegate->GetSelectedWindowAndReset());
+
+  StartWindowScreenshotSession();
+  generator.PressKey(ui::VKEY_RETURN, 0);
+  generator.ReleaseKey(ui::VKEY_RETURN, 0);
+  EXPECT_FALSE(IsActive());
+  EXPECT_EQ(window1.get(), test_delegate->GetSelectedWindowAndReset());
+  // Make sure it's properly reset.
+  EXPECT_FALSE(test_delegate->GetSelectedWindowAndReset());
+}
+
+TEST_F(WindowScreenshotControllerTest, MouseOperation) {
+  ui::test::EventGenerator& generator(GetEventGenerator());
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+  StartWindowScreenshotSession();
+  EXPECT_TRUE(IsActive());
+  generator.ClickLeftButton();
+  EXPECT_FALSE(IsActive());
+  EXPECT_FALSE(test_delegate->GetSelectedWindowAndReset());
+
+  std::unique_ptr<aura::Window> window1(
+      CreateSelectableWindow(gfx::Rect(5, 5, 20, 20)));
+  std::unique_ptr<aura::Window> window2(
+      CreateSelectableWindow(gfx::Rect(100, 100, 100, 100)));
+  wm::ActivateWindow(window1.get());
+  StartWindowScreenshotSession();
+  EXPECT_EQ(window1.get(), GetCurrentSelectedWindow());
+  generator.MoveMouseTo(150, 150);
+  EXPECT_EQ(window2.get(), GetCurrentSelectedWindow());
+  generator.MoveMouseTo(400, 0);
+  EXPECT_FALSE(GetCurrentSelectedWindow());
+  generator.MoveMouseTo(10, 10);
+  EXPECT_EQ(window1.get(), GetCurrentSelectedWindow());
+  generator.ClickLeftButton();
+  EXPECT_EQ(window1.get(), test_delegate->GetSelectedWindowAndReset());
+
+  // Window selection should work even with Capture.
+  window2->SetCapture();
+  wm::ActivateWindow(window2.get());
+  StartWindowScreenshotSession();
+  EXPECT_EQ(window2.get(), GetCurrentSelectedWindow());
+  generator.MoveMouseTo(10, 10);
+  EXPECT_EQ(window1.get(), GetCurrentSelectedWindow());
+  generator.MoveMouseTo(400, 0);
+  EXPECT_FALSE(GetCurrentSelectedWindow());
+  generator.MoveMouseTo(10, 10);
+  EXPECT_EQ(window1.get(), GetCurrentSelectedWindow());
+  generator.ClickLeftButton();
+  EXPECT_EQ(window1.get(), test_delegate->GetSelectedWindowAndReset());
+
+  // Remove window.
+  StartWindowScreenshotSession();
+  generator.MoveMouseTo(10, 10);
+  EXPECT_EQ(window1.get(), GetCurrentSelectedWindow());
+  window1.reset();
+  EXPECT_FALSE(GetCurrentSelectedWindow());
+  generator.ClickLeftButton();
+  EXPECT_FALSE(test_delegate->GetSelectedWindowAndReset());
+}
+
+TEST_F(WindowScreenshotControllerTest, MultiDisplays) {
+  if (!SupportsMultipleDisplays())
+    return;
+
+  UpdateDisplay("400x400,500x500");
+
+  ui::test::EventGenerator& generator(GetEventGenerator());
+  test::TestScreenshotDelegate* test_delegate = GetScreenshotDelegate();
+
+  std::unique_ptr<aura::Window> window1(
+      CreateSelectableWindow(gfx::Rect(100, 100, 100, 100)));
+  std::unique_ptr<aura::Window> window2(
+      CreateSelectableWindow(gfx::Rect(600, 200, 100, 100)));
+  EXPECT_NE(window1.get()->GetRootWindow(), window2.get()->GetRootWindow());
+
+  StartWindowScreenshotSession();
+  generator.MoveMouseTo(150, 150);
+  EXPECT_EQ(window1.get(), GetCurrentSelectedWindow());
+  generator.MoveMouseTo(650, 250);
+  EXPECT_EQ(window2.get(), GetCurrentSelectedWindow());
+  generator.ClickLeftButton();
+  EXPECT_EQ(window2.get(), test_delegate->GetSelectedWindowAndReset());
+
+  window2->SetCapture();
+  wm::ActivateWindow(window2.get());
+  StartWindowScreenshotSession();
+  generator.MoveMouseTo(150, 150);
+  EXPECT_EQ(window1.get(), GetCurrentSelectedWindow());
+  generator.ClickLeftButton();
+  EXPECT_EQ(window1.get(), test_delegate->GetSelectedWindowAndReset());
+}
+
+TEST_F(ScreenshotControllerTest, MultipleDisplays) {
+  if (!SupportsMultipleDisplays())
+    return;
+
+  StartPartialScreenshotSession();
+  EXPECT_TRUE(IsActive());
+  UpdateDisplay("400x400,500x500");
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+
+  StartPartialScreenshotSession();
+  EXPECT_TRUE(IsActive());
+  UpdateDisplay("400x400");
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+
+  StartWindowScreenshotSession();
+  EXPECT_TRUE(IsActive());
+  UpdateDisplay("400x400,500x500");
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+
+  StartWindowScreenshotSession();
+  EXPECT_TRUE(IsActive());
+  UpdateDisplay("400x400");
+  RunAllPendingInMessageLoop();
+  EXPECT_FALSE(IsActive());
+}
+
+}  // namespace ash
diff --git a/ash/wm/aura/wm_globals_aura.cc b/ash/wm/aura/wm_globals_aura.cc
index 7de57d99f..fe216134 100644
--- a/ash/wm/aura/wm_globals_aura.cc
+++ b/ash/wm/aura/wm_globals_aura.cc
@@ -12,8 +12,11 @@
 #include "ash/wm/common/wm_activation_observer.h"
 #include "ash/wm/common/wm_display_observer.h"
 #include "ash/wm/common/wm_overview_mode_observer.h"
+#include "ash/wm/drag_window_resizer.h"
 #include "ash/wm/mru_window_tracker.h"
+#include "ash/wm/overview/window_selector_controller.h"
 #include "ash/wm/window_util.h"
+#include "base/memory/ptr_util.h"
 #include "ui/aura/client/focus_client.h"
 #include "ui/wm/public/activation_client.h"
 
@@ -109,8 +112,29 @@
   return wm_windows;
 }
 
-UserMetricsRecorder* WmGlobalsAura::GetUserMetricsRecorder() {
-  return Shell::GetInstance()->metrics();
+void WmGlobalsAura::RecordUserMetricsAction(WmUserMetricsAction action) {
+  return Shell::GetInstance()->metrics()->RecordUserMetricsAction(action);
+}
+
+std::unique_ptr<WindowResizer> WmGlobalsAura::CreateDragWindowResizer(
+    std::unique_ptr<WindowResizer> next_window_resizer,
+    wm::WindowState* window_state) {
+  return base::WrapUnique(
+      DragWindowResizer::Create(next_window_resizer.release(), window_state));
+}
+
+bool WmGlobalsAura::IsOverviewModeSelecting() {
+  WindowSelectorController* window_selector_controller =
+      Shell::GetInstance()->window_selector_controller();
+  return window_selector_controller &&
+         window_selector_controller->IsSelecting();
+}
+
+bool WmGlobalsAura::IsOverviewModeRestoringMinimizedWindows() {
+  WindowSelectorController* window_selector_controller =
+      Shell::GetInstance()->window_selector_controller();
+  return window_selector_controller &&
+         window_selector_controller->IsRestoringMinimizedWindows();
 }
 
 void WmGlobalsAura::AddActivationObserver(WmActivationObserver* observer) {
diff --git a/ash/wm/aura/wm_globals_aura.h b/ash/wm/aura/wm_globals_aura.h
index 866bbf0..9835b8d 100644
--- a/ash/wm/aura/wm_globals_aura.h
+++ b/ash/wm/aura/wm_globals_aura.h
@@ -39,7 +39,12 @@
   void LockCursor() override;
   void UnlockCursor() override;
   std::vector<WmWindow*> GetAllRootWindows() override;
-  UserMetricsRecorder* GetUserMetricsRecorder() override;
+  void RecordUserMetricsAction(WmUserMetricsAction action) override;
+  std::unique_ptr<WindowResizer> CreateDragWindowResizer(
+      std::unique_ptr<WindowResizer> next_window_resizer,
+      wm::WindowState* window_state) override;
+  bool IsOverviewModeSelecting() override;
+  bool IsOverviewModeRestoringMinimizedWindows() override;
   void AddActivationObserver(WmActivationObserver* observer) override;
   void RemoveActivationObserver(WmActivationObserver* observer) override;
   void AddDisplayObserver(WmDisplayObserver* observer) override;
diff --git a/ash/wm/aura/wm_shelf_aura.cc b/ash/wm/aura/wm_shelf_aura.cc
index f4145861..a9048a1 100644
--- a/ash/wm/aura/wm_shelf_aura.cc
+++ b/ash/wm/aura/wm_shelf_aura.cc
@@ -6,6 +6,7 @@
 
 #include "ash/shelf/shelf.h"
 #include "ash/shelf/shelf_layout_manager.h"
+#include "ash/wm/aura/wm_window_aura.h"
 #include "ash/wm/common/shelf/wm_shelf_observer.h"
 #include "ash/wm/common/wm_window.h"
 #include "ui/views/widget/widget.h"
@@ -16,22 +17,29 @@
 WmShelfAura::WmShelfAura(Shelf* shelf)
     : shelf_(shelf), shelf_layout_manager_(shelf->shelf_layout_manager()) {
   shelf_layout_manager_->AddObserver(this);
+  shelf_->AddIconObserver(this);
 }
 
 WmShelfAura::~WmShelfAura() {
+  shelf_->RemoveIconObserver(this);
   if (shelf_layout_manager_)
     shelf_layout_manager_->RemoveObserver(this);
 }
 
+// static
+Shelf* WmShelfAura::GetShelf(WmShelf* shelf) {
+  return static_cast<WmShelfAura*>(shelf)->shelf_;
+}
+
 WmWindow* WmShelfAura::GetWindow() {
   return WmWindow::Get(shelf_->shelf_widget());
 }
 
-ShelfAlignment WmShelfAura::GetAlignment() {
+ShelfAlignment WmShelfAura::GetAlignment() const {
   return shelf_->alignment();
 }
 
-ShelfBackgroundType WmShelfAura::GetBackgroundType() {
+ShelfBackgroundType WmShelfAura::GetBackgroundType() const {
   return shelf_->shelf_widget()->GetBackgroundType();
 }
 
@@ -39,6 +47,21 @@
   shelf_->shelf_layout_manager()->UpdateVisibilityState();
 }
 
+ShelfVisibilityState WmShelfAura::GetVisibilityState() const {
+  return shelf_layout_manager_ ? shelf_layout_manager_->visibility_state()
+                               : SHELF_HIDDEN;
+}
+
+void WmShelfAura::UpdateIconPositionForWindow(WmWindow* window) {
+  shelf_->UpdateIconPositionForWindow(WmWindowAura::GetAuraWindow(window));
+}
+
+gfx::Rect WmShelfAura::GetScreenBoundsOfItemIconForWindow(
+    wm::WmWindow* window) {
+  return shelf_->GetScreenBoundsOfItemIconForWindow(
+      WmWindowAura::GetAuraWindow(window));
+}
+
 void WmShelfAura::AddObserver(WmShelfObserver* observer) {
   observers_.AddObserver(observer);
 }
@@ -59,5 +82,14 @@
                     OnBackgroundUpdated(background_type, change_type));
 }
 
+void WmShelfAura::WillChangeVisibilityState(ShelfVisibilityState new_state) {
+  FOR_EACH_OBSERVER(WmShelfObserver, observers_,
+                    WillChangeVisibilityState(new_state));
+}
+
+void WmShelfAura::OnShelfIconPositionsChanged() {
+  FOR_EACH_OBSERVER(WmShelfObserver, observers_, OnShelfIconPositionsChanged());
+}
+
 }  // namespace wm
 }  // namespace ash
diff --git a/ash/wm/aura/wm_shelf_aura.h b/ash/wm/aura/wm_shelf_aura.h
index d73d190..0e5b63c 100644
--- a/ash/wm/aura/wm_shelf_aura.h
+++ b/ash/wm/aura/wm_shelf_aura.h
@@ -6,6 +6,7 @@
 #define ASH_WM_AURA_WM_SHELF_AURA_H_
 
 #include "ash/ash_export.h"
+#include "ash/shelf/shelf_icon_observer.h"
 #include "ash/shelf/shelf_layout_manager_observer.h"
 #include "ash/wm/common/shelf/wm_shelf.h"
 #include "base/macros.h"
@@ -20,17 +21,23 @@
 
 // Aura implementation of WmShelf.
 class ASH_EXPORT WmShelfAura : public WmShelf,
-                               public ShelfLayoutManagerObserver {
+                               public ShelfLayoutManagerObserver,
+                               public ShelfIconObserver {
  public:
   explicit WmShelfAura(Shelf* shelf);
   ~WmShelfAura() override;
 
+  static Shelf* GetShelf(WmShelf* shelf);
+
  private:
   // WmShelf:
   WmWindow* GetWindow() override;
-  ShelfAlignment GetAlignment() override;
-  ShelfBackgroundType GetBackgroundType() override;
+  ShelfAlignment GetAlignment() const override;
+  ShelfBackgroundType GetBackgroundType() const override;
   void UpdateVisibilityState() override;
+  ShelfVisibilityState GetVisibilityState() const override;
+  void UpdateIconPositionForWindow(WmWindow* window) override;
+  gfx::Rect GetScreenBoundsOfItemIconForWindow(wm::WmWindow* window) override;
   void AddObserver(WmShelfObserver* observer) override;
   void RemoveObserver(WmShelfObserver* observer) override;
 
@@ -38,6 +45,10 @@
   void WillDeleteShelf() override;
   void OnBackgroundUpdated(wm::ShelfBackgroundType background_type,
                            BackgroundAnimatorChangeType change_type) override;
+  void WillChangeVisibilityState(ShelfVisibilityState new_state) override;
+
+  // ShelfIconObserver:
+  void OnShelfIconPositionsChanged() override;
 
   Shelf* shelf_;
   base::ObserverList<WmShelfObserver> observers_;
diff --git a/ash/wm/boot_splash_screen_chromeos.cc b/ash/wm/boot_splash_screen_chromeos.cc
index ea2f143..8c2fda3 100644
--- a/ash/wm/boot_splash_screen_chromeos.cc
+++ b/ash/wm/boot_splash_screen_chromeos.cc
@@ -7,13 +7,16 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_type.h"
 #include "ui/compositor/paint_recorder.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/canvas.h"
 
+#if defined(USE_X11)
+#include "ui/base/x/x11_util.h"  // nogncheck
+#endif
+
 namespace ash {
 
 // ui::LayerDelegate that copies the aura host window's content to a ui::Layer.
diff --git a/ash/wm/common/shelf/wm_shelf.h b/ash/wm/common/shelf/wm_shelf.h
index 2bcac6e1..488400ad 100644
--- a/ash/wm/common/shelf/wm_shelf.h
+++ b/ash/wm/common/shelf/wm_shelf.h
@@ -8,6 +8,10 @@
 #include "ash/ash_export.h"
 #include "ash/wm/common/shelf/wm_shelf_types.h"
 
+namespace gfx {
+class Rect;
+}
+
 namespace ash {
 namespace wm {
 
@@ -20,12 +24,21 @@
   // Returns the window showing the shelf.
   virtual WmWindow* GetWindow() = 0;
 
-  virtual ShelfAlignment GetAlignment() = 0;
+  virtual ShelfAlignment GetAlignment() const = 0;
 
-  virtual ShelfBackgroundType GetBackgroundType() = 0;
+  virtual ShelfBackgroundType GetBackgroundType() const = 0;
 
   virtual void UpdateVisibilityState() = 0;
 
+  virtual ShelfVisibilityState GetVisibilityState() const = 0;
+
+  virtual void UpdateIconPositionForWindow(WmWindow* window) = 0;
+
+  // Returns the screen bounds of the item for the specified window. If there is
+  // no item for the specified window an empty rect is returned.
+  virtual gfx::Rect GetScreenBoundsOfItemIconForWindow(
+      wm::WmWindow* window) = 0;
+
   virtual void AddObserver(WmShelfObserver* observer) = 0;
   virtual void RemoveObserver(WmShelfObserver* observer) = 0;
 
diff --git a/ash/wm/common/shelf/wm_shelf_observer.h b/ash/wm/common/shelf/wm_shelf_observer.h
index 44d8277..299e6b84 100644
--- a/ash/wm/common/shelf/wm_shelf_observer.h
+++ b/ash/wm/common/shelf/wm_shelf_observer.h
@@ -6,7 +6,6 @@
 #define ASH_WM_COMMON_SHELF_WM_SHELF_OBSERVER_H_
 
 #include "ash/ash_export.h"
-// TODO(sky): refactor into common.
 #include "ash/wm/common/background_animator.h"
 #include "ash/wm/common/shelf/wm_shelf_types.h"
 
@@ -20,6 +19,8 @@
  public:
   virtual void OnBackgroundUpdated(ShelfBackgroundType background_type,
                                    BackgroundAnimatorChangeType change_type) {}
+  virtual void WillChangeVisibilityState(ShelfVisibilityState new_state) {}
+  virtual void OnShelfIconPositionsChanged() {}
 
  protected:
   virtual ~WmShelfObserver() {}
diff --git a/ash/wm/common/shelf/wm_shelf_types.h b/ash/wm/common/shelf/wm_shelf_types.h
index 469491f5..7c05d83c 100644
--- a/ash/wm/common/shelf/wm_shelf_types.h
+++ b/ash/wm/common/shelf/wm_shelf_types.h
@@ -6,6 +6,19 @@
 #define ASH_WM_COMMON_SHELF_WM_SHELF_TYPES_H_
 
 namespace ash {
+
+// TODO(sky): move into wm namespace.
+enum ShelfVisibilityState {
+  // Always visible.
+  SHELF_VISIBLE,
+
+  // A couple of pixels are reserved at the bottom for the shelf.
+  SHELF_AUTO_HIDE,
+
+  // Nothing is shown. Used for fullscreen windows.
+  SHELF_HIDDEN,
+};
+
 namespace wm {
 
 enum ShelfAlignment {
diff --git a/ash/wm/common/shelf/wm_shelf_util.cc b/ash/wm/common/shelf/wm_shelf_util.cc
new file mode 100644
index 0000000..5133feb7
--- /dev/null
+++ b/ash/wm/common/shelf/wm_shelf_util.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 "ash/wm/common/shelf/wm_shelf_util.h"
+
+namespace ash {
+namespace wm {
+
+bool IsHorizontalAlignment(wm::ShelfAlignment alignment) {
+  return alignment == wm::SHELF_ALIGNMENT_BOTTOM ||
+         alignment == wm::SHELF_ALIGNMENT_BOTTOM_LOCKED;
+}
+
+}  // namespace wm
+}  // namespace ash
diff --git a/ash/wm/common/shelf/wm_shelf_util.h b/ash/wm/common/shelf/wm_shelf_util.h
new file mode 100644
index 0000000..2405622d2
--- /dev/null
+++ b/ash/wm/common/shelf/wm_shelf_util.h
@@ -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.
+
+#ifndef ASH_WM_COMMON_SHELF_WM_SHELF_UTIL_H_
+#define ASH_WM_COMMON_SHELF_WM_SHELF_UTIL_H_
+
+#include "ash/ash_export.h"
+#include "ash/wm/common/shelf/wm_shelf_types.h"
+
+namespace ash {
+namespace wm {
+
+// Returns true if the shelf |alignment| is horizontal.
+ASH_EXPORT bool IsHorizontalAlignment(ShelfAlignment alignment);
+
+}  // namespace wm
+}  // namespace ash
+
+#endif  // ASH_WM_COMMON_SHELF_WM_SHELF_UTIL_H_
diff --git a/ash/wm/common/wm_globals.h b/ash/wm/common/wm_globals.h
index 34ad0f2..26eec68 100644
--- a/ash/wm/common/wm_globals.h
+++ b/ash/wm/common/wm_globals.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <memory>
 #include <vector>
 
 #include "ash/ash_export.h"
@@ -17,15 +18,18 @@
 
 namespace ash {
 
-class UserMetricsRecorder;
+class WindowResizer;
 
 namespace wm {
 
+class WindowState;
 class WmActivationObserver;
 class WmDisplayObserver;
 class WmOverviewModeObserver;
 class WmWindow;
 
+enum class WmUserMetricsAction;
+
 // Used for accessing global state.
 class ASH_EXPORT WmGlobals {
  public:
@@ -62,7 +66,19 @@
 
   virtual std::vector<WmWindow*> GetAllRootWindows() = 0;
 
-  virtual UserMetricsRecorder* GetUserMetricsRecorder() = 0;
+  virtual void RecordUserMetricsAction(WmUserMetricsAction action) = 0;
+
+  // Returns a WindowResizer to handle dragging. |next_window_resizer| is
+  // the next WindowResizer in the WindowResizer chain. This may return
+  // |next_window_resizer|.
+  virtual std::unique_ptr<WindowResizer> CreateDragWindowResizer(
+      std::unique_ptr<WindowResizer> next_window_resizer,
+      wm::WindowState* window_state) = 0;
+
+  // TODO(sky): if WindowSelectorController can't be moved over, move these
+  // onto their own local class.
+  virtual bool IsOverviewModeSelecting() = 0;
+  virtual bool IsOverviewModeRestoringMinimizedWindows() = 0;
 
   virtual void AddActivationObserver(WmActivationObserver* observer) = 0;
   virtual void RemoveActivationObserver(WmActivationObserver* observer) = 0;
diff --git a/ash/wm/common/wm_shell_window_ids.h b/ash/wm/common/wm_shell_window_ids.h
index 421f4f0..5b1f036 100644
--- a/ash/wm/common/wm_shell_window_ids.h
+++ b/ash/wm/common/wm_shell_window_ids.h
@@ -25,6 +25,9 @@
 // The container for windows docked to either side of the desktop.
 const int kShellWindowId_DockedContainer = 8;
 
+// The container for the shelf.
+const int kShellWindowId_ShelfContainer = 9;
+
 // The container for panel windows.
 const int kShellWindowId_PanelContainer = 11;
 
@@ -32,6 +35,9 @@
 // The container for the app list.
 const int kShellWindowId_AppListContainer = 12;
 
+// ID of the window created by PhantomWindowController or DragWindowController.
+const int kShellWindowId_PhantomWindow = 23;
+
 }  // namespace ash
 
 #endif  // ASH_WM_COMMON_WM_SHELL_WINDOW_IDS_H_
diff --git a/ash/wm/common/wm_user_metrics_action.h b/ash/wm/common/wm_user_metrics_action.h
new file mode 100644
index 0000000..b192ff6
--- /dev/null
+++ b/ash/wm/common/wm_user_metrics_action.h
@@ -0,0 +1,19 @@
+// 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 ASH_WM_COMMON_WM_USER_METRICS_ACTION_H_
+#define ASH_WM_COMMON_WM_USER_METRICS_ACTION_H_
+
+namespace ash {
+namespace wm {
+
+enum class WmUserMetricsAction {
+  DRAG_MAXIMIZE_LEFT,
+  DRAG_MAXIMIZE_RIGHT,
+};
+
+}  // namespace wm
+}  // namespace ash
+
+#endif  // ASH_WM_COMMON_WM_USER_METRICS_ACTION_H_
diff --git a/ash/wm/panels/attached_panel_window_targeter.cc b/ash/wm/panels/attached_panel_window_targeter.cc
index cb3c67ff..9ccc0d9 100644
--- a/ash/wm/panels/attached_panel_window_targeter.cc
+++ b/ash/wm/panels/attached_panel_window_targeter.cc
@@ -6,6 +6,7 @@
 
 #include "ash/shelf/shelf.h"
 #include "ash/shell.h"
+#include "ash/wm/aura/wm_shelf_aura.h"
 #include "ash/wm/panels/panel_layout_manager.h"
 
 namespace ash {
@@ -50,10 +51,12 @@
 
   DCHECK(panel_layout_manager_->shelf());
   gfx::Insets touch(default_touch_extend_);
-  set_touch_extend(panel_layout_manager_->shelf()->SelectValueForShelfAlignment(
-      gfx::Insets(touch.top(), touch.left(), 0, touch.right()),
-      gfx::Insets(touch.top(), 0, touch.bottom(), touch.right()),
-      gfx::Insets(touch.top(), touch.left(), touch.bottom(), 0)));
+  set_touch_extend(
+      wm::WmShelfAura::GetShelf(panel_layout_manager_->shelf())
+          ->SelectValueForShelfAlignment(
+              gfx::Insets(touch.top(), touch.left(), 0, touch.right()),
+              gfx::Insets(touch.top(), 0, touch.bottom(), touch.right()),
+              gfx::Insets(touch.top(), touch.left(), touch.bottom(), 0)));
 }
 
 }  // namespace ash
diff --git a/ash/wm/panels/panel_layout_manager.cc b/ash/wm/panels/panel_layout_manager.cc
index 5d18d25..181fcdd 100644
--- a/ash/wm/panels/panel_layout_manager.cc
+++ b/ash/wm/panels/panel_layout_manager.cc
@@ -8,28 +8,21 @@
 #include <map>
 #include <utility>
 
-#include "ash/shelf/shelf.h"
-#include "ash/shelf/shelf_layout_manager.h"
-#include "ash/shelf/shelf_types.h"
-#include "ash/shelf/shelf_util.h"
-#include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/wm/aura/wm_window_aura.h"
+#include "ash/wm/common/shelf/wm_shelf.h"
+#include "ash/wm/common/shelf/wm_shelf_util.h"
 #include "ash/wm/common/window_animation_types.h"
 #include "ash/wm/common/window_parenting_utils.h"
 #include "ash/wm/common/window_state.h"
 #include "ash/wm/common/wm_globals.h"
 #include "ash/wm/common/wm_root_window_controller.h"
+#include "ash/wm/common/wm_shell_window_ids.h"
 #include "ash/wm/common/wm_window.h"
 #include "ash/wm/common/wm_window_property.h"
-#include "ash/wm/overview/window_selector_controller.h"
-#include "ash/wm/window_animations.h"
 #include "base/auto_reset.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkPath.h"
-#include "ui/aura/window.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/rect.h"
@@ -190,7 +183,7 @@
 
   void SetAlignment(wm::ShelfAlignment alignment) {
     gfx::Rect callout_bounds = GetWindowBoundsInScreen();
-    if (IsHorizontalAlignment(alignment)) {
+    if (wm::IsHorizontalAlignment(alignment)) {
       callout_bounds.set_width(kArrowWidth);
       callout_bounds.set_height(kArrowHeight);
     } else {
@@ -247,8 +240,7 @@
       in_layout_(false),
       show_callout_widgets_(true),
       dragged_panel_(NULL),
-      shelf_(NULL),
-      shelf_layout_manager_(NULL),
+      shelf_(nullptr),
       last_active_panel_(NULL),
       weak_factory_(this) {
   DCHECK(panel_container);
@@ -275,17 +267,15 @@
 }
 
 void PanelLayoutManager::Shutdown() {
-  if (shelf_layout_manager_)
-    shelf_layout_manager_->RemoveObserver(this);
-  shelf_layout_manager_ = NULL;
+  if (shelf_) {
+    shelf_->RemoveObserver(this);
+    shelf_ = nullptr;
+  }
   for (PanelList::iterator iter = panel_windows_.begin();
        iter != panel_windows_.end(); ++iter) {
     delete iter->callout_widget;
   }
   panel_windows_.clear();
-  if (shelf_)
-    shelf_->RemoveIconObserver(this);
-  shelf_ = NULL;
   wm::WmGlobals* globals = panel_container_->GetGlobals();
   globals->RemoveActivationObserver(this);
   globals->RemoveDisplayObserver(this);
@@ -304,16 +294,11 @@
   Relayout();
 }
 
-void PanelLayoutManager::SetShelf(Shelf* shelf) {
+void PanelLayoutManager::SetShelf(wm::WmShelf* shelf) {
   DCHECK(!shelf_);
-  DCHECK(!shelf_layout_manager_);
   shelf_ = shelf;
-  shelf_->AddIconObserver(this);
-  if (shelf_->shelf_layout_manager()) {
-    shelf_layout_manager_ = shelf_->shelf_layout_manager();
-    WillChangeVisibilityState(shelf_layout_manager_->visibility_state());
-    shelf_layout_manager_->AddObserver(this);
-  }
+  shelf_->AddObserver(this);
+  WillChangeVisibilityState(shelf_->GetVisibilityState());
 }
 
 void PanelLayoutManager::ToggleMinimize(wm::WmWindow* panel) {
@@ -452,16 +437,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// PanelLayoutManager, ShelfIconObserver implementation:
-
-void PanelLayoutManager::OnShelfIconPositionsChanged() {
-  // TODO: As this is called for every animation step now. Relayout needs to be
-  // updated to use current icon position instead of use the ideal bounds so
-  // that the panels slide with their icons instead of jumping.
-  Relayout();
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // PanelLayoutManager, ash::ShellObserver implementation:
 
 void PanelLayoutManager::OnOverviewModeEnded() {
@@ -509,7 +484,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// PanelLayoutManager, aura::client::ActivationChangeObserver implementation:
+// PanelLayoutManager, wm::WmActivationObserver implementation:
 
 void PanelLayoutManager::OnWindowActivated(wm::WmWindow* gained_active,
                                            wm::WmWindow* lost_active) {
@@ -565,6 +540,13 @@
   restore_windows_on_shelf_visible_ = std::move(minimized_windows);
 }
 
+void PanelLayoutManager::OnShelfIconPositionsChanged() {
+  // TODO: As this is called for every animation step now. Relayout needs to be
+  // updated to use current icon position instead of use the ideal bounds so
+  // that the panels slide with their icons instead of jumping.
+  Relayout();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // PanelLayoutManager private implementation:
 
@@ -578,7 +560,7 @@
   panel_slide_settings.SetTransitionDuration(
       base::TimeDelta::FromMilliseconds(kPanelSlideDurationMilliseconds));
   gfx::Rect bounds(panel->GetBounds());
-  bounds.Offset(GetSlideInAnimationOffset(shelf_->alignment()));
+  bounds.Offset(GetSlideInAnimationOffset(shelf_->GetAlignment()));
   panel->SetBoundsDirect(bounds);
   panel->Hide();
   layer->SetOpacity(0);
@@ -596,26 +578,25 @@
 }
 
 void PanelLayoutManager::Relayout() {
-  if (!shelf_ || !shelf_->shelf_widget())
+  if (!shelf_)
     return;
 
   // Suppress layouts during overview mode because changing window bounds
   // interfered with overview mode animations. However, layouts need to be done
   // when the WindowSelectorController is restoring minimized windows so that
   // they actually become visible.
-  WindowSelectorController* window_selector_controller =
-      Shell::GetInstance()->window_selector_controller();
-  if (in_layout_ || !window_selector_controller ||
-      (window_selector_controller->IsSelecting() &&
-          !window_selector_controller->IsRestoringMinimizedWindows()))
+  wm::WmGlobals* globals = panel_container_->GetGlobals();
+  if (in_layout_ || (globals->IsOverviewModeSelecting() &&
+                     !globals->IsOverviewModeRestoringMinimizedWindows())) {
     return;
+  }
 
   base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
 
-  const wm::ShelfAlignment alignment = shelf_->alignment();
-  const bool horizontal = shelf_->IsHorizontalAlignment();
+  const wm::ShelfAlignment alignment = shelf_->GetAlignment();
+  const bool horizontal = wm::IsHorizontalAlignment(shelf_->GetAlignment());
   gfx::Rect shelf_bounds = panel_container_->ConvertRectFromScreen(
-      shelf_->shelf_widget()->GetWindowBoundsInScreen());
+      shelf_->GetWindow()->GetBoundsInScreen());
   int panel_start_bounds = kPanelIdealSpacing;
   int panel_end_bounds =
       horizontal ? panel_container_->GetBounds().width() - kPanelIdealSpacing
@@ -645,8 +626,7 @@
       continue;
     }
 
-    gfx::Rect icon_bounds = shelf_->GetScreenBoundsOfItemIconForWindow(
-        wm::WmWindowAura::GetAuraWindow(panel));
+    gfx::Rect icon_bounds = shelf_->GetScreenBoundsOfItemIconForWindow(panel);
 
     // If both the icon width and height are 0 then there is no icon in the
     // shelf. If the shelf is hidden, one of the height or width will be
@@ -772,7 +752,7 @@
   // the titlebar--even though it doesn't update the shelf icon positions, we
   // still want the visual effect.
   std::map<int, wm::WmWindow*> window_ordering;
-  const bool horizontal = shelf_->IsHorizontalAlignment();
+  const bool horizontal = wm::IsHorizontalAlignment(shelf_->GetAlignment());
   for (PanelList::const_iterator it = panel_windows_.begin();
        it != panel_windows_.end(); ++it) {
     gfx::Rect bounds = it->window->GetBounds();
@@ -807,7 +787,7 @@
 }
 
 void PanelLayoutManager::UpdateCallouts() {
-  const bool horizontal = shelf_->IsHorizontalAlignment();
+  const bool horizontal = wm::IsHorizontalAlignment(shelf_->GetAlignment());
   for (PanelList::iterator iter = panel_windows_.begin();
        iter != panel_windows_.end(); ++iter) {
     wm::WmWindow* panel = iter->window;
@@ -817,8 +797,7 @@
     gfx::Rect current_bounds = panel->GetBoundsInScreen();
     gfx::Rect bounds =
         panel->GetParent()->ConvertRectToScreen(panel->GetTargetBounds());
-    gfx::Rect icon_bounds = shelf_->GetScreenBoundsOfItemIconForWindow(
-        wm::WmWindowAura::GetAuraWindow(panel));
+    gfx::Rect icon_bounds = shelf_->GetScreenBoundsOfItemIconForWindow(panel);
     if (icon_bounds.IsEmpty() || !panel->GetLayer()->GetTargetVisibility() ||
         panel == dragged_panel_ || !show_callout_widgets_) {
       callout_widget->Hide();
@@ -844,9 +823,9 @@
           current_bounds.y() - callout_bounds.y(),
           callout_bounds.bottom() - current_bounds.bottom());
     }
-    if (shelf_->alignment() == wm::SHELF_ALIGNMENT_LEFT)
+    if (shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_LEFT)
       callout_bounds.set_x(bounds.x() - callout_bounds.width());
-    else if (shelf_->alignment() == wm::SHELF_ALIGNMENT_RIGHT)
+    else if (shelf_->GetAlignment() == wm::SHELF_ALIGNMENT_RIGHT)
       callout_bounds.set_x(bounds.right());
     else
       callout_bounds.set_y(bounds.bottom());
diff --git a/ash/wm/panels/panel_layout_manager.h b/ash/wm/panels/panel_layout_manager.h
index 34ef96be..2f013aab 100644
--- a/ash/wm/panels/panel_layout_manager.h
+++ b/ash/wm/panels/panel_layout_manager.h
@@ -10,8 +10,8 @@
 
 #include "ash/ash_export.h"
 #include "ash/shelf/shelf_icon_observer.h"
-#include "ash/shelf/shelf_layout_manager_observer.h"
 #include "ash/shell_observer.h"
+#include "ash/wm/common/shelf/wm_shelf_observer.h"
 #include "ash/wm/common/window_state_observer.h"
 #include "ash/wm/common/wm_activation_observer.h"
 #include "ash/wm/common/wm_display_observer.h"
@@ -45,6 +45,7 @@
 
 namespace wm {
 class WmRootWindowController;
+class WmShelf;
 }
 
 // PanelLayoutManager is responsible for organizing panels within the
@@ -66,7 +67,7 @@
       public wm::WmRootWindowControllerObserver,
       public wm::WmWindowObserver,
       public keyboard::KeyboardControllerObserver,
-      public ShelfLayoutManagerObserver {
+      public wm::WmShelfObserver {
  public:
   explicit PanelLayoutManager(wm::WmWindow* panel_container);
   ~PanelLayoutManager() override;
@@ -89,8 +90,8 @@
   // Returns the callout widget (arrow) for |panel|.
   views::Widget* GetCalloutWidgetForPanel(wm::WmWindow* panel);
 
-  Shelf* shelf() { return shelf_; }
-  void SetShelf(Shelf* shelf);
+  wm::WmShelf* shelf() { return shelf_; }
+  void SetShelf(wm::WmShelf* shelf);
 
   // Overridden from wm::WmLayoutManager
   void OnWindowResized() override;
@@ -102,9 +103,6 @@
   void SetChildBounds(wm::WmWindow* child,
                       const gfx::Rect& requested_bounds) override;
 
-  // Overridden from ShelfIconObserver
-  void OnShelfIconPositionsChanged() override;
-
   // Overridden from wm::WmOverviewModeObserver
   void OnOverviewModeEnded() override;
 
@@ -127,8 +125,9 @@
   // Overridden from WindowTreeHostManager::Observer
   void OnDisplayConfigurationChanged() override;
 
-  // Overridden from ShelfLayoutManagerObserver
+  // Overridden from wm::WmShelfObserver
   void WillChangeVisibilityState(ShelfVisibilityState new_state) override;
+  void OnShelfIconPositionsChanged() override;
 
  private:
   friend class PanelLayoutManagerTest;
@@ -198,9 +197,7 @@
   // The panel being dragged.
   wm::WmWindow* dragged_panel_;
   // The shelf we are observing for shelf icon changes.
-  Shelf* shelf_;
-  // The shelf layout manager being observed for visibility changes.
-  ShelfLayoutManager* shelf_layout_manager_;
+  wm::WmShelf* shelf_;
 
   // When not NULL, the shelf is hidden (i.e. full screen) and this tracks the
   // set of panel windows which have been temporarily hidden and need to be
diff --git a/ash/wm/panels/panel_window_resizer.cc b/ash/wm/panels/panel_window_resizer.cc
index 8ece548..2a6ee3c 100644
--- a/ash/wm/panels/panel_window_resizer.cc
+++ b/ash/wm/panels/panel_window_resizer.cc
@@ -4,20 +4,16 @@
 
 #include "ash/wm/panels/panel_window_resizer.h"
 
-#include "ash/shelf/shelf.h"
-#include "ash/shelf/shelf_types.h"
-#include "ash/shelf/shelf_widget.h"
-#include "ash/shell_window_ids.h"
-#include "ash/wm/aura/wm_window_aura.h"
+#include "ash/wm/common/shelf/wm_shelf.h"
 #include "ash/wm/common/window_parenting_utils.h"
 #include "ash/wm/common/window_state.h"
 #include "ash/wm/common/wm_root_window_controller.h"
+#include "ash/wm/common/wm_shell_window_ids.h"
 #include "ash/wm/common/wm_window.h"
 #include "ash/wm/panels/panel_layout_manager.h"
 #include "ui/base/hit_test.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/display/screen.h"
-#include "ui/views/widget/widget.h"
 
 namespace ash {
 
@@ -122,10 +118,8 @@
     PanelLayoutManager* panel_layout_manager =
         PanelLayoutManager::Get(panel_container_);
     gfx::Rect launcher_bounds = GetTarget()->GetParent()->ConvertRectFromScreen(
-        panel_layout_manager->shelf()
-            ->shelf_widget()
-            ->GetWindowBoundsInScreen());
-    switch (panel_layout_manager->shelf()->alignment()) {
+        panel_layout_manager->shelf()->GetWindow()->GetBoundsInScreen());
+    switch (panel_layout_manager->shelf()->GetAlignment()) {
       case wm::SHELF_ALIGNMENT_BOTTOM:
       case wm::SHELF_ALIGNMENT_BOTTOM_LOCKED:
         if (bounds.bottom() >= (launcher_bounds.y() -
@@ -202,8 +196,7 @@
   if (panel_container_) {
     PanelLayoutManager::Get(panel_container_)
         ->shelf()
-        ->UpdateIconPositionForWindow(
-            wm::WmWindowAura::GetAuraWindow(GetTarget()));
+        ->UpdateIconPositionForWindow(GetTarget());
   }
 }
 
diff --git a/ash/wm/workspace/phantom_window_controller.cc b/ash/wm/workspace/phantom_window_controller.cc
index f39dc65..025ca11 100644
--- a/ash/wm/workspace/phantom_window_controller.cc
+++ b/ash/wm/workspace/phantom_window_controller.cc
@@ -6,9 +6,9 @@
 
 #include <math.h>
 
-#include "ash/shell_window_ids.h"
 #include "ash/wm/common/root_window_finder.h"
 #include "ash/wm/common/wm_root_window_controller.h"
+#include "ash/wm/common/wm_shell_window_ids.h"
 #include "ash/wm/common/wm_window.h"
 #include "grit/ash_resources.h"
 #include "ui/compositor/layer.h"
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index 1540fa2..577ba24 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -9,7 +9,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/metrics/user_metrics_recorder.h"
 #include "ash/wm/common/default_window_resizer.h"
 #include "ash/wm/common/dock/docked_window_layout_manager.h"
 #include "ash/wm/common/window_positioning_utils.h"
@@ -19,9 +18,9 @@
 #include "ash/wm/common/wm_root_window_controller.h"
 #include "ash/wm/common/wm_screen_util.h"
 #include "ash/wm/common/wm_shell_window_ids.h"
+#include "ash/wm/common/wm_user_metrics_action.h"
 #include "ash/wm/common/wm_window.h"
 #include "ash/wm/dock/docked_window_resizer.h"
-#include "ash/wm/drag_window_resizer.h"
 #include "ash/wm/panels/panel_window_resizer.h"
 #include "ash/wm/workspace/phantom_window_controller.h"
 #include "ash/wm/workspace/two_step_edge_cycler.h"
@@ -85,8 +84,8 @@
   } else {
     window_resizer.reset(DefaultWindowResizer::Create(window_state));
   }
-  window_resizer.reset(
-      DragWindowResizer::Create(window_resizer.release(), window_state));
+  window_resizer = window->GetGlobals()->CreateDragWindowResizer(
+      std::move(window_resizer), window_state);
   if (window->GetType() == ui::wm::WINDOW_TYPE_PANEL)
     window_resizer.reset(
         PanelWindowResizer::Create(window_resizer.release(), window_state));
@@ -429,15 +428,15 @@
           details().restore_bounds);
     }
     if (!dock_layout_->is_dragged_window_docked()) {
-      UserMetricsRecorder* metrics = globals_->GetUserMetricsRecorder();
       // TODO(oshima): Add event source type to WMEvent and move
       // metrics recording inside WindowState::OnWMEvent.
       const wm::WMEvent event(snap_type_ == SNAP_LEFT ?
                               wm::WM_EVENT_SNAP_LEFT : wm::WM_EVENT_SNAP_RIGHT);
       window_state()->OnWMEvent(&event);
-      metrics->RecordUserMetricsAction(
-          snap_type_ == SNAP_LEFT ?
-          UMA_DRAG_MAXIMIZE_LEFT : UMA_DRAG_MAXIMIZE_RIGHT);
+      globals_->RecordUserMetricsAction(
+          snap_type_ == SNAP_LEFT
+              ? wm::WmUserMetricsAction::DRAG_MAXIMIZE_LEFT
+              : wm::WmUserMetricsAction::DRAG_MAXIMIZE_RIGHT);
       snapped = true;
     }
   }
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 7136d40fab..fc2c0f2 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1693,6 +1693,7 @@
     "base64url_unittest.cc",
     "big_endian_unittest.cc",
     "bind_unittest.cc",
+    "bit_cast_unittest.cc",
     "bits_unittest.cc",
     "build_time_unittest.cc",
     "callback_helpers_unittest.cc",
diff --git a/base/android/context_utils.cc b/base/android/context_utils.cc
index e9ab723..fd62c45f 100644
--- a/base/android/context_utils.cc
+++ b/base/android/context_utils.cc
@@ -38,6 +38,11 @@
   return g_application_context.Get().obj();
 }
 
+void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) {
+  SetNativeApplicationContext(env, context);
+  Java_ContextUtils_initJavaSideApplicationContext(env, context.obj());
+}
+
 static void InitNativeSideApplicationContext(
     JNIEnv* env,
     const JavaParamRef<jclass>& clazz,
diff --git a/base/android/context_utils.h b/base/android/context_utils.h
index f172d93..52895a9 100644
--- a/base/android/context_utils.h
+++ b/base/android/context_utils.h
@@ -18,6 +18,14 @@
 // must NOT release it.
 BASE_EXPORT jobject GetApplicationContext();
 
+// Initialize the global application context object.
+// Either this or the Java equivalent ContextUtils.initApplicationContext must
+// be called once during startup. JNI bindings must have been initialized, as
+// the context is stored on both sides.
+BASE_EXPORT void InitApplicationContext(
+    JNIEnv* env,
+    const base::android::JavaRef<jobject>& context);
+
 bool RegisterContextUtils(JNIEnv* env);
 
 }  // namespace android
diff --git a/base/android/java/src/org/chromium/base/ContextUtils.java b/base/android/java/src/org/chromium/base/ContextUtils.java
index 95cdc40..51adcff 100644
--- a/base/android/java/src/org/chromium/base/ContextUtils.java
+++ b/base/android/java/src/org/chromium/base/ContextUtils.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 
+import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 
 /**
@@ -13,7 +14,6 @@
  */
 @JNINamespace("base::android")
 public class ContextUtils {
-    private static final String TAG = "ContextUtils";
     private static Context sApplicationContext;
 
     /**
@@ -29,52 +29,34 @@
      * may make is that it is a Context whose lifetime is the same as the lifetime of the process.
      */
     public static Context getApplicationContext() {
+        assert sApplicationContext != null;
         return sApplicationContext;
     }
 
     /**
-     * Initializes the java application context.
+     * Initialize the Android application context.
      *
-     * This should be called exactly once early on during startup, before native is loaded and
-     * before any other clients make use of the application context through this class.
-     *
-     * @param appContext The application context.
+     * Either this or the native equivalent base::android::InitApplicationContext must be called
+     * once during startup. JNI bindings must have been initialized, as the context is stored on
+     * both sides.
      */
     public static void initApplicationContext(Context appContext) {
-        // Conceding that occasionally in tests, native is loaded before the browser process is
-        // started, in which case the browser process re-sets the application context.
-        if (sApplicationContext != null && sApplicationContext != appContext) {
-            throw new RuntimeException("Attempting to set multiple global application contexts.");
-        }
+        assert appContext != null;
+        assert sApplicationContext == null || sApplicationContext == appContext;
         initJavaSideApplicationContext(appContext);
+        nativeInitNativeSideApplicationContext(appContext);
     }
 
     /**
-     * Initialize the native Android application context to be the same as the java counter-part.
+     * JUnit Robolectric tests run without native code; allow them to set just the Java-side
+     * context. Do not use in configurations that actually run on Android!
      */
-    public static void initApplicationContextForNative() {
-        if (sApplicationContext == null) {
-            throw new RuntimeException("Cannot have native global application context be null.");
-        }
-        nativeInitNativeSideApplicationContext(sApplicationContext);
-    }
-
-    /**
-     * Occasionally tests cannot ensure the application context doesn't change between tests (junit)
-     * and sometimes specific tests has its own special needs, initApplicationContext should be used
-     * as much as possible, but this method can be used to override it.
-     *
-     * @param appContext The new application context.
-     */
-    @VisibleForTesting
-    public static void initApplicationContextForTests(Context appContext) {
+    public static void initApplicationContextForJUnitTests(Context appContext) {
         initJavaSideApplicationContext(appContext);
     }
 
+    @CalledByNative
     private static void initJavaSideApplicationContext(Context appContext) {
-        if (appContext == null) {
-            throw new RuntimeException("Global application context cannot be set to null.");
-        }
         sApplicationContext = appContext;
     }
 
diff --git a/base/android/java/src/org/chromium/base/SysUtils.java b/base/android/java/src/org/chromium/base/SysUtils.java
index db3335d4..04a8332 100644
--- a/base/android/java/src/org/chromium/base/SysUtils.java
+++ b/base/android/java/src/org/chromium/base/SysUtils.java
@@ -109,6 +109,6 @@
         }
 
         int ramSizeKB = amountOfPhysicalMemoryKB();
-        return (ramSizeKB > 0 && ramSizeKB / 1024 < ANDROID_LOW_MEMORY_DEVICE_THRESHOLD_MB);
+        return (ramSizeKB > 0 && ramSizeKB / 1024 <= ANDROID_LOW_MEMORY_DEVICE_THRESHOLD_MB);
     }
 }
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
index 7858271..6665ddfd 100644
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -13,7 +13,6 @@
 import android.os.SystemClock;
 
 import org.chromium.base.CommandLine;
-import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.PackageUtils;
 import org.chromium.base.TraceEvent;
@@ -133,8 +132,6 @@
      *  @param context The context in which the method is called.
      */
     public void ensureInitialized(Context context) throws ProcessInitException {
-        // TODO(wnwen): Move this call appropriately down to the tests that need it.
-        ContextUtils.initApplicationContext(context.getApplicationContext());
         synchronized (sLock) {
             if (mInitialized) {
                 // Already initialized, nothing to do.
@@ -363,10 +360,6 @@
         nativeInitCommandLine(CommandLine.getJavaSwitchesOrNull());
         CommandLine.enableNativeProxy();
         mCommandLineSwitched = true;
-
-        // Ensure that native side application context is loaded and in sync with java side. Must do
-        // this here so webview also gets its application context set before fully initializing.
-        ContextUtils.initApplicationContextForNative();
     }
 
     // Invoke base::android::LibraryLoaded in library_loader_hooks.cc
@@ -375,13 +368,23 @@
             return;
         }
 
-        ensureCommandLineSwitchedAlreadyLocked();
+        // Setup the native command line if necessary.
+        if (!mCommandLineSwitched) {
+            nativeInitCommandLine(CommandLine.getJavaSwitchesOrNull());
+        }
 
         if (!nativeLibraryLoaded()) {
             Log.e(TAG, "error calling nativeLibraryLoaded");
             throw new ProcessInitException(LoaderErrors.LOADER_ERROR_FAILED_TO_REGISTER_JNI);
         }
 
+        // The Chrome JNI is registered by now so we can switch the Java
+        // command line over to delegating to native if it's necessary.
+        if (!mCommandLineSwitched) {
+            CommandLine.enableNativeProxy();
+            mCommandLineSwitched = true;
+        }
+
         // From now on, keep tracing in sync with native.
         TraceEvent.registerNativeEnabledObserver();
 
diff --git a/base/base.gyp b/base/base.gyp
index db408a71d..0bfe5ae 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -379,6 +379,7 @@
         'big_endian_unittest.cc',
         'bind_unittest.cc',
         'bind_unittest.nc',
+        'bit_cast_unittest.cc',
         'bits_unittest.cc',
         'build_time_unittest.cc',
         'callback_helpers_unittest.cc',
diff --git a/base/base_switches.cc b/base/base_switches.cc
index d1a38e4b..fa0bc33 100644
--- a/base/base_switches.cc
+++ b/base/base_switches.cc
@@ -20,6 +20,10 @@
 // the memory-infra category is enabled.
 const char kEnableHeapProfiling[]           = "enable-heap-profiling";
 
+// Report native (walk the stack) allocation traces. By default pseudo stacks
+// derived from trace events are reported.
+const char kEnableHeapProfilingModeNative[] = "native";
+
 // Generates full memory crash dump.
 const char kFullMemoryCrashReport[]         = "full-memory-crash-report";
 
diff --git a/base/base_switches.h b/base/base_switches.h
index 300c5f7..b80077b 100644
--- a/base/base_switches.h
+++ b/base/base_switches.h
@@ -15,6 +15,7 @@
 extern const char kDisableLowEndDeviceMode[];
 extern const char kEnableCrashReporter[];
 extern const char kEnableHeapProfiling[];
+extern const char kEnableHeapProfilingModeNative[];
 extern const char kEnableLowEndDeviceMode[];
 extern const char kForceFieldTrials[];
 extern const char kFullMemoryCrashReport[];
diff --git a/base/bit_cast.h b/base/bit_cast.h
index 42d08ee8..c9514bc 100644
--- a/base/bit_cast.h
+++ b/base/bit_cast.h
@@ -65,9 +65,11 @@
                 "bit_cast requires source and destination to be the same size");
 
 #if (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) || \
-     defined(_LIBCPP_VERSION))
+     (defined(__clang__) && defined(_LIBCPP_VERSION)))
   // GCC 5.1 contains the first libstdc++ with is_trivially_copyable.
   // Assume libc++ Just Works: is_trivially_copyable added on May 13th 2011.
+  // However, with libc++ when GCC is the compiler the trait is buggy, see
+  // crbug.com/607158, so fall back to the less strict variant for non-clang.
   static_assert(std::is_trivially_copyable<Dest>::value,
                 "non-trivially-copyable bit_cast is undefined");
   static_assert(std::is_trivially_copyable<Source>::value,
diff --git a/base/bit_cast_unittest.cc b/base/bit_cast_unittest.cc
new file mode 100644
index 0000000..757b0c65
--- /dev/null
+++ b/base/bit_cast_unittest.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 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/bit_cast.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace {
+
+TEST(BitCastTest, FloatIntFloat) {
+  float f = 3.1415926f;
+  int i = bit_cast<int32_t>(f);
+  float f2 = bit_cast<float>(i);
+  EXPECT_EQ(f, f2);
+}
+
+struct A {
+  int x;
+};
+
+TEST(BitCastTest, StructureInt) {
+  A a = { 1 };
+  int b = bit_cast<int>(a);
+  EXPECT_EQ(1, b);
+}
+
+
+}  // namespace
+}  // namespace base
diff --git a/base/debug/profiler.cc b/base/debug/profiler.cc
index 15d1d8c..a4426ab 100644
--- a/base/debug/profiler.cc
+++ b/base/debug/profiler.cc
@@ -154,8 +154,8 @@
   FunctionSearchContext* context =
       reinterpret_cast<FunctionSearchContext*>(cookie);
 
-  DCHECK_NE(static_cast<FunctionSearchContext*>(NULL), context);
-  DCHECK_EQ(static_cast<FARPROC>(NULL), context->function);
+  DCHECK_NE(nullptr, context);
+  DCHECK_EQ(nullptr, context->function);
 
   // Our import address table contains pointers to the functions we import
   // at this point. Let's retrieve the first such function and use it to
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index 801c84a..c1bcf4a 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -5,10 +5,11 @@
 #include "base/json/json_parser.h"
 
 #include <cmath>
-#include <memory>
+#include <utility>
 
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
@@ -27,16 +28,19 @@
 
 const int32_t kExtendedASCIIStart = 0x80;
 
-// This and the class below are used to own the JSON input string for when
-// string tokens are stored as StringPiece instead of std::string. This
-// optimization avoids about 2/3rds of string memory copies. The constructor
-// takes ownership of the input string. The real root value is Swap()ed into
-// the new instance.
+// DictionaryHiddenRootValue and ListHiddenRootValue are used in conjunction
+// with JSONStringValue as an optimization for reducing the number of string
+// copies. When this optimization is active, the parser uses a hidden root to
+// keep the original JSON input string live and creates JSONStringValue children
+// holding StringPiece references to the input string, avoiding about 2/3rds of
+// string memory copies. The real root value is Swap()ed into the new instance.
 class DictionaryHiddenRootValue : public DictionaryValue {
  public:
-  DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) {
+  DictionaryHiddenRootValue(std::unique_ptr<std::string> json,
+                            std::unique_ptr<Value> root)
+      : json_(std::move(json)) {
     DCHECK(root->IsType(Value::TYPE_DICTIONARY));
-    DictionaryValue::Swap(static_cast<DictionaryValue*>(root));
+    DictionaryValue::Swap(static_cast<DictionaryValue*>(root.get()));
   }
 
   void Swap(DictionaryValue* other) override {
@@ -44,7 +48,7 @@
 
     // First deep copy to convert JSONStringValue to std::string and swap that
     // copy with |other|, which contains the new contents of |this|.
-    std::unique_ptr<DictionaryValue> copy(DeepCopy());
+    std::unique_ptr<DictionaryValue> copy(CreateDeepCopy());
     copy->Swap(other);
 
     // Then erase the contents of the current dictionary and swap in the
@@ -71,7 +75,7 @@
     if (!DictionaryValue::RemoveWithoutPathExpansion(key, &out_owned))
       return false;
 
-    out->reset(out_owned->DeepCopy());
+    *out = out_owned->CreateDeepCopy();
 
     return true;
   }
@@ -84,9 +88,11 @@
 
 class ListHiddenRootValue : public ListValue {
  public:
-  ListHiddenRootValue(std::string* json, Value* root) : json_(json) {
+  ListHiddenRootValue(std::unique_ptr<std::string> json,
+                      std::unique_ptr<Value> root)
+      : json_(std::move(json)) {
     DCHECK(root->IsType(Value::TYPE_LIST));
-    ListValue::Swap(static_cast<ListValue*>(root));
+    ListValue::Swap(static_cast<ListValue*>(root.get()));
   }
 
   void Swap(ListValue* other) override {
@@ -94,7 +100,7 @@
 
     // First deep copy to convert JSONStringValue to std::string and swap that
     // copy with |other|, which contains the new contents of |this|.
-    std::unique_ptr<ListValue> copy(DeepCopy());
+    std::unique_ptr<ListValue> copy(CreateDeepCopy());
     copy->Swap(other);
 
     // Then erase the contents of the current list and swap in the new contents,
@@ -117,7 +123,7 @@
     if (!ListValue::Remove(index, &out_owned))
       return false;
 
-    out->reset(out_owned->DeepCopy());
+    *out = out_owned->CreateDeepCopy();
 
     return true;
   }
@@ -133,10 +139,8 @@
 // otherwise the referenced string will not be guaranteed to outlive it.
 class JSONStringValue : public Value {
  public:
-  explicit JSONStringValue(const StringPiece& piece)
-      : Value(TYPE_STRING),
-        string_piece_(piece) {
-  }
+  explicit JSONStringValue(StringPiece piece)
+      : Value(TYPE_STRING), string_piece_(piece) {}
 
   // Overridden from Value:
   bool GetAsString(std::string* out_value) const override {
@@ -203,13 +207,13 @@
 JSONParser::~JSONParser() {
 }
 
-Value* JSONParser::Parse(const StringPiece& input) {
+std::unique_ptr<Value> JSONParser::Parse(StringPiece input) {
   std::unique_ptr<std::string> input_copy;
   // If the children of a JSON root can be detached, then hidden roots cannot
   // be used, so do not bother copying the input because StringPiece will not
   // be used anywhere.
   if (!(options_ & JSON_DETACHABLE_CHILDREN)) {
-    input_copy.reset(new std::string(input.as_string()));
+    input_copy = WrapUnique(new std::string(input.as_string()));
     start_pos_ = input_copy->data();
   } else {
     start_pos_ = input.data();
@@ -236,14 +240,14 @@
 
   // Parse the first and any nested tokens.
   std::unique_ptr<Value> root(ParseNextToken());
-  if (!root.get())
-    return NULL;
+  if (!root)
+    return nullptr;
 
   // Make sure the input stream is at an end.
   if (GetNextToken() != T_END_OF_INPUT) {
     if (!CanConsume(1) || (NextChar() && GetNextToken() != T_END_OF_INPUT)) {
       ReportError(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, 1);
-      return NULL;
+      return nullptr;
     }
   }
 
@@ -251,19 +255,21 @@
   // hidden root.
   if (!(options_ & JSON_DETACHABLE_CHILDREN)) {
     if (root->IsType(Value::TYPE_DICTIONARY)) {
-      return new DictionaryHiddenRootValue(input_copy.release(), root.get());
+      return WrapUnique(new DictionaryHiddenRootValue(std::move(input_copy),
+                                                      std::move(root)));
     } else if (root->IsType(Value::TYPE_LIST)) {
-      return new ListHiddenRootValue(input_copy.release(), root.get());
+      return WrapUnique(
+          new ListHiddenRootValue(std::move(input_copy), std::move(root)));
     } else if (root->IsType(Value::TYPE_STRING)) {
       // A string type could be a JSONStringValue, but because there's no
       // corresponding HiddenRootValue, the memory will be lost. Deep copy to
       // preserve it.
-      return root->DeepCopy();
+      return root->CreateDeepCopy();
     }
   }
 
   // All other values can be returned directly.
-  return root.release();
+  return root;
 }
 
 JSONReader::JsonParseError JSONParser::error_code() const {
diff --git a/base/json/json_parser.h b/base/json/json_parser.h
index 304edd1a..5bdec58 100644
--- a/base/json/json_parser.h
+++ b/base/json/json_parser.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
 #include <string>
 
 #include "base/base_export.h"
@@ -50,7 +51,7 @@
 
   // Parses the input string according to the set options and returns the
   // result as a Value owned by the caller.
-  Value* Parse(const StringPiece& input);
+  std::unique_ptr<Value> Parse(StringPiece input);
 
   // Returns the error code.
   JSONReader::JsonParseError error_code() const;
diff --git a/base/json/json_reader.cc b/base/json/json_reader.cc
index 983508c..4ff7496b 100644
--- a/base/json/json_reader.cc
+++ b/base/json/json_reader.cc
@@ -6,7 +6,6 @@
 
 #include "base/json/json_parser.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/values.h"
 
 namespace base {
@@ -44,15 +43,15 @@
 }
 
 // static
-std::unique_ptr<Value> JSONReader::Read(const StringPiece& json) {
+std::unique_ptr<Value> JSONReader::Read(StringPiece json) {
   internal::JSONParser parser(JSON_PARSE_RFC);
-  return WrapUnique(parser.Parse(json));
+  return parser.Parse(json);
 }
 
 // static
-std::unique_ptr<Value> JSONReader::Read(const StringPiece& json, int options) {
+std::unique_ptr<Value> JSONReader::Read(StringPiece json, int options) {
   internal::JSONParser parser(options);
-  return WrapUnique(parser.Parse(json));
+  return parser.Parse(json);
 }
 
 
@@ -107,8 +106,8 @@
   }
 }
 
-std::unique_ptr<Value> JSONReader::ReadToValue(const std::string& json) {
-  return WrapUnique(parser_->Parse(json));
+std::unique_ptr<Value> JSONReader::ReadToValue(StringPiece json) {
+  return parser_->Parse(json);
 }
 
 JSONReader::JsonParseError JSONReader::error_code() const {
diff --git a/base/json/json_reader.h b/base/json/json_reader.h
index 7b5b3b0..f647724 100644
--- a/base/json/json_reader.h
+++ b/base/json/json_reader.h
@@ -93,12 +93,12 @@
 
   // Reads and parses |json|, returning a Value. The caller owns the returned
   // instance. If |json| is not a properly formed JSON string, returns NULL.
-  static std::unique_ptr<Value> Read(const StringPiece& json);
+  static std::unique_ptr<Value> Read(StringPiece json);
 
   // Reads and parses |json|, returning a Value owned by the caller. The
   // parser respects the given |options|. If the input is not properly formed,
   // returns NULL.
-  static std::unique_ptr<Value> Read(const StringPiece& json, int options);
+  static std::unique_ptr<Value> Read(StringPiece json, int options);
 
   // Reads and parses |json| like Read(). |error_code_out| and |error_msg_out|
   // are optional. If specified and NULL is returned, they will be populated
@@ -117,7 +117,7 @@
   static std::string ErrorCodeToString(JsonParseError error_code);
 
   // Parses an input string into a Value that is owned by the caller.
-  std::unique_ptr<Value> ReadToValue(const std::string& json);
+  std::unique_ptr<Value> ReadToValue(StringPiece json);
 
   // Returns the error code if the last call to ReadToValue() failed.
   // Returns JSON_NO_ERROR otherwise.
diff --git a/base/logging.cc b/base/logging.cc
index a5f9e11..4390d8cd 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -454,6 +454,11 @@
 template std::string* MakeCheckOpString<std::string, std::string>(
     const std::string&, const std::string&, const char* name);
 
+template <>
+void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& p) {
+  (*os) << "nullptr";
+}
+
 #if !defined(NDEBUG)
 // Displays a message box to the user with the error message in it.
 // Used for fatal messages, where we close the app simultaneously.
diff --git a/base/logging.h b/base/logging.h
index bbbfce14..e3f0cef 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -513,6 +513,18 @@
 
 #endif
 
+// This formats a value for a failing CHECK_XX statement.  Ordinarily,
+// it uses the definition for operator<<, with a few special cases below.
+template <typename T>
+inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
+  (*os) << v;
+}
+
+// We need an explicit specialization for std::nullptr_t.
+template <>
+BASE_EXPORT void MakeCheckOpValueString(std::ostream* os,
+                                        const std::nullptr_t& p);
+
 // Build the error message string.  This is separate from the "Impl"
 // function template because it is not performance critical and so can
 // be out of line, while the "Impl" code should be inline.  Caller
@@ -520,7 +532,11 @@
 template<class t1, class t2>
 std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
   std::ostringstream ss;
-  ss << names << " (" << v1 << " vs. " << v2 << ")";
+  ss << names << " (";
+  MakeCheckOpValueString(&ss, v1);
+  ss << " vs. ";
+  MakeCheckOpValueString(&ss, v2);
+  ss << ")";
   std::string* msg = new std::string(ss.str());
   return msg;
 }
@@ -714,9 +730,10 @@
 // for example:
 //   DCHECK_EQ(string("abc")[1], 'b');
 //
-// WARNING: These may not compile correctly if one of the arguments is a pointer
-// and the other is NULL. To work around this, simply static_cast NULL to the
-// type of the desired pointer.
+// WARNING: These don't compile correctly if one of the arguments is a pointer
+// and the other is NULL.  In new code, prefer nullptr instead.  To
+// work around this for C++98, simply static_cast NULL to the type of the
+// desired pointer.
 
 #define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2)
 #define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2)
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc
index 531af1a3..7254265 100644
--- a/base/logging_unittest.cc
+++ b/base/logging_unittest.cc
@@ -241,6 +241,16 @@
   EXPECT_EQ(DCHECK_IS_ON() ? 2 : 0, log_sink_call_count);
   DCHECK_EQ(0, 1);
   EXPECT_EQ(DCHECK_IS_ON() ? 3 : 0, log_sink_call_count);
+
+  // Test DCHECK on std::nullptr_t
+  log_sink_call_count = 0;
+  const void* p_null = nullptr;
+  const void* p_not_null = &p_null;
+  DCHECK_EQ(p_null, nullptr);
+  DCHECK_EQ(nullptr, p_null);
+  DCHECK_NE(p_not_null, nullptr);
+  DCHECK_NE(nullptr, p_not_null);
+  EXPECT_EQ(0, log_sink_call_count);
 }
 
 TEST_F(LoggingTest, DcheckReleaseBehavior) {
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
index 6ae5df3..d872fc3 100644
--- a/base/mac/foundation_util.mm
+++ b/base/mac/foundation_util.mm
@@ -18,6 +18,10 @@
 #include "build/build_config.h"
 
 #if !defined(OS_IOS)
+#import <AppKit/AppKit.h>
+#endif
+
+#if !defined(OS_IOS)
 extern "C" {
 CFTypeID SecACLGetTypeID();
 CFTypeID SecTrustedApplicationGetTypeID();
@@ -316,7 +320,7 @@
   DCHECK(!cf_val ||
          CTFontGetTypeID() == CFGetTypeID(cf_val) ||
          (_CFIsObjC(CTFontGetTypeID(), cf_val) &&
-          [ns_val isKindOfClass:NSClassFromString(@"NSFont")]));
+          [ns_val isKindOfClass:[NSFont class]]));
   return ns_val;
 }
 
@@ -324,7 +328,7 @@
   CTFontRef cf_val = reinterpret_cast<CTFontRef>(ns_val);
   DCHECK(!cf_val ||
          CTFontGetTypeID() == CFGetTypeID(cf_val) ||
-         [ns_val isKindOfClass:NSClassFromString(@"NSFont")]);
+         [ns_val isKindOfClass:[NSFont class]]);
   return cf_val;
 }
 #endif
@@ -388,7 +392,7 @@
     return NULL;
 
   id<NSObject> ns_val = reinterpret_cast<id>(const_cast<void*>(cf_val));
-  if ([ns_val isKindOfClass:NSClassFromString(@"NSFont")]) {
+  if ([ns_val isKindOfClass:[NSFont class]]) {
     return (CTFontRef)(cf_val);
   }
   return NULL;
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index f189637..6d1cd703 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -294,13 +294,6 @@
   task_runner_->PostNonNestableTask(from_here, task);
 }
 
-void MessageLoop::PostNonNestableDelayedTask(
-    const tracked_objects::Location& from_here,
-    const Closure& task,
-    TimeDelta delay) {
-  task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
-}
-
 void MessageLoop::Run() {
   DCHECK(pump_);
   RunLoop run_loop;
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index 24d5b46..667cf1e 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -203,10 +203,6 @@
   void PostNonNestableTask(const tracked_objects::Location& from_here,
                            const Closure& task);
 
-  void PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
-                                  const Closure& task,
-                                  TimeDelta delay);
-
   // A variant on PostTask that deletes the given object.  This is useful
   // if the object needs to live until the next run of the MessageLoop (for
   // example, deleting a RenderProcessHost from within an IPC callback is not
diff --git a/base/message_loop/message_loop_test.cc b/base/message_loop/message_loop_test.cc
index 0f1e924..dc14db2 100644
--- a/base/message_loop/message_loop_test.cc
+++ b/base/message_loop/message_loop_test.cc
@@ -697,8 +697,7 @@
 }
 
 // Tests that non nestable tasks don't run when there's code in the call stack.
-void RunTest_NonNestableInNestedLoop(MessagePumpFactory factory,
-                                     bool use_delayed) {
+void RunTest_NonNestableInNestedLoop(MessagePumpFactory factory) {
   std::unique_ptr<MessagePump> pump(factory());
   MessageLoop loop(std::move(pump));
 
@@ -707,16 +706,9 @@
   MessageLoop::current()->PostTask(
       FROM_HERE,
       Bind(&FuncThatPumps, &order, 1));
-  if (use_delayed) {
-    MessageLoop::current()->PostNonNestableDelayedTask(
-        FROM_HERE,
-        Bind(&OrderedFunc, &order, 2),
-        TimeDelta::FromMilliseconds(1));
-  } else {
-    MessageLoop::current()->PostNonNestableTask(
-        FROM_HERE,
-        Bind(&OrderedFunc, &order, 2));
-  }
+  MessageLoop::current()->PostNonNestableTask(
+      FROM_HERE,
+      Bind(&OrderedFunc, &order, 2));
   MessageLoop::current()->PostTask(FROM_HERE,
                                    Bind(&OrderedFunc, &order, 3));
   MessageLoop::current()->PostTask(
@@ -724,16 +716,9 @@
       Bind(&SleepFunc, &order, 4, TimeDelta::FromMilliseconds(50)));
   MessageLoop::current()->PostTask(FROM_HERE,
                                    Bind(&OrderedFunc, &order, 5));
-  if (use_delayed) {
-    MessageLoop::current()->PostNonNestableDelayedTask(
-        FROM_HERE,
-        Bind(&QuitFunc, &order, 6),
-        TimeDelta::FromMilliseconds(2));
-  } else {
-    MessageLoop::current()->PostNonNestableTask(
-        FROM_HERE,
-        Bind(&QuitFunc, &order, 6));
-  }
+  MessageLoop::current()->PostNonNestableTask(
+      FROM_HERE,
+      Bind(&QuitFunc, &order, 6));
 
   MessageLoop::current()->Run();
 
diff --git a/base/message_loop/message_loop_test.h b/base/message_loop/message_loop_test.h
index 200232e87..b7ae28e 100644
--- a/base/message_loop/message_loop_test.h
+++ b/base/message_loop/message_loop_test.h
@@ -33,8 +33,7 @@
 void RunTest_RecursiveDenial3(MessagePumpFactory factory);
 void RunTest_RecursiveSupport1(MessagePumpFactory factory);
 void RunTest_NonNestableWithNoNesting(MessagePumpFactory factory);
-void RunTest_NonNestableInNestedLoop(MessagePumpFactory factory,
-                                     bool use_delayed);
+void RunTest_NonNestableInNestedLoop(MessagePumpFactory factory);
 void RunTest_QuitNow(MessagePumpFactory factory);
 void RunTest_RunLoopQuitTop(MessagePumpFactory factory);
 void RunTest_RunLoopQuitNested(MessagePumpFactory factory);
@@ -97,11 +96,8 @@
   TEST(MessageLoopTestType##id, NonNestableWithNoNesting) { \
     base::test::RunTest_NonNestableWithNoNesting(factory); \
   } \
-  TEST(MessageLoopTestType##id, NonNestableInNestedLoop) { \
-    base::test::RunTest_NonNestableInNestedLoop(factory, false); \
-  } \
   TEST(MessageLoopTestType##id, NonNestableDelayedInNestedLoop) { \
-    base::test::RunTest_NonNestableInNestedLoop(factory, true); \
+    base::test::RunTest_NonNestableInNestedLoop(factory); \
   } \
   TEST(MessageLoopTestType##id, QuitNow) { \
     base::test::RunTest_QuitNow(factory); \
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
index f53a79c..c29aa6fe 100644
--- a/base/metrics/persistent_histogram_allocator.cc
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -270,6 +270,10 @@
   memory_allocator_->UpdateTrackingHistograms();
 }
 
+void PersistentHistogramAllocator::ClearLastCreatedReferenceForTesting() {
+  subtle::NoBarrier_Store(&last_created_, 0);
+}
+
 // static
 HistogramBase*
 PersistentHistogramAllocator::GetCreateHistogramResultHistogram() {
diff --git a/base/metrics/persistent_histogram_allocator.h b/base/metrics/persistent_histogram_allocator.h
index 7f46dc9..61fadaf 100644
--- a/base/metrics/persistent_histogram_allocator.h
+++ b/base/metrics/persistent_histogram_allocator.h
@@ -267,6 +267,10 @@
   void CreateTrackingHistograms(StringPiece name);
   void UpdateTrackingHistograms();
 
+  // Clears the internal |last_created_| reference so testing can validate
+  // operation without that optimization.
+  void ClearLastCreatedReferenceForTesting();
+
   // Histogram containing creation results. Visible for testing.
   static HistogramBase* GetCreateHistogramResultHistogram();
 
diff --git a/base/metrics/persistent_sample_map.cc b/base/metrics/persistent_sample_map.cc
index f61e53c..15f83cd 100644
--- a/base/metrics/persistent_sample_map.cc
+++ b/base/metrics/persistent_sample_map.cc
@@ -96,22 +96,11 @@
     uint64_t id,
     PersistentHistogramAllocator* allocator,
     Metadata* meta)
-    : PersistentSampleMap(id, allocator->UseSampleMapRecords(id, this), meta) {}
-
-PersistentSampleMap::PersistentSampleMap(
-    uint64_t id,
-    PersistentSparseHistogramDataManager* manager,
-    Metadata* meta)
-    : PersistentSampleMap(id, manager->UseSampleMapRecords(id, this), meta) {}
-
-PersistentSampleMap::PersistentSampleMap(
-    uint64_t id,
-    PersistentSampleMapRecords* records,
-    Metadata* meta)
-    : HistogramSamples(id, meta), records_(records) {}
+    : HistogramSamples(id, meta), allocator_(allocator) {}
 
 PersistentSampleMap::~PersistentSampleMap() {
-  records_->Release(this);
+  if (records_)
+    records_->Release(this);
 }
 
 void PersistentSampleMap::Accumulate(Sample value, Count count) {
@@ -219,7 +208,9 @@
   if (count_pointer)
     return count_pointer;
 
-  // Create a new record in persistent memory for the value.
+  // Create a new record in persistent memory for the value. |records_| will
+  // have been initialized by the GetSampleCountStorage() call above.
+  DCHECK(records_);
   PersistentMemoryAllocator::Reference ref = records_->CreateNew(value);
   if (!ref) {
     // If a new record could not be created then the underlying allocator is
@@ -245,13 +236,25 @@
   return count_pointer;
 }
 
+PersistentSampleMapRecords* PersistentSampleMap::GetRecords() {
+  // The |records_| pointer is lazily fetched from the |allocator_| only on
+  // first use. Sometimes duplicate histograms are created by race conditions
+  // and if both were to grab the records object, there would be a conflict.
+  // Use of a histogram, and thus a call to this method, won't occur until
+  // after the histogram has been de-dup'd.
+  if (!records_)
+    records_ = allocator_->UseSampleMapRecords(id(), this);
+  return records_;
+}
+
 Count* PersistentSampleMap::ImportSamples(Sample until_value,
                                           bool import_everything) {
   Count* found_count = nullptr;
   PersistentMemoryAllocator::Reference ref;
-  while ((ref = records_->GetNext()) != 0) {
+  PersistentSampleMapRecords* records = GetRecords();
+  while ((ref = records->GetNext()) != 0) {
     SampleRecord* record =
-        records_->GetAsObject<SampleRecord>(ref, kTypeIdSampleRecord);
+        records->GetAsObject<SampleRecord>(ref, kTypeIdSampleRecord);
     if (!record)
       continue;
 
diff --git a/base/metrics/persistent_sample_map.h b/base/metrics/persistent_sample_map.h
index 2ef70da..3c175db 100644
--- a/base/metrics/persistent_sample_map.h
+++ b/base/metrics/persistent_sample_map.h
@@ -30,19 +30,11 @@
 // structures. Changes here likely need to be duplicated there.
 class BASE_EXPORT PersistentSampleMap : public HistogramSamples {
  public:
-  // Constructs a persistent sample map using any of a variety of persistent
-  // data sources. Really, the first two are just convenience methods for
-  // getting at the PersistentSampleMapRecords object for the specified |id|.
-  // The source objects must live longer than this object.
+  // Constructs a persistent sample map using a PersistentHistogramAllocator
+  // as the data source for persistent records.
   PersistentSampleMap(uint64_t id,
                       PersistentHistogramAllocator* allocator,
                       Metadata* meta);
-  PersistentSampleMap(uint64_t id,
-                      PersistentSparseHistogramDataManager* manager,
-                      Metadata* meta);
-  PersistentSampleMap(uint64_t id,
-                      PersistentSampleMapRecords* records,
-                      Metadata* meta);
 
   ~PersistentSampleMap() override;
 
@@ -81,6 +73,10 @@
       HistogramBase::Sample value);
 
  private:
+  // Gets the object that manages persistent records. This returns the
+  // |records_| member after first initializing it if necessary.
+  PersistentSampleMapRecords* GetRecords();
+
   // Imports samples from persistent memory by iterating over all sample
   // records found therein, adding them to the sample_counts_ map. If a
   // count for the sample |until_value| is found, stop the import and return
@@ -96,10 +92,15 @@
   // underlying allocator.
   std::map<HistogramBase::Sample, HistogramBase::Count*> sample_counts_;
 
-  // The object that manages records inside persistent memory. This is owned
-  // externally (typically by a PersistentHistogramAllocator) and is expected
-  // to live beyond the life of this object.
-  PersistentSampleMapRecords* records_;
+  // The allocator that manages histograms inside persistent memory. This is
+  // owned externally and is expected to live beyond the life of this object.
+  PersistentHistogramAllocator* allocator_;
+
+  // The object that manages sample records inside persistent memory. This is
+  // owned by the |allocator_| object (above) and so, like it, is expected to
+  // live beyond the life of this object. This value is lazily-initialized on
+  // first use via the GetRecords() accessor method.
+  PersistentSampleMapRecords* records_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(PersistentSampleMap);
 };
diff --git a/base/metrics/persistent_sample_map_unittest.cc b/base/metrics/persistent_sample_map_unittest.cc
index ed06337d..beb72e5 100644
--- a/base/metrics/persistent_sample_map_unittest.cc
+++ b/base/metrics/persistent_sample_map_unittest.cc
@@ -6,18 +6,32 @@
 
 #include <memory>
 
+#include "base/memory/ptr_util.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
 namespace {
 
-TEST(PersistentSampleMapTest, AccumulateTest) {
-  LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");  // 64 KiB
+std::unique_ptr<PersistentHistogramAllocator> CreateHistogramAllocator(
+    size_t bytes) {
+  return WrapUnique(new PersistentHistogramAllocator(
+      WrapUnique(new LocalPersistentMemoryAllocator(bytes, 0, ""))));
+}
 
+std::unique_ptr<PersistentHistogramAllocator> DuplicateHistogramAllocator(
+    PersistentHistogramAllocator* original) {
+  return WrapUnique(
+      new PersistentHistogramAllocator(WrapUnique(new PersistentMemoryAllocator(
+          const_cast<void*>(original->data()), original->length(), 0,
+          original->Id(), original->Name(), false))));
+}
+
+TEST(PersistentSampleMapTest, AccumulateTest) {
+  std::unique_ptr<PersistentHistogramAllocator> allocator =
+      CreateHistogramAllocator(64 << 10);  // 64 KiB
   HistogramSamples::Metadata meta;
-  PersistentSparseHistogramDataManager manager(&allocator);
-  PersistentSampleMap samples(1, &manager, &meta);
+  PersistentSampleMap samples(1, allocator.get(), &meta);
 
   samples.Accumulate(1, 100);
   samples.Accumulate(2, 200);
@@ -31,11 +45,10 @@
 }
 
 TEST(PersistentSampleMapTest, Accumulate_LargeValuesDontOverflow) {
-  LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");  // 64 KiB
-
+  std::unique_ptr<PersistentHistogramAllocator> allocator =
+      CreateHistogramAllocator(64 << 10);  // 64 KiB
   HistogramSamples::Metadata meta;
-  PersistentSparseHistogramDataManager manager(&allocator);
-  PersistentSampleMap samples(1, &manager, &meta);
+  PersistentSampleMap samples(1, allocator.get(), &meta);
 
   samples.Accumulate(250000000, 100);
   samples.Accumulate(500000000, 200);
@@ -49,18 +62,18 @@
 }
 
 TEST(PersistentSampleMapTest, AddSubtractTest) {
-  LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");  // 64 KiB
-
+  std::unique_ptr<PersistentHistogramAllocator> allocator1 =
+      CreateHistogramAllocator(64 << 10);  // 64 KiB
   HistogramSamples::Metadata meta1;
-  PersistentSparseHistogramDataManager manager1(&allocator);
-  PersistentSampleMap samples1(1, &manager1, &meta1);
+  PersistentSampleMap samples1(1, allocator1.get(), &meta1);
   samples1.Accumulate(1, 100);
   samples1.Accumulate(2, 100);
   samples1.Accumulate(3, 100);
 
+  std::unique_ptr<PersistentHistogramAllocator> allocator2 =
+      DuplicateHistogramAllocator(allocator1.get());
   HistogramSamples::Metadata meta2;
-  PersistentSparseHistogramDataManager manager2(&allocator);
-  PersistentSampleMap samples2(2, &manager2, &meta2);
+  PersistentSampleMap samples2(2, allocator2.get(), &meta2);
   samples2.Accumulate(1, 200);
   samples2.Accumulate(2, 200);
   samples2.Accumulate(4, 200);
@@ -85,11 +98,10 @@
 }
 
 TEST(PersistentSampleMapTest, PersistenceTest) {
-  LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");  // 64 KiB
-
+  std::unique_ptr<PersistentHistogramAllocator> allocator1 =
+      CreateHistogramAllocator(64 << 10);  // 64 KiB
   HistogramSamples::Metadata meta12;
-  PersistentSparseHistogramDataManager manager1(&allocator);
-  PersistentSampleMap samples1(12, &manager1, &meta12);
+  PersistentSampleMap samples1(12, allocator1.get(), &meta12);
   samples1.Accumulate(1, 100);
   samples1.Accumulate(2, 200);
   samples1.Accumulate(1, -200);
@@ -101,8 +113,9 @@
   EXPECT_EQ(101, samples1.TotalCount());
   EXPECT_EQ(samples1.redundant_count(), samples1.TotalCount());
 
-  PersistentSparseHistogramDataManager manager2(&allocator);
-  PersistentSampleMap samples2(12, &manager2, &meta12);
+  std::unique_ptr<PersistentHistogramAllocator> allocator2 =
+      DuplicateHistogramAllocator(allocator1.get());
+  PersistentSampleMap samples2(12, allocator2.get(), &meta12);
   EXPECT_EQ(samples1.id(), samples2.id());
   EXPECT_EQ(samples1.sum(), samples2.sum());
   EXPECT_EQ(samples1.redundant_count(), samples2.redundant_count());
@@ -138,11 +151,10 @@
 }
 
 TEST(PersistentSampleMapIteratorTest, IterateTest) {
-  LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");  // 64 KiB
-
+  std::unique_ptr<PersistentHistogramAllocator> allocator =
+      CreateHistogramAllocator(64 << 10);  // 64 KiB
   HistogramSamples::Metadata meta;
-  PersistentSparseHistogramDataManager manager(&allocator);
-  PersistentSampleMap samples(1, &manager, &meta);
+  PersistentSampleMap samples(1, allocator.get(), &meta);
   samples.Accumulate(1, 100);
   samples.Accumulate(2, 200);
   samples.Accumulate(4, -300);
@@ -177,20 +189,20 @@
 }
 
 TEST(PersistentSampleMapIteratorTest, SkipEmptyRanges) {
-  LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");  // 64 KiB
-
+  std::unique_ptr<PersistentHistogramAllocator> allocator1 =
+      CreateHistogramAllocator(64 << 10);  // 64 KiB
   HistogramSamples::Metadata meta1;
-  PersistentSparseHistogramDataManager manager1(&allocator);
-  PersistentSampleMap samples1(1, &manager1, &meta1);
+  PersistentSampleMap samples1(1, allocator1.get(), &meta1);
   samples1.Accumulate(5, 1);
   samples1.Accumulate(10, 2);
   samples1.Accumulate(15, 3);
   samples1.Accumulate(20, 4);
   samples1.Accumulate(25, 5);
 
+  std::unique_ptr<PersistentHistogramAllocator> allocator2 =
+      DuplicateHistogramAllocator(allocator1.get());
   HistogramSamples::Metadata meta2;
-  PersistentSparseHistogramDataManager manager2(&allocator);
-  PersistentSampleMap samples2(2, &manager2, &meta2);
+  PersistentSampleMap samples2(2, allocator2.get(), &meta2);
   samples2.Accumulate(5, 1);
   samples2.Accumulate(20, 4);
   samples2.Accumulate(25, 5);
@@ -224,11 +236,10 @@
 // Only run this test on builds that support catching a DCHECK crash.
 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
 TEST(PersistentSampleMapIteratorDeathTest, IterateDoneTest) {
-  LocalPersistentMemoryAllocator allocator(64 << 10, 0, "");  // 64 KiB
-
+  std::unique_ptr<PersistentHistogramAllocator> allocator =
+      CreateHistogramAllocator(64 << 10);  // 64 KiB
   HistogramSamples::Metadata meta;
-  PersistentSparseHistogramDataManager manager(&allocator);
-  PersistentSampleMap samples(1, &manager, &meta);
+  PersistentSampleMap samples(1, allocator.get(), &meta);
 
   std::unique_ptr<SampleCountIterator> it = samples.Iterator();
 
diff --git a/base/metrics/sparse_histogram_unittest.cc b/base/metrics/sparse_histogram_unittest.cc
index 0946a67..fbff977 100644
--- a/base/metrics/sparse_histogram_unittest.cc
+++ b/base/metrics/sparse_histogram_unittest.cc
@@ -217,6 +217,55 @@
   EXPECT_FALSE(iter.SkipBytes(1));
 }
 
+// Ensure that race conditions that cause multiple, identical sparse histograms
+// to be created will safely resolve to a single one.
+TEST_P(SparseHistogramTest, DuplicationSafety) {
+  const char histogram_name[] = "Duplicated";
+  size_t histogram_count = StatisticsRecorder::GetHistogramCount();
+
+  // Create a histogram that we will later duplicate.
+  HistogramBase* original =
+      SparseHistogram::FactoryGet(histogram_name, HistogramBase::kNoFlags);
+  ++histogram_count;
+  DCHECK_EQ(histogram_count, StatisticsRecorder::GetHistogramCount());
+  original->Add(1);
+
+  // Create a duplicate. This has to happen differently depending on where the
+  // memory is taken from.
+  if (use_persistent_histogram_allocator_) {
+    // To allocate from persistent memory, clear the last_created reference in
+    // the GlobalHistogramAllocator. This will cause an Import to recreate
+    // the just-created histogram which will then be released as a duplicate.
+    GlobalHistogramAllocator::Get()->ClearLastCreatedReferenceForTesting();
+    // Creating a different histogram will first do an Import to ensure it
+    // hasn't been created elsewhere, triggering the duplication and release.
+    SparseHistogram::FactoryGet("something.new", HistogramBase::kNoFlags);
+    ++histogram_count;
+  } else {
+    // To allocate from the heap, just call the (private) constructor directly.
+    // Delete it immediately like would have happened within FactoryGet();
+    std::unique_ptr<SparseHistogram> something =
+        NewSparseHistogram(histogram_name);
+    DCHECK_NE(original, something.get());
+  }
+  DCHECK_EQ(histogram_count, StatisticsRecorder::GetHistogramCount());
+
+  // Re-creating the histogram via FactoryGet() will return the same one.
+  HistogramBase* duplicate =
+      SparseHistogram::FactoryGet(histogram_name, HistogramBase::kNoFlags);
+  DCHECK_EQ(original, duplicate);
+  DCHECK_EQ(histogram_count, StatisticsRecorder::GetHistogramCount());
+  duplicate->Add(2);
+
+  // Ensure that original histograms are still cross-functional.
+  original->Add(2);
+  duplicate->Add(1);
+  std::unique_ptr<HistogramSamples> snapshot_orig = original->SnapshotSamples();
+  std::unique_ptr<HistogramSamples> snapshot_dup = duplicate->SnapshotSamples();
+  DCHECK_EQ(2, snapshot_orig->GetCount(2));
+  DCHECK_EQ(2, snapshot_dup->GetCount(1));
+}
+
 TEST_P(SparseHistogramTest, FactoryTime) {
   const int kTestCreateCount = 1 << 10;  // Must be power-of-2.
   const int kTestLookupCount = 100000;
diff --git a/base/sys_info.cc b/base/sys_info.cc
index cebb3630..5aac9b7 100644
--- a/base/sys_info.cc
+++ b/base/sys_info.cc
@@ -28,7 +28,7 @@
     return false;
 
   int ram_size_mb = SysInfo::AmountOfPhysicalMemoryMB();
-  return (ram_size_mb > 0 && ram_size_mb < kLowMemoryDeviceThresholdMB);
+  return (ram_size_mb > 0 && ram_size_mb <= kLowMemoryDeviceThresholdMB);
 }
 
 static LazyInstance<
diff --git a/base/task_scheduler/priority_queue.cc b/base/task_scheduler/priority_queue.cc
index 05a90b22..8fec497 100644
--- a/base/task_scheduler/priority_queue.cc
+++ b/base/task_scheduler/priority_queue.cc
@@ -12,15 +12,50 @@
 namespace base {
 namespace internal {
 
-PriorityQueue::SequenceAndSortKey::SequenceAndSortKey()
-    : sort_key(TaskPriority::LOWEST, TimeTicks()) {}
+// A class combining a Sequence and the SequenceSortKey that determines its
+// position in a PriorityQueue. Instances are only mutable via take_sequence()
+// which can only be called once and renders its instance invalid after the
+// call.
+class PriorityQueue::SequenceAndSortKey {
+ public:
+  SequenceAndSortKey(scoped_refptr<Sequence>&& sequence,
+                     const SequenceSortKey& sort_key)
+      : sequence_(sequence), sort_key_(sort_key) {
+    DCHECK(sequence_);
+  }
 
-PriorityQueue::SequenceAndSortKey::SequenceAndSortKey(
-    scoped_refptr<Sequence> sequence,
-    const SequenceSortKey& sort_key)
-    : sequence(std::move(sequence)), sort_key(sort_key) {}
+  // Note: while |sequence_| should always be non-null post-move (i.e. we
+  // shouldn't be moving an invalid SequenceAndSortKey around), there can't be a
+  // DCHECK(sequence_) on moves as the Windows STL moves elements on pop instead
+  // of overwriting them: resulting in the move of a SequenceAndSortKey with a
+  // null |sequence_| in Transaction::Pop()'s implementation.
+  SequenceAndSortKey(SequenceAndSortKey&& other) = default;
+  SequenceAndSortKey& operator=(SequenceAndSortKey&& other) = default;
 
-PriorityQueue::SequenceAndSortKey::~SequenceAndSortKey() = default;
+  // Extracts |sequence_| from this object. This object is invalid after this
+  // call.
+  scoped_refptr<Sequence> take_sequence() {
+    DCHECK(sequence_);
+    return std::move(sequence_);
+  }
+
+  // Compares this SequenceAndSortKey to |other| based on their respective
+  // |sort_key_|.
+  bool operator<(const SequenceAndSortKey& other) const {
+    return sort_key_ < other.sort_key_;
+  }
+  bool operator>(const SequenceAndSortKey& other) const {
+    return other < *this;
+  }
+
+  const SequenceSortKey& sort_key() const { return sort_key_; }
+
+ private:
+  scoped_refptr<Sequence> sequence_;
+  SequenceSortKey sort_key_;
+
+  DISALLOW_COPY_AND_ASSIGN(SequenceAndSortKey);
+};
 
 PriorityQueue::Transaction::Transaction(PriorityQueue* outer_queue)
     : auto_lock_(outer_queue->container_lock_), outer_queue_(outer_queue) {
@@ -32,29 +67,36 @@
 }
 
 void PriorityQueue::Transaction::Push(
-    std::unique_ptr<SequenceAndSortKey> sequence_and_sort_key) {
+    scoped_refptr<Sequence> sequence,
+    const SequenceSortKey& sequence_sort_key) {
   DCHECK(CalledOnValidThread());
-  DCHECK(!sequence_and_sort_key->is_null());
-
-  outer_queue_->container_.push(std::move(sequence_and_sort_key));
+  outer_queue_->container_.emplace(std::move(sequence), sequence_sort_key);
 }
 
-const PriorityQueue::SequenceAndSortKey& PriorityQueue::Transaction::Peek()
-    const {
+const SequenceSortKey& PriorityQueue::Transaction::PeekSortKey() const {
   DCHECK(CalledOnValidThread());
-
-  // TODO(fdoray): Add an IsEmpty() method to Transaction and require Peek() to
-  // be called on a non-empty PriorityQueue only.
-  if (outer_queue_->container_.empty())
-    return outer_queue_->empty_sequence_and_sort_key_;
-
-  return *outer_queue_->container_.top();
+  DCHECK(!IsEmpty());
+  return outer_queue_->container_.top().sort_key();
 }
 
-void PriorityQueue::Transaction::Pop() {
+scoped_refptr<Sequence> PriorityQueue::Transaction::PopSequence() {
   DCHECK(CalledOnValidThread());
-  DCHECK(!outer_queue_->container_.empty());
+  DCHECK(!IsEmpty());
+
+  // The const_cast on top() is okay since the SequenceAndSortKey is
+  // transactionally being popped from |container_| right after and taking its
+  // Sequence does not alter its sort order (a requirement for the Windows STL's
+  // consistency debug-checks for std::priority_queue::top()).
+  scoped_refptr<Sequence> sequence =
+      const_cast<PriorityQueue::SequenceAndSortKey&>(
+          outer_queue_->container_.top())
+          .take_sequence();
   outer_queue_->container_.pop();
+  return sequence;
+}
+
+bool PriorityQueue::Transaction::IsEmpty() const {
+  return outer_queue_->container_.empty();
 }
 
 PriorityQueue::PriorityQueue() = default;
diff --git a/base/task_scheduler/priority_queue.h b/base/task_scheduler/priority_queue.h
index 8e0a532..ac1dbde 100644
--- a/base/task_scheduler/priority_queue.h
+++ b/base/task_scheduler/priority_queue.h
@@ -23,27 +23,6 @@
 // A PriorityQueue holds Sequences of Tasks. This class is thread-safe.
 class BASE_EXPORT PriorityQueue {
  public:
-  // An immutable struct combining a Sequence and the sort key that determines
-  // its position in a PriorityQueue.
-  struct BASE_EXPORT SequenceAndSortKey {
-    // Constructs a null SequenceAndSortKey.
-    SequenceAndSortKey();
-
-    // Constructs a SequenceAndSortKey with the given |sequence| and |sort_key|.
-    SequenceAndSortKey(scoped_refptr<Sequence> sequence,
-                       const SequenceSortKey& sort_key);
-    ~SequenceAndSortKey();
-
-    // Returns true if this is a null SequenceAndSortKey.
-    bool is_null() const { return !sequence; }
-
-    const scoped_refptr<Sequence> sequence;
-    const SequenceSortKey sort_key;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(SequenceAndSortKey);
-  };
-
   // A Transaction can perform multiple operations atomically on a
   // PriorityQueue. While a Transaction is alive, it is guaranteed that nothing
   // else will access the PriorityQueue.
@@ -57,17 +36,25 @@
    public:
     ~Transaction();
 
-    // Inserts |sequence_and_sort_key| in the PriorityQueue.
-    void Push(std::unique_ptr<SequenceAndSortKey> sequence_and_sort_key);
+    // Inserts |sequence| in the PriorityQueue with |sequence_sort_key|.
+    // Note: |sequence_sort_key| is required as a parameter instead of being
+    // extracted from |sequence| in Push() to avoid this Transaction having a
+    // lock interdependency with |sequence|.
+    void Push(scoped_refptr<Sequence> sequence,
+              const SequenceSortKey& sequence_sort_key);
 
-    // Returns the SequenceAndSortKey with the highest priority or a null
-    // SequenceAndSortKey if the PriorityQueue is empty. The reference becomes
-    // invalid the next time that a Sequence is popped from the PriorityQueue.
-    const SequenceAndSortKey& Peek() const;
+    // Returns a reference to the SequenceSortKey representing the priority of
+    // the highest pending task in this PriorityQueue. The reference becomes
+    // invalid the next time that this PriorityQueue is modified.
+    // Cannot be called on an empty PriorityQueue.
+    const SequenceSortKey& PeekSortKey() const;
 
-    // Removes the SequenceAndSortKey with the highest priority from the
-    // PriorityQueue. Cannot be called on an empty PriorityQueue.
-    void Pop();
+    // Removes and returns the highest priority Sequence in this PriorityQueue.
+    // Cannot be called on an empty PriorityQueue.
+    scoped_refptr<Sequence> PopSequence();
+
+    // Returns true if the PriorityQueue is empty.
+    bool IsEmpty() const;
 
    private:
     friend class PriorityQueue;
@@ -100,26 +87,17 @@
   const SchedulerLock* container_lock() const { return &container_lock_; }
 
  private:
-  struct SequenceAndSortKeyComparator {
-    bool operator()(const std::unique_ptr<SequenceAndSortKey>& left,
-                    const std::unique_ptr<SequenceAndSortKey>& right) const {
-      return left->sort_key < right->sort_key;
-    }
-  };
-  using ContainerType =
-      std::priority_queue<std::unique_ptr<SequenceAndSortKey>,
-                          std::vector<std::unique_ptr<SequenceAndSortKey>>,
-                          SequenceAndSortKeyComparator>;
+  // A class combining a Sequence and the SequenceSortKey that determines its
+  // position in a PriorityQueue.
+  class SequenceAndSortKey;
+
+  using ContainerType = std::priority_queue<SequenceAndSortKey>;
 
   // Synchronizes access to |container_|.
   SchedulerLock container_lock_;
 
   ContainerType container_;
 
-  // A null SequenceAndSortKey returned by Peek() when the PriorityQueue is
-  // empty.
-  const SequenceAndSortKey empty_sequence_and_sort_key_;
-
   DISALLOW_COPY_AND_ASSIGN(PriorityQueue);
 };
 
diff --git a/base/task_scheduler/priority_queue_unittest.cc b/base/task_scheduler/priority_queue_unittest.cc
index 84195cd..cf8d099 100644
--- a/base/task_scheduler/priority_queue_unittest.cc
+++ b/base/task_scheduler/priority_queue_unittest.cc
@@ -52,21 +52,6 @@
   DISALLOW_COPY_AND_ASSIGN(ThreadBeginningTransaction);
 };
 
-void ExpectSequenceAndSortKeyEq(
-    const PriorityQueue::SequenceAndSortKey& expected,
-    const PriorityQueue::SequenceAndSortKey& actual) {
-  EXPECT_EQ(expected.sequence, actual.sequence);
-  EXPECT_EQ(expected.sort_key.priority, actual.sort_key.priority);
-  EXPECT_EQ(expected.sort_key.next_task_sequenced_time,
-            actual.sort_key.next_task_sequenced_time);
-}
-
-#define EXPECT_SEQUENCE_AND_SORT_KEY_EQ(expected, actual) \
-  do {                                                    \
-    SCOPED_TRACE("");                                     \
-    ExpectSequenceAndSortKeyEq(expected, actual);         \
-  } while (false)
-
 }  // namespace
 
 TEST(TaskSchedulerPriorityQueueTest, PushPopPeek) {
@@ -98,66 +83,46 @@
   // Create a PriorityQueue and a Transaction.
   PriorityQueue pq;
   auto transaction(pq.BeginTransaction());
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(),
-                                  transaction->Peek());
+  EXPECT_TRUE(transaction->IsEmpty());
 
   // Push |sequence_a| in the PriorityQueue. It becomes the sequence with the
   // highest priority.
-  transaction->Push(WrapUnique(
-      new PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a)));
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
-      PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a),
-      transaction->Peek());
+  transaction->Push(sequence_a, sort_key_a);
+  EXPECT_EQ(sort_key_a, transaction->PeekSortKey());
 
   // Push |sequence_b| in the PriorityQueue. It becomes the sequence with the
   // highest priority.
-  transaction->Push(WrapUnique(
-      new PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b)));
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
-      PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b),
-      transaction->Peek());
+  transaction->Push(sequence_b, sort_key_b);
+  EXPECT_EQ(sort_key_b, transaction->PeekSortKey());
 
   // Push |sequence_c| in the PriorityQueue. |sequence_b| is still the sequence
   // with the highest priority.
-  transaction->Push(WrapUnique(
-      new PriorityQueue::SequenceAndSortKey(sequence_c, sort_key_c)));
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
-      PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b),
-      transaction->Peek());
+  transaction->Push(sequence_c, sort_key_c);
+  EXPECT_EQ(sort_key_b, transaction->PeekSortKey());
 
   // Push |sequence_d| in the PriorityQueue. |sequence_b| is still the sequence
   // with the highest priority.
-  transaction->Push(WrapUnique(
-      new PriorityQueue::SequenceAndSortKey(sequence_d, sort_key_d)));
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
-      PriorityQueue::SequenceAndSortKey(sequence_b, sort_key_b),
-      transaction->Peek());
+  transaction->Push(sequence_d, sort_key_d);
+  EXPECT_EQ(sort_key_b, transaction->PeekSortKey());
 
   // Pop |sequence_b| from the PriorityQueue. |sequence_c| becomes the sequence
   // with the highest priority.
-  transaction->Pop();
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
-      PriorityQueue::SequenceAndSortKey(sequence_c, sort_key_c),
-      transaction->Peek());
+  EXPECT_EQ(sequence_b, transaction->PopSequence());
+  EXPECT_EQ(sort_key_c, transaction->PeekSortKey());
 
   // Pop |sequence_c| from the PriorityQueue. |sequence_a| becomes the sequence
   // with the highest priority.
-  transaction->Pop();
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
-      PriorityQueue::SequenceAndSortKey(sequence_a, sort_key_a),
-      transaction->Peek());
+  EXPECT_EQ(sequence_c, transaction->PopSequence());
+  EXPECT_EQ(sort_key_a, transaction->PeekSortKey());
 
   // Pop |sequence_a| from the PriorityQueue. |sequence_d| becomes the sequence
   // with the highest priority.
-  transaction->Pop();
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(
-      PriorityQueue::SequenceAndSortKey(sequence_d, sort_key_d),
-      transaction->Peek());
+  EXPECT_EQ(sequence_a, transaction->PopSequence());
+  EXPECT_EQ(sort_key_d, transaction->PeekSortKey());
 
   // Pop |sequence_d| from the PriorityQueue. It is now empty.
-  transaction->Pop();
-  EXPECT_SEQUENCE_AND_SORT_KEY_EQ(PriorityQueue::SequenceAndSortKey(),
-                                  transaction->Peek());
+  EXPECT_EQ(sequence_d, transaction->PopSequence());
+  EXPECT_TRUE(transaction->IsEmpty());
 }
 
 // Check that creating Transactions on the same thread for 2 unrelated
@@ -215,14 +180,5 @@
   thread_beginning_transaction.Join();
 }
 
-TEST(TaskSchedulerPriorityQueueTest, SequenceAndSortKeyIsNull) {
-  EXPECT_TRUE(PriorityQueue::SequenceAndSortKey().is_null());
-
-  const PriorityQueue::SequenceAndSortKey non_null_sequence_and_sort_key(
-      make_scoped_refptr(new Sequence),
-      SequenceSortKey(TaskPriority::USER_VISIBLE, TimeTicks()));
-  EXPECT_FALSE(non_null_sequence_and_sort_key.is_null());
-}
-
 }  // namespace internal
 }  // namespace base
diff --git a/base/task_scheduler/scheduler_thread_pool.h b/base/task_scheduler/scheduler_thread_pool.h
index 9793162..774b111 100644
--- a/base/task_scheduler/scheduler_thread_pool.h
+++ b/base/task_scheduler/scheduler_thread_pool.h
@@ -18,7 +18,7 @@
 namespace internal {
 
 class SchedulerWorkerThread;
-struct SequenceSortKey;
+class SequenceSortKey;
 
 // Interface for a thread pool.
 class BASE_EXPORT SchedulerThreadPool {
@@ -26,34 +26,35 @@
   virtual ~SchedulerThreadPool() = default;
 
   // Returns a TaskRunner whose PostTask invocations will result in scheduling
-  // Tasks with |traits| and |execution_mode| in this thread pool.
+  // Tasks with |traits| and |execution_mode| in this SchedulerThreadPool.
   virtual scoped_refptr<TaskRunner> CreateTaskRunnerWithTraits(
       const TaskTraits& traits,
       ExecutionMode execution_mode) = 0;
 
-  // Inserts |sequence| into this thread pool's shared priority queue with
-  // |sequence_sort_key|. Must only be called from a worker thread to put
-  // |sequence| back into a PriorityQueue after running a Task from it. The
-  // worker thread doesn't have to belong to this thread pool.
+  // Inserts |sequence| with |sequence_sort_key| into a queue of Sequences that
+  // can be processed by any worker thread owned by this SchedulerThreadPool.
+  // Must only be used to put |sequence| back into a queue after running a Task
+  // from it. The thread that calls this doesn't have to belong to this
+  // SchedulerThreadPool.
   virtual void ReEnqueueSequence(scoped_refptr<Sequence> sequence,
                                  const SequenceSortKey& sequence_sort_key) = 0;
 
-  // Posts |task| to be executed as part of |sequence|. If |worker_thread| is
-  // non-null, |task| will be scheduled to run on it specifically (note:
-  // |worker_thread| must be owned by this SchedulerThreadPool); otherwise,
-  // |task| will be added to the pending shared work. Returns true if |task| is
-  // posted.
+  // Posts |task| to be executed by this SchedulerThreadPool as part of
+  // |sequence|. If |worker_thread| is non-null, |task| will be scheduled to run
+  // on it specifically (note: |worker_thread| must be owned by this
+  // SchedulerThreadPool); otherwise, |task| will be added to the pending shared
+  // work. |task| won't be executed before its delayed run time, if any. Returns
+  // true if |task| is posted.
   virtual bool PostTaskWithSequence(std::unique_ptr<Task> task,
                                     scoped_refptr<Sequence> sequence,
                                     SchedulerWorkerThread* worker_thread) = 0;
 
-  // Posts |task| to be executed by this thread pool as part of |sequence|. If
-  // |worker_thread| is non-null, |task| will be scheduled to run on it
-  // specifically (note: |worker_thread| must be owned by this
+  // Posts |task| to be executed by this SchedulerThreadPool as part of
+  // |sequence|. If |worker_thread| is non-null, |task| will be scheduled to run
+  // on it specifically (note: |worker_thread| must be owned by this
   // SchedulerThreadPool); otherwise, |task| will be added to the pending shared
-  // work. The scheduler's TaskTracker must have allowed |task| to be posted
-  // before this is called. This must only be called after |task|'s delayed run
-  // time.
+  // work. This must only be called after |task| has gone through
+  // PostTaskWithSequence() and after |task|'s delayed run time.
   virtual void PostTaskWithSequenceNow(
       std::unique_ptr<Task> task,
       scoped_refptr<Sequence> sequence,
diff --git a/base/task_scheduler/scheduler_thread_pool_impl.cc b/base/task_scheduler/scheduler_thread_pool_impl.cc
index b64405d..ab9bbf6 100644
--- a/base/task_scheduler/scheduler_thread_pool_impl.cc
+++ b/base/task_scheduler/scheduler_thread_pool_impl.cc
@@ -16,6 +16,7 @@
 #include "base/task_scheduler/delayed_task_manager.h"
 #include "base/task_scheduler/task_tracker.h"
 #include "base/threading/thread_local.h"
+#include "base/threading/thread_restrictions.h"
 
 namespace base {
 namespace internal {
@@ -216,11 +217,13 @@
 std::unique_ptr<SchedulerThreadPoolImpl> SchedulerThreadPoolImpl::Create(
     ThreadPriority thread_priority,
     size_t max_threads,
+    IORestriction io_restriction,
     const ReEnqueueSequenceCallback& re_enqueue_sequence_callback,
     TaskTracker* task_tracker,
     DelayedTaskManager* delayed_task_manager) {
   std::unique_ptr<SchedulerThreadPoolImpl> thread_pool(
-      new SchedulerThreadPoolImpl(task_tracker, delayed_task_manager));
+      new SchedulerThreadPoolImpl(io_restriction, task_tracker,
+                                  delayed_task_manager));
   if (thread_pool->Initialize(thread_priority, max_threads,
                               re_enqueue_sequence_callback)) {
     return thread_pool;
@@ -276,9 +279,8 @@
 void SchedulerThreadPoolImpl::ReEnqueueSequence(
     scoped_refptr<Sequence> sequence,
     const SequenceSortKey& sequence_sort_key) {
-  shared_priority_queue_.BeginTransaction()->Push(
-      WrapUnique(new PriorityQueue::SequenceAndSortKey(std::move(sequence),
-                                                       sequence_sort_key)));
+  shared_priority_queue_.BeginTransaction()->Push(std::move(sequence),
+                                                  sequence_sort_key);
 
   // The thread calling this method just ran a Task from |sequence| and will
   // soon try to get another Sequence from which to run a Task. If the thread
@@ -347,9 +349,8 @@
     // - A worker thread is running a Task from |sequence|. It will insert
     //   |sequence| in a PriorityQueue once it's done running the Task.
     const auto sequence_sort_key = sequence->GetSortKey();
-    priority_queue->BeginTransaction()->Push(
-        WrapUnique(new PriorityQueue::SequenceAndSortKey(std::move(sequence),
-                                                         sequence_sort_key)));
+    priority_queue->BeginTransaction()->Push(std::move(sequence),
+                                             sequence_sort_key);
 
     // Wake up a worker thread to process |sequence|.
     if (worker_thread)
@@ -384,6 +385,9 @@
   DCHECK(!tls_current_thread_pool.Get().Get());
   tls_current_worker_thread.Get().Set(worker_thread);
   tls_current_thread_pool.Get().Set(outer_);
+
+  ThreadRestrictions::SetIOAllowed(outer_->io_restriction_ ==
+                                   IORestriction::ALLOWED);
 }
 
 scoped_refptr<Sequence>
@@ -395,15 +399,11 @@
   {
     std::unique_ptr<PriorityQueue::Transaction> shared_transaction(
         outer_->shared_priority_queue_.BeginTransaction());
-    const auto& shared_sequence_and_sort_key = shared_transaction->Peek();
-
     std::unique_ptr<PriorityQueue::Transaction> single_threaded_transaction(
         single_threaded_priority_queue_.BeginTransaction());
-    const auto& single_threaded_sequence_and_sort_key =
-        single_threaded_transaction->Peek();
 
-    if (shared_sequence_and_sort_key.is_null() &&
-        single_threaded_sequence_and_sort_key.is_null()) {
+    if (shared_transaction->IsEmpty() &&
+        single_threaded_transaction->IsEmpty()) {
       single_threaded_transaction.reset();
 
       // |shared_transaction| is kept alive while |worker_thread| is added to
@@ -425,20 +425,18 @@
     // True if both PriorityQueues have Sequences and the Sequence at the top of
     // the shared PriorityQueue is more important.
     const bool shared_sequence_is_more_important =
-        !shared_sequence_and_sort_key.is_null() &&
-        !single_threaded_sequence_and_sort_key.is_null() &&
-        shared_sequence_and_sort_key.sort_key >
-            single_threaded_sequence_and_sort_key.sort_key;
+        !shared_transaction->IsEmpty() &&
+        !single_threaded_transaction->IsEmpty() &&
+        shared_transaction->PeekSortKey() >
+            single_threaded_transaction->PeekSortKey();
 
-    if (single_threaded_sequence_and_sort_key.is_null() ||
+    if (single_threaded_transaction->IsEmpty() ||
         shared_sequence_is_more_important) {
-      sequence = shared_sequence_and_sort_key.sequence;
-      shared_transaction->Pop();
+      sequence = shared_transaction->PopSequence();
       last_sequence_is_single_threaded_ = false;
     } else {
-      DCHECK(!single_threaded_sequence_and_sort_key.is_null());
-      sequence = single_threaded_sequence_and_sort_key.sequence;
-      single_threaded_transaction->Pop();
+      DCHECK(!single_threaded_transaction->IsEmpty());
+      sequence = single_threaded_transaction->PopSequence();
       last_sequence_is_single_threaded_ = true;
     }
   }
@@ -455,8 +453,7 @@
     // PriorityQueue from which it was extracted.
     const SequenceSortKey sequence_sort_key = sequence->GetSortKey();
     single_threaded_priority_queue_.BeginTransaction()->Push(
-        WrapUnique(new PriorityQueue::SequenceAndSortKey(std::move(sequence),
-                                                         sequence_sort_key)));
+        std::move(sequence), sequence_sort_key);
   } else {
     // |re_enqueue_sequence_callback_| will determine in which PriorityQueue
     // |sequence| must be enqueued.
@@ -465,9 +462,11 @@
 }
 
 SchedulerThreadPoolImpl::SchedulerThreadPoolImpl(
+    IORestriction io_restriction,
     TaskTracker* task_tracker,
     DelayedTaskManager* delayed_task_manager)
-    : idle_worker_threads_stack_lock_(shared_priority_queue_.container_lock()),
+    : io_restriction_(io_restriction),
+      idle_worker_threads_stack_lock_(shared_priority_queue_.container_lock()),
       idle_worker_threads_stack_cv_for_testing_(
           idle_worker_threads_stack_lock_.CreateConditionVariable()),
       join_for_testing_returned_(true, false),
diff --git a/base/task_scheduler/scheduler_thread_pool_impl.h b/base/task_scheduler/scheduler_thread_pool_impl.h
index 13fba7e5..06812c7 100644
--- a/base/task_scheduler/scheduler_thread_pool_impl.h
+++ b/base/task_scheduler/scheduler_thread_pool_impl.h
@@ -31,12 +31,16 @@
 namespace internal {
 
 class DelayedTaskManager;
-struct SequenceSortKey;
 class TaskTracker;
 
 // A pool of threads that run Tasks. This class is thread-safe.
 class BASE_EXPORT SchedulerThreadPoolImpl : public SchedulerThreadPool {
  public:
+  enum class IORestriction {
+    ALLOWED,
+    DISALLOWED,
+  };
+
   // Callback invoked when a Sequence isn't empty after a worker thread pops a
   // Task from it.
   using ReEnqueueSequenceCallback = Callback<void(scoped_refptr<Sequence>)>;
@@ -47,14 +51,17 @@
   ~SchedulerThreadPoolImpl() override;
 
   // Creates a SchedulerThreadPool with up to |max_threads| threads of priority
-  // |thread_priority|. |re_enqueue_sequence_callback| will be invoked after a
-  // thread of this thread pool tries to run a Task. |task_tracker| is used to
-  // handle shutdown behavior of Tasks. |delayed_task_manager| handles Tasks
-  // posted with a delay. Returns nullptr on failure to create a thread pool
-  // with at least one thread.
+  // |thread_priority|. |io_restriction| indicates whether Tasks on the
+  // constructed thread pool are allowed to make I/O calls.
+  // |re_enqueue_sequence_callback| will be invoked after a thread of this
+  // thread pool tries to run a Task. |task_tracker| is used to handle shutdown
+  // behavior of Tasks. |delayed_task_manager| handles Tasks posted with a
+  // delay. Returns nullptr on failure to create a thread pool with at least one
+  // thread.
   static std::unique_ptr<SchedulerThreadPoolImpl> Create(
       ThreadPriority thread_priority,
       size_t max_threads,
+      IORestriction io_restriction,
       const ReEnqueueSequenceCallback& re_enqueue_sequence_callback,
       TaskTracker* task_tracker,
       DelayedTaskManager* delayed_task_manager);
@@ -82,7 +89,8 @@
  private:
   class SchedulerWorkerThreadDelegateImpl;
 
-  SchedulerThreadPoolImpl(TaskTracker* task_tracker,
+  SchedulerThreadPoolImpl(IORestriction io_restriction,
+                          TaskTracker* task_tracker,
                           DelayedTaskManager* delayed_task_manager);
 
   bool Initialize(
@@ -113,6 +121,9 @@
   // PriorityQueue from which all threads of this thread pool get work.
   PriorityQueue shared_priority_queue_;
 
+  // Indicates whether Tasks on this thread pool are allowed to make I/O calls.
+  const IORestriction io_restriction_;
+
   // Synchronizes access to |idle_worker_threads_stack_| and
   // |idle_worker_threads_stack_cv_for_testing_|. Has |shared_priority_queue_|'s
   // lock as its predecessor so that a thread can be pushed to
diff --git a/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc b/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc
index 3eb003e..8ab4e17 100644
--- a/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc
+++ b/base/task_scheduler/scheduler_thread_pool_impl_unittest.cc
@@ -12,6 +12,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
@@ -24,8 +25,10 @@
 #include "base/task_scheduler/sequence_sort_key.h"
 #include "base/task_scheduler/task_tracker.h"
 #include "base/task_scheduler/test_task_factory.h"
+#include "base/task_scheduler/test_utils.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/simple_thread.h"
+#include "base/threading/thread_restrictions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -36,6 +39,8 @@
 const size_t kNumThreadsPostingTasks = 4;
 const size_t kNumTasksPostedPerThread = 150;
 
+using IORestriction = SchedulerThreadPoolImpl::IORestriction;
+
 class TestDelayedTaskManager : public DelayedTaskManager {
  public:
   TestDelayedTaskManager() : DelayedTaskManager(Bind(&DoNothing)) {}
@@ -58,7 +63,7 @@
 
   void SetUp() override {
     thread_pool_ = SchedulerThreadPoolImpl::Create(
-        ThreadPriority::NORMAL, kNumThreadsInThreadPool,
+        ThreadPriority::NORMAL, kNumThreadsInThreadPool, IORestriction::ALLOWED,
         Bind(&TaskSchedulerThreadPoolImplTest::ReEnqueueSequenceCallback,
              Unretained(this)),
         &task_tracker_, &delayed_task_manager_);
@@ -126,7 +131,7 @@
           WaitBeforePostTask::WAIT_FOR_ALL_THREADS_IDLE) {
         thread_pool_->WaitForAllWorkerThreadsIdleForTesting();
       }
-      EXPECT_TRUE(factory_.PostTask(post_nested_task_, nullptr));
+      EXPECT_TRUE(factory_.PostTask(post_nested_task_, Closure()));
     }
   }
 
@@ -145,11 +150,6 @@
   ADD_FAILURE() << "Ran a task that shouldn't run.";
 }
 
-void SignalEventCallback(WaitableEvent* event) {
-  DCHECK(event);
-  event->Signal();
-}
-
 }  // namespace
 
 TEST_P(TaskSchedulerThreadPoolImplTest, PostTasks) {
@@ -219,17 +219,17 @@
 }
 
 TEST_P(TaskSchedulerThreadPoolImplTest, PostTasksWithOneAvailableThread) {
-  // Post tasks to keep all threads busy except one until |event| is signaled.
-  // Use different factories so that tasks are added to different sequences and
-  // can run simultaneously when the execution mode is SEQUENCED.
+  // Post blocking tasks to keep all threads busy except one until |event| is
+  // signaled. Use different factories so that tasks are added to different
+  // sequences and can run simultaneously when the execution mode is SEQUENCED.
   WaitableEvent event(true, false);
   std::vector<std::unique_ptr<test::TestTaskFactory>> blocked_task_factories;
   for (size_t i = 0; i < (kNumThreadsInThreadPool - 1); ++i) {
     blocked_task_factories.push_back(WrapUnique(new test::TestTaskFactory(
         thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()),
         GetParam())));
-    EXPECT_TRUE(
-        blocked_task_factories.back()->PostTask(PostNestedTask::NO, &event));
+    EXPECT_TRUE(blocked_task_factories.back()->PostTask(
+        PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event))));
     blocked_task_factories.back()->WaitForAllTasksToRun();
   }
 
@@ -239,7 +239,7 @@
       thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()),
       GetParam());
   for (size_t i = 0; i < kNumTasksPostedPerThread; ++i)
-    EXPECT_TRUE(short_task_factory.PostTask(PostNestedTask::NO, nullptr));
+    EXPECT_TRUE(short_task_factory.PostTask(PostNestedTask::NO, Closure()));
   short_task_factory.WaitForAllTasksToRun();
 
   // Release tasks waiting on |event|.
@@ -252,16 +252,17 @@
 
 TEST_P(TaskSchedulerThreadPoolImplTest, Saturate) {
   // Verify that it is possible to have |kNumThreadsInThreadPool|
-  // tasks/sequences running simultaneously. Use different factories so that
-  // tasks are added to different sequences and can run simultaneously when the
-  // execution mode is SEQUENCED.
+  // tasks/sequences running simultaneously. Use different factories so that the
+  // blocking tasks are added to different sequences and can run simultaneously
+  // when the execution mode is SEQUENCED.
   WaitableEvent event(true, false);
   std::vector<std::unique_ptr<test::TestTaskFactory>> factories;
   for (size_t i = 0; i < kNumThreadsInThreadPool; ++i) {
     factories.push_back(WrapUnique(new test::TestTaskFactory(
         thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()),
         GetParam())));
-    EXPECT_TRUE(factories.back()->PostTask(PostNestedTask::NO, &event));
+    EXPECT_TRUE(factories.back()->PostTask(
+        PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event))));
     factories.back()->WaitForAllTasksToRun();
   }
 
@@ -289,7 +290,7 @@
   // Post a delayed task.
   WaitableEvent task_ran(true, false);
   EXPECT_TRUE(thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam())
-                  ->PostDelayedTask(FROM_HERE, Bind(&SignalEventCallback,
+                  ->PostDelayedTask(FROM_HERE, Bind(&WaitableEvent::Signal,
                                                     Unretained(&task_ran)),
                                     TimeDelta::FromSeconds(10)));
 
@@ -318,5 +319,65 @@
                         TaskSchedulerThreadPoolImplTest,
                         ::testing::Values(ExecutionMode::SINGLE_THREADED));
 
+namespace {
+
+void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) {
+  ADD_FAILURE()
+      << "Unexpected invocation of NotReachedReEnqueueSequenceCallback.";
+}
+
+// Verifies that the current thread allows I/O if |io_restriction| is ALLOWED
+// and disallows it otherwise. Signals |event| before returning.
+void ExpectIORestriction(IORestriction io_restriction, WaitableEvent* event) {
+  DCHECK(event);
+
+  if (io_restriction == IORestriction::ALLOWED) {
+    ThreadRestrictions::AssertIOAllowed();
+  } else {
+    static_assert(
+        ENABLE_THREAD_RESTRICTIONS == DCHECK_IS_ON(),
+        "ENABLE_THREAD_RESTRICTIONS and DCHECK_IS_ON() have diverged.");
+    EXPECT_DCHECK_DEATH({ ThreadRestrictions::AssertIOAllowed(); }, "");
+  }
+
+  event->Signal();
+}
+
+class TaskSchedulerThreadPoolImplIORestrictionTest
+    : public testing::TestWithParam<IORestriction> {
+ public:
+  TaskSchedulerThreadPoolImplIORestrictionTest() = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TaskSchedulerThreadPoolImplIORestrictionTest);
+};
+
+}  // namespace
+
+TEST_P(TaskSchedulerThreadPoolImplIORestrictionTest, IORestriction) {
+  TaskTracker task_tracker;
+  DelayedTaskManager delayed_task_manager(Bind(&DoNothing));
+
+  auto thread_pool = SchedulerThreadPoolImpl::Create(
+      ThreadPriority::NORMAL, 1U, GetParam(),
+      Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker,
+      &delayed_task_manager);
+  ASSERT_TRUE(thread_pool);
+
+  WaitableEvent task_ran(true, false);
+  thread_pool->CreateTaskRunnerWithTraits(TaskTraits(), ExecutionMode::PARALLEL)
+      ->PostTask(FROM_HERE, Bind(&ExpectIORestriction, GetParam(), &task_ran));
+  task_ran.Wait();
+
+  thread_pool->JoinForTesting();
+}
+
+INSTANTIATE_TEST_CASE_P(IOAllowed,
+                        TaskSchedulerThreadPoolImplIORestrictionTest,
+                        ::testing::Values(IORestriction::ALLOWED));
+INSTANTIATE_TEST_CASE_P(IODisallowed,
+                        TaskSchedulerThreadPoolImplIORestrictionTest,
+                        ::testing::Values(IORestriction::DISALLOWED));
+
 }  // namespace internal
 }  // namespace base
diff --git a/base/task_scheduler/sequence_sort_key.cc b/base/task_scheduler/sequence_sort_key.cc
index 758a411..e356c8b 100644
--- a/base/task_scheduler/sequence_sort_key.cc
+++ b/base/task_scheduler/sequence_sort_key.cc
@@ -9,19 +9,20 @@
 
 SequenceSortKey::SequenceSortKey(TaskPriority priority,
                                  TimeTicks next_task_sequenced_time)
-    : priority(priority), next_task_sequenced_time(next_task_sequenced_time) {}
+    : priority_(priority),
+      next_task_sequenced_time_(next_task_sequenced_time) {}
 
 bool SequenceSortKey::operator<(const SequenceSortKey& other) const {
   // This SequenceSortKey is considered less important than |other| if it has a
   // lower priority or if it has the same priority but its next task was posted
   // later than |other|'s.
   const int priority_diff =
-      static_cast<int>(priority) - static_cast<int>(other.priority);
+      static_cast<int>(priority_) - static_cast<int>(other.priority_);
   if (priority_diff < 0)
     return true;
   if (priority_diff > 0)
     return false;
-  return next_task_sequenced_time > other.next_task_sequenced_time;
+  return next_task_sequenced_time_ > other.next_task_sequenced_time_;
 }
 
 }  // namespace internal
diff --git a/base/task_scheduler/sequence_sort_key.h b/base/task_scheduler/sequence_sort_key.h
index f2dd561c..0a03ed1 100644
--- a/base/task_scheduler/sequence_sort_key.h
+++ b/base/task_scheduler/sequence_sort_key.h
@@ -12,20 +12,33 @@
 namespace base {
 namespace internal {
 
-// An immutable representation of the priority of a Sequence.
-struct BASE_EXPORT SequenceSortKey final {
+// An immutable but assignable representation of the priority of a Sequence.
+class BASE_EXPORT SequenceSortKey final {
+ public:
   SequenceSortKey(TaskPriority priority, TimeTicks next_task_sequenced_time);
 
   bool operator<(const SequenceSortKey& other) const;
   bool operator>(const SequenceSortKey& other) const { return other < *this; }
 
+  bool operator==(const SequenceSortKey& other) const {
+    return priority_ == other.priority_ &&
+           next_task_sequenced_time_ == other.next_task_sequenced_time_;
+  }
+  bool operator!=(const SequenceSortKey& other) const {
+    return !(other == *this);
+  };
+
+ private:
+  // The private section allows this class to keep its immutable property while
+  // being copy-assignable (i.e. instead of making its members const).
+
   // Highest task priority in the sequence at the time this sort key was
   // created.
-  const TaskPriority priority;
+  TaskPriority priority_;
 
   // Sequenced time of the next task to run in the sequence at the time this
   // sort key was created.
-  const TimeTicks next_task_sequenced_time;
+  TimeTicks next_task_sequenced_time_;
 };
 
 }  // namespace internal
diff --git a/base/task_scheduler/sequence_sort_key_unittest.cc b/base/task_scheduler/sequence_sort_key_unittest.cc
index 5c6c917..2c1d80d 100644
--- a/base/task_scheduler/sequence_sort_key_unittest.cc
+++ b/base/task_scheduler/sequence_sort_key_unittest.cc
@@ -125,5 +125,119 @@
   EXPECT_FALSE(key_f > key_f);
 }
 
+TEST(TaskSchedulerSequenceSortKeyTest, OperatorEqual) {
+  SequenceSortKey key_a(TaskPriority::USER_BLOCKING,
+                        TimeTicks::FromInternalValue(1000));
+  SequenceSortKey key_b(TaskPriority::USER_BLOCKING,
+                        TimeTicks::FromInternalValue(2000));
+  SequenceSortKey key_c(TaskPriority::USER_VISIBLE,
+                        TimeTicks::FromInternalValue(1000));
+  SequenceSortKey key_d(TaskPriority::USER_VISIBLE,
+                        TimeTicks::FromInternalValue(2000));
+  SequenceSortKey key_e(TaskPriority::BACKGROUND,
+                        TimeTicks::FromInternalValue(1000));
+  SequenceSortKey key_f(TaskPriority::BACKGROUND,
+                        TimeTicks::FromInternalValue(2000));
+
+  EXPECT_EQ(key_a, key_a);
+  EXPECT_FALSE(key_b == key_a);
+  EXPECT_FALSE(key_c == key_a);
+  EXPECT_FALSE(key_d == key_a);
+  EXPECT_FALSE(key_e == key_a);
+  EXPECT_FALSE(key_f == key_a);
+
+  EXPECT_FALSE(key_a == key_b);
+  EXPECT_EQ(key_b, key_b);
+  EXPECT_FALSE(key_c == key_b);
+  EXPECT_FALSE(key_d == key_b);
+  EXPECT_FALSE(key_e == key_b);
+  EXPECT_FALSE(key_f == key_b);
+
+  EXPECT_FALSE(key_a == key_c);
+  EXPECT_FALSE(key_b == key_c);
+  EXPECT_EQ(key_c, key_c);
+  EXPECT_FALSE(key_d == key_c);
+  EXPECT_FALSE(key_e == key_c);
+  EXPECT_FALSE(key_f == key_c);
+
+  EXPECT_FALSE(key_a == key_d);
+  EXPECT_FALSE(key_b == key_d);
+  EXPECT_FALSE(key_c == key_d);
+  EXPECT_EQ(key_d, key_d);
+  EXPECT_FALSE(key_e == key_d);
+  EXPECT_FALSE(key_f == key_d);
+
+  EXPECT_FALSE(key_a == key_e);
+  EXPECT_FALSE(key_b == key_e);
+  EXPECT_FALSE(key_c == key_e);
+  EXPECT_FALSE(key_d == key_e);
+  EXPECT_EQ(key_e, key_e);
+  EXPECT_FALSE(key_f == key_e);
+
+  EXPECT_FALSE(key_a == key_f);
+  EXPECT_FALSE(key_b == key_f);
+  EXPECT_FALSE(key_c == key_f);
+  EXPECT_FALSE(key_d == key_f);
+  EXPECT_FALSE(key_e == key_f);
+  EXPECT_EQ(key_f, key_f);
+}
+
+TEST(TaskSchedulerSequenceSortKeyTest, OperatorNotEqual) {
+  SequenceSortKey key_a(TaskPriority::USER_BLOCKING,
+                        TimeTicks::FromInternalValue(1000));
+  SequenceSortKey key_b(TaskPriority::USER_BLOCKING,
+                        TimeTicks::FromInternalValue(2000));
+  SequenceSortKey key_c(TaskPriority::USER_VISIBLE,
+                        TimeTicks::FromInternalValue(1000));
+  SequenceSortKey key_d(TaskPriority::USER_VISIBLE,
+                        TimeTicks::FromInternalValue(2000));
+  SequenceSortKey key_e(TaskPriority::BACKGROUND,
+                        TimeTicks::FromInternalValue(1000));
+  SequenceSortKey key_f(TaskPriority::BACKGROUND,
+                        TimeTicks::FromInternalValue(2000));
+
+  EXPECT_FALSE(key_a != key_a);
+  EXPECT_NE(key_b, key_a);
+  EXPECT_NE(key_c, key_a);
+  EXPECT_NE(key_d, key_a);
+  EXPECT_NE(key_e, key_a);
+  EXPECT_NE(key_f, key_a);
+
+  EXPECT_NE(key_a, key_b);
+  EXPECT_FALSE(key_b != key_b);
+  EXPECT_NE(key_c, key_b);
+  EXPECT_NE(key_d, key_b);
+  EXPECT_NE(key_e, key_b);
+  EXPECT_NE(key_f, key_b);
+
+  EXPECT_NE(key_a, key_c);
+  EXPECT_NE(key_b, key_c);
+  EXPECT_FALSE(key_c != key_c);
+  EXPECT_NE(key_d, key_c);
+  EXPECT_NE(key_e, key_c);
+  EXPECT_NE(key_f, key_c);
+
+  EXPECT_NE(key_a, key_d);
+  EXPECT_NE(key_b, key_d);
+  EXPECT_NE(key_c, key_d);
+  EXPECT_FALSE(key_d != key_d);
+  EXPECT_NE(key_e, key_d);
+  EXPECT_NE(key_f, key_d);
+
+  EXPECT_NE(key_a, key_e);
+  EXPECT_NE(key_b, key_e);
+  EXPECT_NE(key_c, key_e);
+  EXPECT_NE(key_d, key_e);
+  EXPECT_FALSE(key_e != key_e);
+  EXPECT_NE(key_f, key_e);
+
+  EXPECT_NE(key_a, key_f);
+  EXPECT_NE(key_b, key_f);
+  EXPECT_NE(key_c, key_f);
+  EXPECT_NE(key_d, key_f);
+  EXPECT_NE(key_e, key_f);
+  EXPECT_FALSE(key_f != key_f);
+}
+
 }  // namespace internal
 }  // namespace base
diff --git a/base/task_scheduler/sequence_unittest.cc b/base/task_scheduler/sequence_unittest.cc
index 25baea4..6a15299e 100644
--- a/base/task_scheduler/sequence_unittest.cc
+++ b/base/task_scheduler/sequence_unittest.cc
@@ -68,13 +68,6 @@
   DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSequenceTest);
 };
 
-void ExpectSortKey(TaskPriority expected_priority,
-                   TimeTicks expected_sequenced_time,
-                   const SequenceSortKey& actual_sort_key) {
-  EXPECT_EQ(expected_priority, actual_sort_key.priority);
-  EXPECT_EQ(expected_sequenced_time, actual_sort_key.next_task_sequenced_time);
-}
-
 }  // namespace
 
 TEST_F(TaskSchedulerSequenceTest, PushPopPeek) {
@@ -133,56 +126,63 @@
   // Push task A in the sequence. The highest priority is from task A
   // (BACKGROUND). Task A is in front of the sequence.
   sequence->PushTask(std::move(task_a_owned_));
-  ExpectSortKey(TaskPriority::BACKGROUND, task_a_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(SequenceSortKey(TaskPriority::BACKGROUND, task_a_->sequenced_time),
+            sequence->GetSortKey());
 
   // Push task B in the sequence. The highest priority is from task B
   // (USER_VISIBLE). Task A is still in front of the sequence.
   sequence->PushTask(std::move(task_b_owned_));
-  ExpectSortKey(TaskPriority::USER_VISIBLE, task_a_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(
+      SequenceSortKey(TaskPriority::USER_VISIBLE, task_a_->sequenced_time),
+      sequence->GetSortKey());
 
   // Push task C in the sequence. The highest priority is from task C
   // (USER_BLOCKING). Task A is still in front of the sequence.
   sequence->PushTask(std::move(task_c_owned_));
-  ExpectSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(
+      SequenceSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time),
+      sequence->GetSortKey());
 
   // Push task D in the sequence. The highest priority is from tasks C/D
   // (USER_BLOCKING). Task A is still in front of the sequence.
   sequence->PushTask(std::move(task_d_owned_));
-  ExpectSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(
+      SequenceSortKey(TaskPriority::USER_BLOCKING, task_a_->sequenced_time),
+      sequence->GetSortKey());
 
   // Pop task A. The highest priority is still USER_BLOCKING. The task in front
   // of the sequence is now task B.
   sequence->PopTask();
-  ExpectSortKey(TaskPriority::USER_BLOCKING, task_b_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(
+      SequenceSortKey(TaskPriority::USER_BLOCKING, task_b_->sequenced_time),
+      sequence->GetSortKey());
 
   // Pop task B. The highest priority is still USER_BLOCKING. The task in front
   // of the sequence is now task C.
   sequence->PopTask();
-  ExpectSortKey(TaskPriority::USER_BLOCKING, task_c_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(
+      SequenceSortKey(TaskPriority::USER_BLOCKING, task_c_->sequenced_time),
+      sequence->GetSortKey());
 
   // Pop task C. The highest priority is still USER_BLOCKING. The task in front
   // of the sequence is now task D.
   sequence->PopTask();
-  ExpectSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(
+      SequenceSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time),
+      sequence->GetSortKey());
 
   // Push task E in the sequence. The highest priority is still USER_BLOCKING.
   // The task in front of the sequence is still task D.
   sequence->PushTask(std::move(task_e_owned_));
-  ExpectSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(
+      SequenceSortKey(TaskPriority::USER_BLOCKING, task_d_->sequenced_time),
+      sequence->GetSortKey());
 
   // Pop task D. The highest priority is now from task E (BACKGROUND). The
   // task in front of the sequence is now task E.
   sequence->PopTask();
-  ExpectSortKey(TaskPriority::BACKGROUND, task_e_->sequenced_time,
-                sequence->GetSortKey());
+  EXPECT_EQ(SequenceSortKey(TaskPriority::BACKGROUND, task_e_->sequenced_time),
+            sequence->GetSortKey());
 }
 
 }  // namespace internal
diff --git a/base/task_scheduler/task_tracker.cc b/base/task_scheduler/task_tracker.cc
index c896a9fa..29951a6 100644
--- a/base/task_scheduler/task_tracker.cc
+++ b/base/task_scheduler/task_tracker.cc
@@ -7,6 +7,7 @@
 #include "base/callback.h"
 #include "base/debug/task_annotator.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/threading/thread_restrictions.h"
 
 namespace base {
 namespace internal {
@@ -78,6 +79,13 @@
   if (!BeforeRunTask(shutdown_behavior))
     return;
 
+  // All tasks run through here and the scheduler itself doesn't use singletons.
+  // Therefore, it isn't necessary to reset the singleton allowed bit after
+  // running the task.
+  ThreadRestrictions::SetSingletonAllowed(
+      task->traits.shutdown_behavior() !=
+      TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
+
   debug::TaskAnnotator task_annotator;
   task_annotator.RunTask(kQueueFunctionName, *task);
 
diff --git a/base/task_scheduler/task_tracker_unittest.cc b/base/task_scheduler/task_tracker_unittest.cc
index c5e0c034..f3a8183f 100644
--- a/base/task_scheduler/task_tracker_unittest.cc
+++ b/base/task_scheduler/task_tracker_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/task_scheduler/test_utils.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/simple_thread.h"
+#include "base/threading/thread_restrictions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -61,6 +62,19 @@
   DISALLOW_COPY_AND_ASSIGN(ThreadRunningTask);
 };
 
+class ScopedSetSingletonAllowed {
+ public:
+  ScopedSetSingletonAllowed(bool singleton_allowed)
+      : previous_value_(
+            ThreadRestrictions::SetSingletonAllowed(singleton_allowed)) {}
+  ~ScopedSetSingletonAllowed() {
+    ThreadRestrictions::SetSingletonAllowed(previous_value_);
+  }
+
+ private:
+  const bool previous_value_;
+};
+
 class TaskSchedulerTaskTrackerTest
     : public testing::TestWithParam<TaskShutdownBehavior> {
  protected:
@@ -283,6 +297,30 @@
   }
 }
 
+// Verify that BLOCK_SHUTDOWN and SKIP_ON_SHUTDOWN tasks can
+// AssertSingletonAllowed() but CONTINUE_ON_SHUTDOWN tasks can't.
+TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) {
+  const bool can_use_singletons =
+      (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
+
+  TaskTracker tracker;
+  Task task(FROM_HERE, Bind(&ThreadRestrictions::AssertSingletonAllowed),
+            TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta());
+  EXPECT_TRUE(tracker.WillPostTask(&task));
+
+  // Set the singleton allowed bit to the opposite of what it is expected to be
+  // when |tracker| runs |task| to verify that |tracker| actually sets the
+  // correct value.
+  ScopedSetSingletonAllowed scoped_singleton_allowed(!can_use_singletons);
+
+  // Running the task should fail iff the task isn't allowed to use singletons.
+  if (can_use_singletons) {
+    tracker.RunTask(&task);
+  } else {
+    EXPECT_DCHECK_DEATH({ tracker.RunTask(&task); }, "");
+  }
+}
+
 INSTANTIATE_TEST_CASE_P(
     ContinueOnShutdown,
     TaskSchedulerTaskTrackerTest,
diff --git a/base/task_scheduler/test_task_factory.cc b/base/task_scheduler/test_task_factory.cc
index 5edf3dd..541caac 100644
--- a/base/task_scheduler/test_task_factory.cc
+++ b/base/task_scheduler/test_task_factory.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/synchronization/waitable_event.h"
@@ -30,12 +31,12 @@
 }
 
 bool TestTaskFactory::PostTask(PostNestedTask post_nested_task,
-                               WaitableEvent* event) {
+                               const Closure& after_task_closure) {
   AutoLock auto_lock(lock_);
   return task_runner_->PostTask(
       FROM_HERE,
       Bind(&TestTaskFactory::RunTaskCallback, Unretained(this),
-           num_posted_tasks_++, post_nested_task, Unretained(event)));
+           num_posted_tasks_++, post_nested_task, after_task_closure));
 }
 
 void TestTaskFactory::WaitForAllTasksToRun() const {
@@ -46,9 +47,9 @@
 
 void TestTaskFactory::RunTaskCallback(size_t task_index,
                                       PostNestedTask post_nested_task,
-                                      WaitableEvent* event) {
+                                      const Closure& after_task_closure) {
   if (post_nested_task == PostNestedTask::YES)
-    PostTask(PostNestedTask::NO, nullptr);
+    PostTask(PostNestedTask::NO, Closure());
 
   EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread());
 
@@ -73,8 +74,8 @@
     cv_.Signal();
   }
 
-  if (event)
-    event->Wait();
+  if (!after_task_closure.is_null())
+    after_task_closure.Run();
 }
 
 }  // namespace test
diff --git a/base/task_scheduler/test_task_factory.h b/base/task_scheduler/test_task_factory.h
index 9a118822..9102c7c5 100644
--- a/base/task_scheduler/test_task_factory.h
+++ b/base/task_scheduler/test_task_factory.h
@@ -9,6 +9,7 @@
 
 #include <unordered_set>
 
+#include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/condition_variable.h"
@@ -26,6 +27,8 @@
 
 // A TestTaskFactory posts tasks to a TaskRunner and verifies that they run as
 // expected. Generates a test failure when:
+// - The RunsTasksOnCurrentThread() method of the TaskRunner returns false on a
+//   thread on which a Task is run.
 // - The ExecutionMode of the TaskRunner is SEQUENCED or SINGLE_THREADED and
 //   Tasks don't run in posting order.
 // - The ExecutionMode of the TaskRunner is SINGLE_THREADED and Tasks don't
@@ -45,10 +48,13 @@
 
   ~TestTaskFactory();
 
-  // Posts a task. If |post_nested_task| is YES, the task will post a new task
-  // when it runs. If |event| is set, the task will block until it is signaled.
-  // Returns true if the task is posted.
-  bool PostTask(PostNestedTask post_nested_task, WaitableEvent* event);
+  // Posts a task. The posted task will:
+  // - Post a new task if |post_nested_task| is YES. The nested task won't run
+  //   |after_task_closure|.
+  // - Verify conditions in which the task runs (see potential failures above).
+  // - Run |after_task_closure| if it is not null.
+  bool PostTask(PostNestedTask post_nested_task,
+                const Closure& after_task_closure);
 
   // Waits for all tasks posted by PostTask() to start running. It is not
   // guaranteed that the tasks have completed their execution when this returns.
@@ -59,7 +65,7 @@
  private:
   void RunTaskCallback(size_t task_index,
                        PostNestedTask post_nested_task,
-                       WaitableEvent* event);
+                       const Closure& after_task_closure);
 
   // Synchronizes access to all members.
   mutable Lock lock_;
diff --git a/base/trace_event/heap_profiler.h b/base/trace_event/heap_profiler.h
index dd587e5e..3ac16cd 100644
--- a/base/trace_event/heap_profiler.h
+++ b/base/trace_event/heap_profiler.h
@@ -33,16 +33,20 @@
 class BASE_EXPORT HeapProfilerScopedIgnore {
  public:
   inline HeapProfilerScopedIgnore() {
+    using base::trace_event::AllocationContextTracker;
     if (UNLIKELY(
-            base::trace_event::AllocationContextTracker::capture_enabled())) {
-      base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()
+            AllocationContextTracker::capture_mode() !=
+            AllocationContextTracker::CaptureMode::DISABLED)) {
+      AllocationContextTracker::GetInstanceForCurrentThread()
           ->begin_ignore_scope();
     }
   }
   inline ~HeapProfilerScopedIgnore() {
+    using base::trace_event::AllocationContextTracker;
     if (UNLIKELY(
-            base::trace_event::AllocationContextTracker::capture_enabled())) {
-      base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()
+            AllocationContextTracker::capture_mode() !=
+            AllocationContextTracker::CaptureMode::DISABLED)) {
+      AllocationContextTracker::GetInstanceForCurrentThread()
           ->end_ignore_scope();
     }
   }
diff --git a/base/trace_event/heap_profiler_allocation_context.h b/base/trace_event/heap_profiler_allocation_context.h
index 764712f..3566dd0 100644
--- a/base/trace_event/heap_profiler_allocation_context.h
+++ b/base/trace_event/heap_profiler_allocation_context.h
@@ -29,9 +29,9 @@
 // memory used for tracing and accuracy. Measurements done on a prototype
 // revealed that:
 //
-// - In 60 percent of the cases, stack depth <= 7.
-// - In 87 percent of the cases, stack depth <= 9.
-// - In 95 percent of the cases, stack depth <= 11.
+// - In 60 percent of the cases, pseudo stack depth <= 7.
+// - In 87 percent of the cases, pseudo stack depth <= 9.
+// - In 95 percent of the cases, pseudo stack depth <= 11.
 //
 // See the design doc (https://goo.gl/4s7v7b) for more details.
 
@@ -44,6 +44,7 @@
   enum class Type {
     TRACE_EVENT_NAME,   // const char* string
     THREAD_NAME,        // const char* thread name
+    PROGRAM_COUNTER,    // as returned by stack tracing (e.g. by StackTrace)
   };
 
   static StackFrame FromTraceEventName(const char* name) {
@@ -52,6 +53,9 @@
   static StackFrame FromThreadName(const char* name) {
     return {Type::THREAD_NAME, name};
   }
+  static StackFrame FromProgramCounter(const void* pc) {
+    return {Type::PROGRAM_COUNTER, pc};
+  }
 
   Type type;
   const void* value;
@@ -65,9 +69,9 @@
   Backtrace();
 
   // If the stack is higher than what can be stored here, the bottom frames
-  // (the ones closer to main()) are stored. Based on the data above, a depth
-  // of 12 captures the full stack in the vast majority of the cases.
-  enum { kMaxFrameCount = 12 };
+  // (the ones closer to main()) are stored. Depth of 12 is enough for most
+  // pseudo traces (see above), but not for native traces, where we need more.
+  enum { kMaxFrameCount = 24 };
   StackFrame frames[kMaxFrameCount];
   size_t frame_count;
 };
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc
index e192bc83..c3df28b 100644
--- a/base/trace_event/heap_profiler_allocation_context_tracker.cc
+++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc
@@ -14,7 +14,8 @@
 namespace base {
 namespace trace_event {
 
-subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0;
+subtle::Atomic32 AllocationContextTracker::capture_mode_ =
+    static_cast<int32_t>(AllocationContextTracker::CaptureMode::DISABLED);
 
 namespace {
 
@@ -60,21 +61,21 @@
 
 // static
 void AllocationContextTracker::SetCurrentThreadName(const char* name) {
-  if (name && capture_enabled()) {
+  if (name && capture_mode() != CaptureMode::DISABLED) {
     GetInstanceForCurrentThread()->thread_name_ = name;
   }
 }
 
 // static
-void AllocationContextTracker::SetCaptureEnabled(bool enabled) {
+void AllocationContextTracker::SetCaptureMode(CaptureMode mode) {
   // When enabling capturing, also initialize the TLS slot. This does not create
   // a TLS instance yet.
-  if (enabled && !g_tls_alloc_ctx_tracker.initialized())
+  if (mode != CaptureMode::DISABLED && !g_tls_alloc_ctx_tracker.initialized())
     g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker);
 
-  // Release ordering ensures that when a thread observes |capture_enabled_| to
+  // Release ordering ensures that when a thread observes |capture_mode_| to
   // be true through an acquire load, the TLS slot has been initialized.
-  subtle::Release_Store(&capture_enabled_, enabled);
+  subtle::Release_Store(&capture_mode_, static_cast<int32_t>(mode));
 }
 
 void AllocationContextTracker::PushPseudoStackFrame(
@@ -129,26 +130,66 @@
     return ctx;
   }
 
-  // Fill the backtrace.
-  {
-    auto backtrace = std::begin(ctx.backtrace.frames);
-    auto backtrace_end = std::end(ctx.backtrace.frames);
+  CaptureMode mode = static_cast<CaptureMode>(
+      subtle::NoBarrier_Load(&capture_mode_));
 
-    // Add the thread name as the first entry
-    if (thread_name_) {
-      *backtrace++ = StackFrame::FromThreadName(thread_name_);
-    }
+  auto backtrace = std::begin(ctx.backtrace.frames);
+  auto backtrace_end = std::end(ctx.backtrace.frames);
 
-    for (const char* event_name: pseudo_stack_) {
-      if (backtrace == backtrace_end) {
+  // Add the thread name as the first entry
+  if (thread_name_) {
+    *backtrace++ = StackFrame::FromThreadName(thread_name_);
+  }
+
+  switch (mode) {
+    case CaptureMode::DISABLED:
+      {
         break;
       }
-      *backtrace++ = StackFrame::FromTraceEventName(event_name);
-    }
+    case CaptureMode::PSEUDO_STACK:
+      {
+        for (const char* event_name: pseudo_stack_) {
+          if (backtrace == backtrace_end) {
+            break;
+          }
+          *backtrace++ = StackFrame::FromTraceEventName(event_name);
+        }
+        break;
+      }
+    case CaptureMode::NATIVE_STACK:
+      {
+        // Backtrace contract requires us to return bottom frames, i.e.
+        // from main() and up. Stack unwinding produces top frames, i.e.
+        // from this point and up until main(). We request many frames to
+        // make sure we reach main(), and then copy bottom portion of them.
+        const void* frames[128];
+        static_assert(arraysize(frames) >= Backtrace::kMaxFrameCount,
+                      "not requesting enough frames to fill Backtrace");
+#if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_NACL)
+        size_t frame_count = debug::TraceStackFramePointers(
+            frames,
+            arraysize(frames),
+            1 /* exclude this function from the trace */ );
+#else
+        size_t frame_count = 0;
+        NOTREACHED();
+#endif
 
-    ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames);
+        // Copy frames backwards
+        size_t backtrace_capacity = backtrace_end - backtrace;
+        size_t top_frame_index = (backtrace_capacity >= frame_count) ?
+            0 :
+            frame_count - backtrace_capacity;
+        for (size_t i = frame_count; i > top_frame_index;) {
+          const void* frame = frames[--i];
+          *backtrace++ = StackFrame::FromProgramCounter(frame);
+        }
+        break;
+      }
   }
 
+  ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames);
+
   // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension
   // (component name) in the heap profiler and not piggy back on the type name.
   ctx.type_name = task_contexts_.empty() ? nullptr : task_contexts_.back();
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.h b/base/trace_event/heap_profiler_allocation_context_tracker.h
index 632a4ef..454200c4 100644
--- a/base/trace_event/heap_profiler_allocation_context_tracker.h
+++ b/base/trace_event/heap_profiler_allocation_context_tracker.h
@@ -9,6 +9,7 @@
 
 #include "base/atomicops.h"
 #include "base/base_export.h"
+#include "base/debug/stack_trace.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/trace_event/heap_profiler_allocation_context.h"
@@ -23,24 +24,30 @@
 // details.
 class BASE_EXPORT AllocationContextTracker {
  public:
-  // Globally enables capturing allocation context.
-  // TODO(ruuda): Should this be replaced by |EnableCapturing| in the future?
-  // Or at least have something that guards agains enable -> disable -> enable?
-  static void SetCaptureEnabled(bool enabled);
+  enum class CaptureMode: int32_t {
+    DISABLED,       // Don't capture anything
+    PSEUDO_STACK,   // GetContextSnapshot() returns pseudo stack trace
+    NATIVE_STACK    // GetContextSnapshot() returns native (real) stack trace
+  };
 
-  // Returns whether capturing allocation context is enabled globally.
-  inline static bool capture_enabled() {
+  // Globally sets capturing mode.
+  // TODO(primiano): How to guard against *_STACK -> DISABLED -> *_STACK?
+  static void SetCaptureMode(CaptureMode mode);
+
+  // Returns global capturing mode.
+  inline static CaptureMode capture_mode() {
     // A little lag after heap profiling is enabled or disabled is fine, it is
     // more important that the check is as cheap as possible when capturing is
     // not enabled, so do not issue a memory barrier in the fast path.
-    if (subtle::NoBarrier_Load(&capture_enabled_) == 0)
-      return false;
+    if (subtle::NoBarrier_Load(&capture_mode_) ==
+            static_cast<int32_t>(CaptureMode::DISABLED))
+      return CaptureMode::DISABLED;
 
     // In the slow path, an acquire load is required to pair with the release
-    // store in |SetCaptureEnabled|. This is to ensure that the TLS slot for
+    // store in |SetCaptureMode|. This is to ensure that the TLS slot for
     // the thread-local allocation context tracker has been initialized if
-    // |capture_enabled| returns true.
-    return subtle::Acquire_Load(&capture_enabled_) != 0;
+    // |capture_mode| returns something other than DISABLED.
+    return static_cast<CaptureMode>(subtle::Acquire_Load(&capture_mode_));
   }
 
   // Returns the thread-local instance, creating one if necessary. Returns
@@ -80,7 +87,7 @@
  private:
   AllocationContextTracker();
 
-  static subtle::Atomic32 capture_enabled_;
+  static subtle::Atomic32 capture_mode_;
 
   // The pseudo stack where frames are |TRACE_EVENT| names.
   std::vector<const char*> pseudo_stack_;
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
index ed03704..cf2360f 100644
--- a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
+++ b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc
@@ -62,11 +62,13 @@
   void SetUp() override {
     TraceConfig config("");
     TraceLog::GetInstance()->SetEnabled(config, TraceLog::RECORDING_MODE);
-    AllocationContextTracker::SetCaptureEnabled(true);
+    AllocationContextTracker::SetCaptureMode(
+        AllocationContextTracker::CaptureMode::PSEUDO_STACK);
   }
 
   void TearDown() override {
-    AllocationContextTracker::SetCaptureEnabled(false);
+    AllocationContextTracker::SetCaptureMode(
+        AllocationContextTracker::CaptureMode::DISABLED);
     TraceLog::GetInstance()->SetDisabled();
   }
 };
diff --git a/base/trace_event/heap_profiler_stack_frame_deduplicator.cc b/base/trace_event/heap_profiler_stack_frame_deduplicator.cc
index 2295780..49a2350 100644
--- a/base/trace_event/heap_profiler_stack_frame_deduplicator.cc
+++ b/base/trace_event/heap_profiler_stack_frame_deduplicator.cc
@@ -4,6 +4,7 @@
 
 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
 
+#include <inttypes.h>
 #include <stddef.h>
 
 #include <string>
@@ -90,6 +91,12 @@
                       static_cast<const char*>(frame.value));
         frame_node_value->SetString("name", stringify_buffer);
         break;
+      case StackFrame::Type::PROGRAM_COUNTER:
+        SStringPrintf(&stringify_buffer,
+                      "pc:%" PRIxPTR,
+                      reinterpret_cast<uintptr_t>(frame.value));
+        frame_node_value->SetString("name", stringify_buffer);
+        break;
     }
     if (frame_node->parent_frame_index >= 0) {
       SStringPrintf(&stringify_buffer, "%d", frame_node->parent_frame_index);
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index 5ae7460e..e18a20c4 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -11,6 +11,8 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
+#include "base/debug/debugging_flags.h"
+#include "base/debug/stack_trace.h"
 #include "base/memory/ptr_util.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/threading/thread.h"
@@ -170,7 +172,29 @@
           switches::kEnableHeapProfiling))
     return;
 
-  AllocationContextTracker::SetCaptureEnabled(true);
+  std::string profiling_mode = CommandLine::ForCurrentProcess()
+      ->GetSwitchValueASCII(switches::kEnableHeapProfiling);
+  if (profiling_mode == "") {
+    AllocationContextTracker::SetCaptureMode(
+        AllocationContextTracker::CaptureMode::PSEUDO_STACK);
+  }
+  else if (profiling_mode == switches::kEnableHeapProfilingModeNative) {
+#if HAVE_TRACE_STACK_FRAME_POINTERS && \
+    (BUILDFLAG(ENABLE_PROFILING) || !defined(NDEBUG))
+    // We need frame pointers for native tracing to work, and they are
+    // enabled in profiling and debug builds.
+    AllocationContextTracker::SetCaptureMode(
+        AllocationContextTracker::CaptureMode::NATIVE_STACK);
+#else
+    CHECK(false) << "'" << profiling_mode << "' mode for "
+                 << switches::kEnableHeapProfiling << " flag is not supported "
+                 << "for this platform / build type.";
+#endif
+  } else {
+    CHECK(false) << "Invalid mode '" << profiling_mode << "' for "
+               << switches::kEnableHeapProfiling << " flag.";
+  }
+
   for (auto mdp : dump_providers_)
     mdp->dump_provider->OnHeapProfilingEnabled(true);
   heap_profiling_enabled_ = true;
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
index ef452f6..542537d 100644
--- a/base/trace_event/trace_event.h
+++ b/base/trace_event/trace_event.h
@@ -1056,17 +1056,21 @@
  public:
   explicit ScopedTaskExecutionEvent(const char* task_context)
       : context_(task_context) {
+    using base::trace_event::AllocationContextTracker;
     if (UNLIKELY(
-            base::trace_event::AllocationContextTracker::capture_enabled())) {
-      base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()
+            AllocationContextTracker::capture_mode() !=
+            AllocationContextTracker::CaptureMode::DISABLED)) {
+      AllocationContextTracker::GetInstanceForCurrentThread()
           ->PushCurrentTaskContext(context_);
     }
   }
 
   ~ScopedTaskExecutionEvent() {
+    using base::trace_event::AllocationContextTracker;
     if (UNLIKELY(
-            base::trace_event::AllocationContextTracker::capture_enabled())) {
-      base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()
+            AllocationContextTracker::capture_mode() !=
+            AllocationContextTracker::CaptureMode::DISABLED)) {
+      AllocationContextTracker::GetInstanceForCurrentThread()
           ->PopCurrentTaskContext(context_);
     }
   }
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index 6a1d8a4..e626a77 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -267,15 +267,15 @@
 }
 
 void TraceEventTestFixture::DropTracedMetadataRecords() {
-  std::unique_ptr<ListValue> old_trace_parsed(trace_parsed_.DeepCopy());
+  std::unique_ptr<ListValue> old_trace_parsed(trace_parsed_.CreateDeepCopy());
   size_t old_trace_parsed_size = old_trace_parsed->GetSize();
   trace_parsed_.Clear();
 
   for (size_t i = 0; i < old_trace_parsed_size; i++) {
-    Value* value = NULL;
+    Value* value = nullptr;
     old_trace_parsed->Get(i, &value);
     if (!value || value->GetType() != Value::TYPE_DICTIONARY) {
-      trace_parsed_.Append(value->DeepCopy());
+      trace_parsed_.Append(value->CreateDeepCopy());
       continue;
     }
     DictionaryValue* dict = static_cast<DictionaryValue*>(value);
@@ -283,7 +283,7 @@
     if (dict->GetString("ph", &tmp) && tmp == "M")
       continue;
 
-    trace_parsed_.Append(value->DeepCopy());
+    trace_parsed_.Append(value->CreateDeepCopy());
   }
 }
 
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
index 1a375d1..5692e83 100644
--- a/base/trace_event/trace_log.cc
+++ b/base/trace_event/trace_log.cc
@@ -1319,7 +1319,8 @@
 
   // TODO(primiano): Add support for events with copied name crbug.com/581078
   if (!(flags & TRACE_EVENT_FLAG_COPY)) {
-    if (AllocationContextTracker::capture_enabled()) {
+    if (AllocationContextTracker::capture_mode() ==
+        AllocationContextTracker::CaptureMode::PSEUDO_STACK) {
       if (phase == TRACE_EVENT_PHASE_BEGIN ||
           phase == TRACE_EVENT_PHASE_COMPLETE) {
         AllocationContextTracker::GetInstanceForCurrentThread()
@@ -1452,9 +1453,10 @@
           EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event);
     }
 
-    if (base::trace_event::AllocationContextTracker::capture_enabled()) {
+    if (AllocationContextTracker::capture_mode() ==
+        AllocationContextTracker::CaptureMode::PSEUDO_STACK) {
       // The corresponding push is in |AddTraceEventWithThreadIdAndTimestamp|.
-      base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()
+      AllocationContextTracker::GetInstanceForCurrentThread()
           ->PopPseudoStackFrame(name);
     }
   }
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc
index 77e84de..d98664e8 100644
--- a/base/win/windows_version.cc
+++ b/base/win/windows_version.cc
@@ -14,6 +14,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/registry.h"
 
+#if !defined(__clang__) && _MSC_FULL_VER < 190023918
+#error VS 2015 Update 2 or higher is required
+#endif
+
 namespace {
 typedef BOOL (WINAPI *GetProductInfoPtr)(DWORD, DWORD, DWORD, DWORD, PDWORD);
 }  // namespace
diff --git a/blimp/BUILD.gn b/blimp/BUILD.gn
index ec23917..61e216fc 100644
--- a/blimp/BUILD.gn
+++ b/blimp/BUILD.gn
@@ -14,8 +14,8 @@
 
   deps = [
     ":blimp_tests",
-    "//blimp/client:blimp_client",
-    "//blimp/common:blimp_common",
+    "//blimp/client",
+    "//blimp/common",
   ]
 
   if (is_android) {
@@ -27,7 +27,7 @@
 
   if (is_linux) {
     deps += [
-      "//blimp/engine:blimp_engine",
+      "//blimp/engine",
       "//blimp/engine:blimp_engine_bundle",
     ]
   }
diff --git a/blimp/client/BUILD.gn b/blimp/client/BUILD.gn
index 9ff28e6..9f59d259 100644
--- a/blimp/client/BUILD.gn
+++ b/blimp/client/BUILD.gn
@@ -9,7 +9,7 @@
   import("//build/config/android/rules.gni")
 }
 
-source_set("blimp_client") {
+source_set("client") {
   sources = [
     "app/blimp_client_switches.cc",
     "app/blimp_client_switches.h",
@@ -17,15 +17,12 @@
     "app/blimp_discardable_memory_allocator.h",
     "app/blimp_startup.cc",
     "app/blimp_startup.h",
-    "blimp_client_export.h",
     "session/assignment_source.cc",
     "session/assignment_source.h",
     "session/blimp_client_session.cc",
     "session/blimp_client_session.h",
   ]
 
-  defines = [ "BLIMP_CLIENT_IMPLEMENTATION=1" ]
-
   public_deps = [
     "//components/safe_json",
     "//components/url_formatter",
@@ -35,14 +32,16 @@
   deps = [
     ":feature",
     "//base",
+    "//blimp/common",
     "//blimp/common/proto",
-    "//blimp/net:blimp_net",
+    "//blimp/net",
     "//cc",
     "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/skia_bindings",
     "//net",
     "//third_party/libwebp",
     "//ui/gfx/geometry",
+    "//ui/gl",
     "//url:url",
   ]
 }
@@ -53,10 +52,11 @@
   sources = []
 
   deps = [
-    ":blimp_client",
+    ":client",
     "//base",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
+    "//blimp/common",
     "//testing/gmock",
     "//testing/gtest",
   ]
@@ -83,7 +83,7 @@
   ]
 
   deps = [
-    ":blimp_client",
+    ":client",
     "//base",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
@@ -125,16 +125,22 @@
   ]
 
   deps = [
-    "//blimp/common:blimp_common",
-    "//blimp/net:blimp_net",
+    "//blimp/common",
+    "//blimp/net",
     "//cc",
     "//cc/proto",
+    "//components/url_formatter",
     "//gpu/command_buffer/client",
     "//gpu/command_buffer/client:gl_in_process_context",
+    "//gpu/command_buffer/client:gles2_c_lib",
+    "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/command_buffer/common:gles2_utils",
     "//gpu/skia_bindings",
+    "//net",
     "//skia",
+    "//third_party/WebKit/public:blink_headers",
     "//ui/base/ime:text_input_types",
+    "//ui/events:gesture_detection",
     "//ui/events/blink",
     "//ui/events/gestures/blink",
     "//ui/gl",
@@ -160,14 +166,18 @@
     "//base",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
-    "//blimp/common:blimp_common",
+    "//blimp/common",
     "//blimp/common/proto",
-    "//blimp/net:blimp_net",
+    "//blimp/net",
     "//blimp/net:test_support",
     "//cc/proto",
+    "//net",
+    "//net:test_support",
     "//skia",
     "//testing/gmock",
     "//testing/gtest",
+    "//ui/events:gesture_detection",
+    "//ui/gfx/geometry",
   ]
 
   if (is_linux) {
@@ -187,12 +197,13 @@
     ]
 
     deps = [
-      ":blimp_client",
+      ":client",
       ":feature",
       "//base",
-      "//blimp/net:blimp_net",
+      "//blimp/net",
       "//net",
       "//ui/events/platform/x11",
+      "//ui/platform_window",
       "//ui/platform_window/x11",
     ]
 
@@ -358,14 +369,16 @@
 
   shared_library("blimp_client_android") {
     deps = [
-      ":blimp_client",
+      ":client",
       ":feature",
       ":jni_headers",
       "//base",
+      "//blimp/common",
       "//blimp/common/proto",
-      "//blimp/net:blimp_net",
+      "//blimp/net",
       "//components/safe_json/android:safe_json_jni_headers",
       "//components/url_formatter",
+      "//net",
       "//skia",
       "//ui/base/ime:text_input_types",
       "//ui/gfx/geometry",
diff --git a/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java b/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java
index 290c4dbb..3463887 100644
--- a/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java
+++ b/blimp/client/app/android/java/src/org/chromium/blimp/BlimpLibraryLoader.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.os.Handler;
 
+import org.chromium.base.ContextUtils;
 import org.chromium.base.ObserverList;
 import org.chromium.base.ResourceExtractor;
 import org.chromium.base.ThreadUtils;
@@ -90,6 +91,7 @@
         extractor.addCompletionCallback(new Runnable() {
             @Override
             public void run() {
+                ContextUtils.initApplicationContext(context.getApplicationContext());
                 new Handler().post(new Runnable() {
                     @Override
                     public void run() {
diff --git a/blimp/client/app/android/java/src/org/chromium/blimp/auth/TokenSourceImpl.java b/blimp/client/app/android/java/src/org/chromium/blimp/auth/TokenSourceImpl.java
index ca04b75..a21c9c0d 100644
--- a/blimp/client/app/android/java/src/org/chromium/blimp/auth/TokenSourceImpl.java
+++ b/blimp/client/app/android/java/src/org/chromium/blimp/auth/TokenSourceImpl.java
@@ -87,7 +87,7 @@
 
         if (accountName == null || !doesAccountExist(accountName)) {
             // Remove any old preference value in case the account is invalid.
-            preferences.edit().remove(ACCOUNT_NAME_PREF).commit();
+            preferences.edit().remove(ACCOUNT_NAME_PREF).apply();
 
             // Trigger account selection.
             mCallback.onNeedsAccountToBeSelected(getAccountChooserIntent());
@@ -130,7 +130,7 @@
 
         String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mAppContext);
-        preferences.edit().putString(ACCOUNT_NAME_PREF, accountName).commit();
+        preferences.edit().putString(ACCOUNT_NAME_PREF, accountName).apply();
     }
 
     @SuppressWarnings("deprecation")
@@ -181,4 +181,4 @@
             if (mTokenQueryTask == TokenQueryTask.this) mTokenQueryTask = null;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/blimp/client/app/blimp_startup.h b/blimp/client/app/blimp_startup.h
index b9eebce0..bd169242 100644
--- a/blimp/client/app/blimp_startup.h
+++ b/blimp/client/app/blimp_startup.h
@@ -5,14 +5,12 @@
 #ifndef BLIMP_CLIENT_APP_BLIMP_STARTUP_H_
 #define BLIMP_CLIENT_APP_BLIMP_STARTUP_H_
 
-#include "blimp/client/blimp_client_export.h"
-
 namespace blimp {
 namespace client {
 
-BLIMP_CLIENT_EXPORT void InitializeLogging();
+void InitializeLogging();
 
-BLIMP_CLIENT_EXPORT bool InitializeMainMessageLoop();
+bool InitializeMainMessageLoop();
 
 }  // namespace client
 }  // namespace blimp
diff --git a/blimp/client/blimp_client_export.h b/blimp/client/blimp_client_export.h
deleted file mode 100644
index 2ed83543..0000000
--- a/blimp/client/blimp_client_export.h
+++ /dev/null
@@ -1,29 +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 BLIMP_CLIENT_BLIMP_CLIENT_EXPORT_H_
-#define BLIMP_CLIENT_BLIMP_CLIENT_EXPORT_H_
-
-#if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(BLIMP_CLIENT_IMPLEMENTATION)
-#define BLIMP_CLIENT_EXPORT __declspec(dllexport)
-#else
-#define BLIMP_CLIENT_EXPORT __declspec(dllimport)
-#endif  // defined(BLIMP_CLIENT_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(BLIMP_CLIENT_IMPLEMENTATION)
-#define BLIMP_CLIENT_EXPORT __attribute__((visibility("default")))
-#else
-#define BLIMP_CLIENT_EXPORT
-#endif  // defined(BLIMP_CLIENT_IMPLEMENTATION)
-#endif
-
-#else  // defined(COMPONENT_BUILD)
-#define BLIMP_CLIENT_EXPORT
-#endif
-
-#endif  // BLIMP_CLIENT_BLIMP_CLIENT_EXPORT_H_
diff --git a/blimp/client/feature/compositor/blimp_compositor.h b/blimp/client/feature/compositor/blimp_compositor.h
index 76f2861..df39b0f 100644
--- a/blimp/client/feature/compositor/blimp_compositor.h
+++ b/blimp/client/feature/compositor/blimp_compositor.h
@@ -10,7 +10,6 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "blimp/client/blimp_client_export.h"
 #include "blimp/client/feature/compositor/blimp_input_manager.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_host_client.h"
@@ -85,7 +84,7 @@
 // RenderWidget, identified by a custom |render_widget_id| generated on the
 // engine. The lifetime of this compositor is controlled by its corresponding
 // RenderWidget.
-class BLIMP_CLIENT_EXPORT BlimpCompositor
+class BlimpCompositor
     : public cc::LayerTreeHostClient,
       public cc::RemoteProtoChannel,
       public BlimpInputManagerClient {
diff --git a/blimp/client/feature/ime_feature.h b/blimp/client/feature/ime_feature.h
index 0eeee823..cf29cc297 100644
--- a/blimp/client/feature/ime_feature.h
+++ b/blimp/client/feature/ime_feature.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/macros.h"
-#include "blimp/client/blimp_client_export.h"
 #include "blimp/net/blimp_message_processor.h"
 #include "ui/base/ime/text_input_type.h"
 
@@ -29,7 +28,7 @@
 // user navigates away from the currently page or the page loads for the first
 // time), ImeMessage::HIDE_IME will be sent.
 
-class BLIMP_CLIENT_EXPORT ImeFeature : public BlimpMessageProcessor {
+class ImeFeature : public BlimpMessageProcessor {
  public:
   // A delegate to be notified of text input requests.
   class Delegate {
diff --git a/blimp/client/feature/navigation_feature.h b/blimp/client/feature/navigation_feature.h
index b971bb70..224764c 100644
--- a/blimp/client/feature/navigation_feature.h
+++ b/blimp/client/feature/navigation_feature.h
@@ -10,7 +10,6 @@
 
 #include "base/containers/small_map.h"
 #include "base/macros.h"
-#include "blimp/client/blimp_client_export.h"
 #include "blimp/net/blimp_message_processor.h"
 
 class GURL;
@@ -22,7 +21,7 @@
 // Handles all incoming and outgoing protobuf messages of type
 // RenderWidget::NAVIGATION.  Delegates can be added to be notified of incoming
 // messages.
-class BLIMP_CLIENT_EXPORT NavigationFeature : public BlimpMessageProcessor {
+class NavigationFeature : public BlimpMessageProcessor {
  public:
   // A delegate to be notified of specific navigation events related to a
   // a particular tab.
diff --git a/blimp/client/feature/render_widget_feature.h b/blimp/client/feature/render_widget_feature.h
index 43c5e920..caa417a 100644
--- a/blimp/client/feature/render_widget_feature.h
+++ b/blimp/client/feature/render_widget_feature.h
@@ -12,7 +12,6 @@
 
 #include "base/containers/small_map.h"
 #include "base/macros.h"
-#include "blimp/client/blimp_client_export.h"
 #include "blimp/net/blimp_message_processor.h"
 #include "blimp/net/input_message_generator.h"
 
@@ -38,7 +37,7 @@
 // notified of incoming messages. This class automatically attaches a specific
 // id so that the engine can drop stale RenderWidget related messages after it
 // sends a RenderWidgetMessage::INITIALIZE message.
-class BLIMP_CLIENT_EXPORT RenderWidgetFeature : public BlimpMessageProcessor {
+class RenderWidgetFeature : public BlimpMessageProcessor {
  public:
   // A delegate to be notified of specific RenderWidget related incoming events.
   class RenderWidgetFeatureDelegate {
diff --git a/blimp/client/feature/settings_feature.h b/blimp/client/feature/settings_feature.h
index d9e94ef1..055a7b4c 100644
--- a/blimp/client/feature/settings_feature.h
+++ b/blimp/client/feature/settings_feature.h
@@ -6,14 +6,13 @@
 #define BLIMP_CLIENT_FEATURE_SETTINGS_FEATURE_H_
 
 #include "base/macros.h"
-#include "blimp/client/blimp_client_export.h"
 #include "blimp/net/blimp_message_processor.h"
 
 namespace blimp {
 namespace client {
 
 // The feature is used to send global settings to the engine.
-class BLIMP_CLIENT_EXPORT SettingsFeature : public BlimpMessageProcessor {
+class SettingsFeature : public BlimpMessageProcessor {
  public:
   SettingsFeature();
   ~SettingsFeature() override;
diff --git a/blimp/client/feature/tab_control_feature.h b/blimp/client/feature/tab_control_feature.h
index 0ae7481..00f21696 100644
--- a/blimp/client/feature/tab_control_feature.h
+++ b/blimp/client/feature/tab_control_feature.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "blimp/client/blimp_client_export.h"
 #include "blimp/net/blimp_message_processor.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -19,7 +18,7 @@
 namespace blimp {
 namespace client {
 
-class BLIMP_CLIENT_EXPORT TabControlFeature : public BlimpMessageProcessor {
+class TabControlFeature : public BlimpMessageProcessor {
  public:
   TabControlFeature();
   ~TabControlFeature() override;
diff --git a/blimp/client/session/assignment_source.h b/blimp/client/session/assignment_source.h
index a5ab358c..6999337 100644
--- a/blimp/client/session/assignment_source.h
+++ b/blimp/client/session/assignment_source.h
@@ -9,7 +9,6 @@
 
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
-#include "blimp/client/blimp_client_export.h"
 #include "net/base/ip_endpoint.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "url/gurl.h"
@@ -34,7 +33,7 @@
 
 // An Assignment contains the configuration data needed for a client
 // to connect to the engine.
-struct BLIMP_CLIENT_EXPORT Assignment {
+struct Assignment {
   enum TransportProtocol {
     UNKNOWN = 0,
     SSL = 1,
@@ -64,7 +63,7 @@
 
 // AssignmentSource provides functionality to find out how a client should
 // connect to an engine.
-class BLIMP_CLIENT_EXPORT AssignmentSource : public net::URLFetcherDelegate {
+class AssignmentSource : public net::URLFetcherDelegate {
  public:
   // A Java counterpart will be generated for this enum.
   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.blimp.assignment
diff --git a/blimp/client/session/blimp_client_session.h b/blimp/client/session/blimp_client_session.h
index da41761..71b4d3d 100644
--- a/blimp/client/session/blimp_client_session.h
+++ b/blimp/client/session/blimp_client_session.h
@@ -11,7 +11,6 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread.h"
-#include "blimp/client/blimp_client_export.h"
 #include "blimp/client/session/assignment_source.h"
 #include "blimp/common/proto/blimp_message.pb.h"
 #include "blimp/net/blimp_message_processor.h"
@@ -54,7 +53,7 @@
 // This session glues together the feature proxy components and the network
 // layer.  The network components must be interacted with on the IO thread.  The
 // feature proxies must be interacted with on the UI thread.
-class BLIMP_CLIENT_EXPORT BlimpClientSession : public NetworkEventObserver {
+class BlimpClientSession : public NetworkEventObserver {
  public:
   explicit BlimpClientSession(const GURL& assigner_endpoint);
 
diff --git a/blimp/common/BUILD.gn b/blimp/common/BUILD.gn
index 1790ee57..122697d 100644
--- a/blimp/common/BUILD.gn
+++ b/blimp/common/BUILD.gn
@@ -4,7 +4,8 @@
 
 import("//testing/test.gni")
 
-component("blimp_common") {
+component("common") {
+  output_name = "blimp_common"
   sources = [
     "blimp_common_export.h",
     "blob_cache/blob_cache.h",
@@ -50,8 +51,11 @@
   ]
 
   deps = [
-    ":blimp_common",
+    ":common",
+    "//base",
     "//blimp/common/proto",
+    "//blimp/net:test_support",
+    "//crypto",
     "//testing/gmock",
     "//testing/gtest",
   ]
diff --git a/blimp/docs/container.md b/blimp/docs/container.md
index 6cec582..5208806b 100644
--- a/blimp/docs/container.md
+++ b/blimp/docs/container.md
@@ -44,7 +44,7 @@
 ```bash
 ./blimp/tools/generate-engine-manifest.py \
     --build-dir out-linux/Debug \
-    --target //blimp/engine:blimp_engine \
+    --target //blimp/engine \
     --output blimp/engine/engine-manifest.txt
 ```
 
diff --git a/blimp/engine/BUILD.gn b/blimp/engine/BUILD.gn
index 21d95b0..3c9d0d79 100644
--- a/blimp/engine/BUILD.gn
+++ b/blimp/engine/BUILD.gn
@@ -53,38 +53,89 @@
     "app/blimp_content_browser_client.h",
     "app/blimp_content_main_delegate.cc",
     "app/blimp_content_main_delegate.h",
-    "app/blimp_engine_config.cc",
-    "app/blimp_engine_config.h",
-    "app/blimp_network_delegate.cc",
-    "app/blimp_network_delegate.h",
-    "app/blimp_permission_manager.cc",
-    "app/blimp_permission_manager.h",
-    "app/blimp_system_url_request_context_getter.cc",
-    "app/blimp_system_url_request_context_getter.h",
-    "app/blimp_url_request_context_getter.cc",
-    "app/blimp_url_request_context_getter.h",
-    "app/engine_settings.h",
-    "app/settings_manager.cc",
-    "app/settings_manager.h",
-    "app/switches.cc",
-    "app/switches.h",
   ]
 
   deps = [
+    ":app_config",
+    ":app_net",
+    ":app_permissions",
+    ":app_settings",
+    ":app_switches",
     ":app_ui",
     ":blob_channel",
     ":common",
     ":renderer",
     ":session",
     "//base",
+    "//blimp/common",
     "//blimp/common/proto",
-    "//components/web_cache/renderer",
-    "//content",
+    "//blimp/engine:blob_channel_mojo_cpp_sources",
+    "//blimp/net",
     "//content/public/app:both",
     "//content/public/browser",
     "//content/public/common",
     "//content/public/renderer",
     "//content/public/utility",
+    "//net",
+  ]
+}
+
+source_set("app_config") {
+  sources = [
+    "app/blimp_engine_config.cc",
+    "app/blimp_engine_config.h",
+  ]
+  deps = [
+    ":app_switches",
+    "//base",
+  ]
+}
+
+source_set("app_net") {
+  sources = [
+    "app/blimp_network_delegate.cc",
+    "app/blimp_network_delegate.h",
+    "app/blimp_system_url_request_context_getter.cc",
+    "app/blimp_system_url_request_context_getter.h",
+    "app/blimp_url_request_context_getter.cc",
+    "app/blimp_url_request_context_getter.h",
+  ]
+  deps = [
+    ":common_user_agent",
+    "//base",
+    "//content/public/browser",
+    "//net",
+  ]
+}
+
+source_set("app_permissions") {
+  sources = [
+    "app/blimp_permission_manager.cc",
+    "app/blimp_permission_manager.h",
+  ]
+  deps = [
+    "//base",
+    "//content/public/browser",
+  ]
+}
+
+source_set("app_settings") {
+  sources = [
+    "app/engine_settings.h",
+    "app/settings_manager.cc",
+    "app/settings_manager.h",
+  ]
+  deps = [
+    "//blimp/net",
+    "//content/public/browser",
+    "//content/public/common",
+  ]
+}
+
+source_set("app_switches") {
+  sources = [
+    "app/switches.cc",
+    "app/switches.h",
   ]
 }
 
@@ -101,11 +152,12 @@
   ]
 
   deps = [
-    "//blimp/common:blimp_common",
+    "//blimp/common",
     "//cc",
     "//cc/surfaces",
     "//ui/aura",
     "//ui/compositor",
+    "//ui/display",
     "//ui/events",
     "//ui/gfx",
     "//ui/platform_window",
@@ -123,10 +175,25 @@
   ]
 
   deps = [
+    ":app_net",
+    ":app_permissions",
+    ":common_user_agent",
     "//base",
+    "//content/public/browser",
+    "//content/public/common",
+    "//net",
+    "//ui/base",
+  ]
+}
+
+source_set("common_user_agent") {
+  sources = [
+    "common/blimp_user_agent.cc",
+    "common/blimp_user_agent.h",
+  ]
+  deps = [
     "//components/version_info",
     "//content/public/common",
-    "//ui/base",
   ]
 }
 
@@ -140,7 +207,14 @@
 
   deps = [
     "//base",
+    "//blimp/common",
     "//blimp/common/proto",
+    "//blimp/engine:app_settings",
+    "//blimp/engine:common",
+    "//blimp/net",
+    "//content/public/browser",
+    "//content/public/common",
+    "//net",
     "//ui/base",
     "//ui/base/ime",
     "//ui/resources",
@@ -159,9 +233,12 @@
   deps = [
     ":blob_channel_mojo",
     "//base",
-    "//blimp/common:blimp_common",
+    "//blimp/common",
     "//blimp/common/proto",
     "//cc",
+    "//components/web_cache/renderer",
+    "//content/public/common",
+    "//content/public/renderer",
     "//skia",
     "//third_party/libwebp",
     "//ui/gfx/geometry",
@@ -176,13 +253,22 @@
   ]
 
   deps = [
+    ":app_config",
+    ":app_settings",
+    ":app_switches",
+    ":app_ui",
+    ":common",
     ":feature",
     "//base",
-    "//blimp/common:blimp_common",
+    "//blimp/common",
     "//blimp/common/proto",
-    "//blimp/net:blimp_net",
-    "//content",
+    "//blimp/net",
+    "//content/public/browser",
     "//net",
+    "//ui/aura",
+    "//ui/base/ime",
+    "//ui/gfx/geometry",
+    "//ui/wm",
   ]
 }
 
@@ -214,11 +300,16 @@
 
   deps = [
     ":app",
+    ":app_config",
+    ":app_settings",
+    ":app_switches",
     "//base",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
+    "//blimp/engine:app_ui",
     "//testing/gmock",
     "//testing/gtest",
+    "//ui/display",
     "//ui/gfx:test_support",
   ]
 }
@@ -236,10 +327,18 @@
     "//base",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
+    "//blimp/common",
     "//blimp/common/proto",
-    "//content",
+    "//blimp/engine:app_settings",
+    "//blimp/net",
+    "//blimp/net:test_support",
+    "//content/public/browser",
+    "//net",
+    "//net:test_support",
     "//testing/gmock",
     "//testing/gtest",
+    "//third_party/WebKit/public:blink_headers",
+    "//ui/base/ime",
   ]
 }
 
@@ -261,12 +360,13 @@
     deps = [
       ":app",
       ":pak",
-      "//blimp/net:blimp_net",
+      "//base",
+      "//blimp/net",
       "//content/public/app:both",
     ]
   }
 
-  group("blimp_engine") {
+  group("engine") {
     deps = [
       ":blimp_engine_app",
       ":pak",
@@ -293,7 +393,7 @@
 
     # Detail the target & "source"-file dependencies, and output, for GN.
     deps = [
-      "//blimp/engine:blimp_engine",
+      "//blimp/engine",
     ]
     sources = [
       _rebased_dockerfile,
diff --git a/blimp/engine/DEPS b/blimp/engine/DEPS
index e64143af..9e550b1 100644
--- a/blimp/engine/DEPS
+++ b/blimp/engine/DEPS
@@ -13,6 +13,7 @@
   "+ui/aura",
   "+ui/base",
   "+ui/compositor",
+  "+ui/display",
   "+ui/events",
   "+ui/gfx",
   "+ui/platform_window",
diff --git a/blimp/engine/app/blimp_url_request_context_getter.cc b/blimp/engine/app/blimp_url_request_context_getter.cc
index b1c4cf9..fe5db28 100644
--- a/blimp/engine/app/blimp_url_request_context_getter.cc
+++ b/blimp/engine/app/blimp_url_request_context_getter.cc
@@ -11,7 +11,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
 #include "blimp/engine/app/blimp_network_delegate.h"
-#include "blimp/engine/common/blimp_content_client.h"
+#include "blimp/engine/common/blimp_user_agent.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/proxy/proxy_config_service.h"
 #include "net/proxy/proxy_service.h"
diff --git a/blimp/engine/app/ui/blimp_screen.cc b/blimp/engine/app/ui/blimp_screen.cc
index 9338193..b7d18b8 100644
--- a/blimp/engine/app/ui/blimp_screen.cc
+++ b/blimp/engine/app/ui/blimp_screen.cc
@@ -6,7 +6,7 @@
 
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
-#include "ui/gfx/display_observer.h"
+#include "ui/display/display_observer.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace blimp {
@@ -30,16 +30,16 @@
     return;
   }
 
-  uint32_t metrics = gfx::DisplayObserver::DISPLAY_METRIC_NONE;
+  uint32_t metrics = display::DisplayObserver::DISPLAY_METRIC_NONE;
   if (scale != display_.device_scale_factor())
-    metrics |= gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
+    metrics |= display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
 
   if (size != display_.GetSizeInPixel())
-    metrics |= gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS;
+    metrics |= display::DisplayObserver::DISPLAY_METRIC_BOUNDS;
 
   display_.SetScaleAndBounds(scale, gfx::Rect(size));
 
-  FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_,
+  FOR_EACH_OBSERVER(display::DisplayObserver, observers_,
                     OnDisplayMetricsChanged(display_, metrics));
 }
 
@@ -62,34 +62,34 @@
   return kNumDisplays;
 }
 
-std::vector<gfx::Display> BlimpScreen::GetAllDisplays() const {
-  return std::vector<gfx::Display>(1, display_);
+std::vector<display::Display> BlimpScreen::GetAllDisplays() const {
+  return std::vector<display::Display>(1, display_);
 }
 
-gfx::Display BlimpScreen::GetDisplayNearestWindow(
+display::Display BlimpScreen::GetDisplayNearestWindow(
     gfx::NativeWindow window) const {
   return display_;
 }
 
-gfx::Display BlimpScreen::GetDisplayNearestPoint(
+display::Display BlimpScreen::GetDisplayNearestPoint(
     const gfx::Point& point) const {
   return display_;
 }
 
-gfx::Display BlimpScreen::GetDisplayMatching(
+display::Display BlimpScreen::GetDisplayMatching(
     const gfx::Rect& match_rect) const {
   return display_;
 }
 
-gfx::Display BlimpScreen::GetPrimaryDisplay() const {
+display::Display BlimpScreen::GetPrimaryDisplay() const {
   return display_;
 }
 
-void BlimpScreen::AddObserver(gfx::DisplayObserver* observer) {
+void BlimpScreen::AddObserver(display::DisplayObserver* observer) {
   observers_.AddObserver(observer);
 }
 
-void BlimpScreen::RemoveObserver(gfx::DisplayObserver* observer) {
+void BlimpScreen::RemoveObserver(display::DisplayObserver* observer) {
   observers_.RemoveObserver(observer);
 }
 
diff --git a/blimp/engine/app/ui/blimp_screen.h b/blimp/engine/app/ui/blimp_screen.h
index 991a028..adf884b 100644
--- a/blimp/engine/app/ui/blimp_screen.h
+++ b/blimp/engine/app/ui/blimp_screen.h
@@ -9,8 +9,8 @@
 
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 
 namespace aura {
 class WindowTreeHost;
@@ -20,7 +20,7 @@
 namespace engine {
 
 // Presents the client's single screen.
-class BlimpScreen : public gfx::Screen {
+class BlimpScreen : public display::Screen {
  public:
   BlimpScreen();
   ~BlimpScreen() override;
@@ -32,23 +32,25 @@
   // Updates the size reported by the primary display.
   void UpdateDisplayScaleAndSize(float scale, const gfx::Size& size);
 
-  // gfx::Screen implementation.
+  // display::Screen implementation.
   gfx::Point GetCursorScreenPoint() override;
   gfx::NativeWindow GetWindowUnderCursor() override;
   gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
   int GetNumDisplays() const override;
-  std::vector<gfx::Display> GetAllDisplays() const override;
-  gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
-  gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override;
-  gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
-  gfx::Display GetPrimaryDisplay() const override;
-  void AddObserver(gfx::DisplayObserver* observer) override;
-  void RemoveObserver(gfx::DisplayObserver* observer) override;
+  std::vector<display::Display> GetAllDisplays() const override;
+  display::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
+  display::Display GetDisplayNearestPoint(
+      const gfx::Point& point) const override;
+  display::Display GetDisplayMatching(
+      const gfx::Rect& match_rect) const override;
+  display::Display GetPrimaryDisplay() const override;
+  void AddObserver(display::DisplayObserver* observer) override;
+  void RemoveObserver(display::DisplayObserver* observer) override;
 
  private:
   aura::WindowTreeHost* window_tree_host_;
-  gfx::Display display_;
-  base::ObserverList<gfx::DisplayObserver> observers_;
+  display::Display display_;
+  base::ObserverList<display::DisplayObserver> observers_;
   DISALLOW_COPY_AND_ASSIGN(BlimpScreen);
 };
 
diff --git a/blimp/engine/app/ui/blimp_screen_unittest.cc b/blimp/engine/app/ui/blimp_screen_unittest.cc
index 09244de..9753fef 100644
--- a/blimp/engine/app/ui/blimp_screen_unittest.cc
+++ b/blimp/engine/app/ui/blimp_screen_unittest.cc
@@ -16,9 +16,9 @@
 #include "blimp/engine/app/switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/display_observer.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/display_observer.h"
+#include "ui/display/screen.h"
 
 using testing::InSequence;
 
@@ -26,20 +26,20 @@
 namespace engine {
 namespace {
 
-// Checks if two gfx::Displays have the ID.
+// Checks if two display::Displays have the ID.
 MATCHER_P(EqualsDisplay, display, "") {
   return display.id() == arg.id();
 }
 
-class MockDisplayObserver : public gfx::DisplayObserver {
+class MockDisplayObserver : public display::DisplayObserver {
  public:
   MockDisplayObserver() {}
   ~MockDisplayObserver() override {}
 
-  MOCK_METHOD1(OnDisplayAdded, void(const gfx::Display&));
-  MOCK_METHOD1(OnDisplayRemoved, void(const gfx::Display&));
+  MOCK_METHOD1(OnDisplayAdded, void(const display::Display&));
+  MOCK_METHOD1(OnDisplayRemoved, void(const display::Display&));
   MOCK_METHOD2(OnDisplayMetricsChanged,
-               void(const gfx::Display& display, uint32_t changed_metrics));
+               void(const display::Display& display, uint32_t changed_metrics));
 };
 
 class BlimpScreenTest : public testing::Test {
@@ -58,8 +58,8 @@
 TEST_F(BlimpScreenTest, ObserversAreInfomed) {
   auto display = screen_->GetPrimaryDisplay();
   uint32_t changed_metrics =
-      gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR |
-      gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS;
+      display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR |
+      display::DisplayObserver::DISPLAY_METRIC_BOUNDS;
 
   InSequence s;
   EXPECT_CALL(observer1_,
@@ -67,13 +67,14 @@
   EXPECT_CALL(observer2_,
               OnDisplayMetricsChanged(EqualsDisplay(display), changed_metrics));
 
-  changed_metrics = gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS;
+  changed_metrics = display::DisplayObserver::DISPLAY_METRIC_BOUNDS;
   EXPECT_CALL(observer1_,
               OnDisplayMetricsChanged(EqualsDisplay(display), changed_metrics));
   EXPECT_CALL(observer2_,
               OnDisplayMetricsChanged(EqualsDisplay(display), changed_metrics));
 
-  changed_metrics = gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
+  changed_metrics =
+      display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
   EXPECT_CALL(observer1_,
               OnDisplayMetricsChanged(EqualsDisplay(display), changed_metrics));
   EXPECT_CALL(observer2_,
@@ -99,8 +100,8 @@
   screen_->RemoveObserver(&observer2_);
   auto display = screen_->GetPrimaryDisplay();
   uint32_t changed_metrics =
-      gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR |
-      gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS;
+      display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR |
+      display::DisplayObserver::DISPLAY_METRIC_BOUNDS;
   EXPECT_CALL(observer1_,
               OnDisplayMetricsChanged(EqualsDisplay(display), changed_metrics));
 
diff --git a/blimp/engine/common/blimp_content_client.cc b/blimp/engine/common/blimp_content_client.cc
index cc57be1..a234adb 100644
--- a/blimp/engine/common/blimp_content_client.cc
+++ b/blimp/engine/common/blimp_content_client.cc
@@ -4,26 +4,12 @@
 
 #include "blimp/engine/common/blimp_content_client.h"
 
-#include "components/version_info/version_info.h"
-#include "content/public/common/user_agent.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
 namespace blimp {
 namespace engine {
 
-std::string client_os_info = "Linux; Android 5.1.1";
-
-std::string GetBlimpEngineUserAgent() {
-  return content::BuildUserAgentFromOSAndProduct(
-      client_os_info,
-      version_info::GetProductNameAndVersionForUserAgent() + " Mobile");
-}
-
-void SetClientOSInfo(std::string os_version_info) {
-  client_os_info = os_version_info;
-}
-
 BlimpContentClient::~BlimpContentClient() {}
 
 std::string BlimpContentClient::GetUserAgent() const {
diff --git a/blimp/engine/common/blimp_user_agent.cc b/blimp/engine/common/blimp_user_agent.cc
new file mode 100644
index 0000000..85182e0
--- /dev/null
+++ b/blimp/engine/common/blimp_user_agent.cc
@@ -0,0 +1,32 @@
+// 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 "blimp/engine/common/blimp_user_agent.h"
+
+#include <string>
+
+#include "components/version_info/version_info.h"
+#include "content/public/common/user_agent.h"
+
+namespace blimp {
+namespace engine {
+
+namespace {
+
+std::string client_os_info = "Linux; Android 5.1.1";
+
+}  // namespace
+
+std::string GetBlimpEngineUserAgent() {
+  return content::BuildUserAgentFromOSAndProduct(
+      client_os_info,
+      version_info::GetProductNameAndVersionForUserAgent() + " Mobile");
+}
+
+void SetClientOSInfo(std::string os_version_info) {
+  client_os_info = os_version_info;
+}
+
+}  // namespace engine
+}  // namespace blimp
diff --git a/blimp/engine/common/blimp_user_agent.h b/blimp/engine/common/blimp_user_agent.h
new file mode 100644
index 0000000..e64af88
--- /dev/null
+++ b/blimp/engine/common/blimp_user_agent.h
@@ -0,0 +1,21 @@
+// 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 BLIMP_ENGINE_COMMON_BLIMP_USER_AGENT_H_
+#define BLIMP_ENGINE_COMMON_BLIMP_USER_AGENT_H_
+
+#include <string>
+
+#include "content/public/common/content_client.h"
+
+namespace blimp {
+namespace engine {
+
+std::string GetBlimpEngineUserAgent();
+void SetClientOSInfo(std::string client_os_info);
+
+}  // namespace engine
+}  // namespace blimp
+
+#endif  // BLIMP_ENGINE_COMMON_BLIMP_USER_AGENT_H_
diff --git a/blimp/engine/engine-manifest.txt b/blimp/engine/engine-manifest.txt
index 285e9c2..8943ec4 100644
--- a/blimp/engine/engine-manifest.txt
+++ b/blimp/engine/engine-manifest.txt
@@ -1,7 +1,7 @@
 # Runtime dependencies for the Blimp Engine
 #
 # This file was generated by running:
-# generate-engine-manifest.py --build-dir out-chromeos/Debug --target //blimp/engine:blimp_engine --output blimp/engine/engine-manifest.txt
+# generate-engine-manifest.py --build-dir out-chromeos/Debug --target //blimp/engine --output blimp/engine/engine-manifest.txt
 #
 # Note: Any unnecessary dependencies should be added to
 #       manifest-blacklist.txt and this file should be regenerated.
@@ -214,4 +214,4 @@
 gen/third_party/blimp_fonts/RobotoCondensed-Light.ttf
 gen/third_party/blimp_fonts/RobotoCondensed-LightItalic.ttf
 gen/third_party/blimp_fonts/RobotoCondensed-Regular.ttf
-gen/third_party/blimp_fonts/fonts.xml
\ No newline at end of file
+gen/third_party/blimp_fonts/fonts.xml
diff --git a/blimp/engine/session/blimp_engine_session.cc b/blimp/engine/session/blimp_engine_session.cc
index dc30c45..3bf2109 100644
--- a/blimp/engine/session/blimp_engine_session.cc
+++ b/blimp/engine/session/blimp_engine_session.cc
@@ -234,8 +234,8 @@
 }
 
 void BlimpEngineSession::Initialize() {
-  DCHECK(!gfx::Screen::GetScreen());
-  gfx::Screen::SetScreenInstance(screen_.get());
+  DCHECK(!display::Screen::GetScreen());
+  display::Screen::SetScreenInstance(screen_.get());
 
   window_tree_host_.reset(new BlimpWindowTreeHost());
 
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn
index 16017b0..0b722be 100644
--- a/blimp/net/BUILD.gn
+++ b/blimp/net/BUILD.gn
@@ -2,7 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-component("blimp_net") {
+component("net") {
+  output_name = "blimp_net"
   sources = [
     "blimp_connection.cc",
     "blimp_connection.h",
@@ -66,9 +67,10 @@
 
   deps = [
     "//base",
-    "//blimp/common:blimp_common",
+    "//blimp/common",
     "//blimp/common/proto",
     "//net",
+    "//third_party/WebKit/public:blink_headers",
     "//third_party/zlib",
     "//ui/base/ime:text_input_types",
   ]
@@ -83,7 +85,7 @@
   ]
 
   deps = [
-    ":blimp_net",
+    ":net",
     "//blimp/common/proto",
     "//net:test_support",
     "//testing/gmock",
@@ -115,15 +117,16 @@
   ]
 
   deps = [
-    ":blimp_net",
+    ":net",
     ":test_support",
     "//base",
     "//base/test:run_all_unittests",
     "//base/test:test_support",
-    "//blimp/common:blimp_common",
+    "//blimp/common",
     "//blimp/common/proto",
     "//net:test_support",
     "//testing/gmock",
     "//testing/gtest",
+    "//third_party/WebKit/public:blink_headers",
   ]
 }
diff --git a/build/all.gyp b/build/all.gyp
index b18497f..6f71d1d3 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -418,6 +418,11 @@
                 },
               }
             }],
+            ['component!="shared_library" or target_arch!="ia32"', {
+              'dependencies': [
+                '../chrome/installer/mini_installer.gyp:next_version_mini_installer',
+              ],
+            }],
           ],
         }],
         ['chromeos==1', {
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn
index 2375a28..9ee562c 100644
--- a/build/android/BUILD.gn
+++ b/build/android/BUILD.gn
@@ -101,6 +101,7 @@
            "//third_party/android_tools/sdk/platform-tools/adb",
            "//third_party/catapult/third_party/gsutil/",
            "//third_party/catapult/devil/devil/devil_dependencies.json",
+           "//third_party/proguard/lib/proguard.jar",
          ]
   data_deps = [
     "//tools/swarming_client:isolate_py",
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
index 91c98d3..c80ba7f4 100644
--- a/build/android/pylib/gtest/gtest_config.py
+++ b/build/android/pylib/gtest/gtest_config.py
@@ -49,5 +49,9 @@
 # http://crbug.com/344868
 ASAN_EXCLUDED_TEST_SUITES = [
     'breakpad_unittests',
-    'sandbox_linux_unittests'
+    'sandbox_linux_unittests',
+
+    # The internal ASAN recipe cannot run step "unit_tests_apk", this is the
+    # only internal recipe affected. See http://crbug.com/607850
+    'unit_tests_apk',
 ]
diff --git a/build/android/resource_sizes.py b/build/android/resource_sizes.py
index 936443a9..83542d35 100755
--- a/build/android/resource_sizes.py
+++ b/build/android/resource_sizes.py
@@ -11,6 +11,7 @@
 
 import collections
 import json
+import logging
 import operator
 import optparse
 import os
@@ -408,6 +409,7 @@
 
   if chartjson:
     results_path = os.path.join(options.output_dir, 'results-chart.json')
+    logging.critical('Dumping json to %s', results_path)
     with open(results_path, 'w') as json_file:
       json.dump(chartjson, json_file)
 
diff --git a/build/common.gypi b/build/common.gypi
index 3ca0957..d7d25e0 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -3908,6 +3908,12 @@
               ['_toolset=="target"', {
                 'conditions': [
                   ['clang==0', {
+                    'cflags': [
+                      # Don't warn about "maybe" uninitialized. Clang doesn't
+                      # include this in -Wall but gcc does, and it gives false
+                      # positives.
+                      '-Wno-maybe-uninitialized',
+                    ],
                     'cflags_cc': [
                       # The codesourcery arm-2009q3 toolchain warns at that the ABI
                       # has changed whenever it encounters a varargs function. This
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index c36aeab..92d0b6e 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -458,7 +458,6 @@
   "//build/config/compiler:no_rtti",
   "//build/config/compiler:runtime_library",
   "//build/config/sanitizers:default_sanitizer_flags",
-  "//build/config/sanitizers:default_sanitizer_coverage_flags",
 ]
 if (is_win) {
   _native_compiler_configs += [
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 81267ed..cf958ef 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1593,6 +1593,9 @@
         depfile,
         "${_dist_ijar_path}",
       ]
+      data = [
+        _dist_ijar_path,
+      ]
       args = [
         "--depfile",
         rebase_path(depfile, root_build_dir),
@@ -2049,6 +2052,17 @@
     if (defined(invoker.apk_under_test)) {
       public_deps += [ invoker.apk_under_test ]
     }
+    if (defined(invoker.isolate_file)) {
+      isolate_values = exec_script("//build/gypi_to_gn.py",
+                                   [
+                                     rebase_path(invoker.isolate_file),
+                                     "--replace",
+                                     "<(DEPTH)=/",
+                                   ],
+                                   "scope",
+                                   [ invoker.isolate_file ])
+      data = isolate_values.files
+    }
   }
 
   # TODO(GYP): Delete once recipes no longer use this target.
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 3ee4412..ed5263ab 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -914,6 +914,10 @@
       # for gcc 4.8.
       # TODO: remove this flag once all builds work. See crbug.com/227506
       cflags += [ "-Wno-unused-local-typedefs" ]
+
+      # Don't warn about "maybe" uninitialized. Clang doesn't include this
+      # in -Wall but gcc does, and it gives false positives.
+      cflags += [ "-Wno-maybe-uninitialized" ]
     }
   }
 
diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni
index 9aa1f92..2105afa7 100644
--- a/build/config/mac/rules.gni
+++ b/build/config/mac/rules.gni
@@ -59,8 +59,10 @@
     ibtool_flags = [
       "--minimum-deployment-target",
       mac_deployment_target,
-      "--target-device",
-      "mac",
+
+      # TODO(rsesek): Enable this once all the bots are on Xcode 7+.
+      # "--target-device",
+      # "mac",
     ]
   }
 
diff --git a/build/config/mac/xcrun.py b/build/config/mac/xcrun.py
new file mode 100644
index 0000000..e2a775e5
--- /dev/null
+++ b/build/config/mac/xcrun.py
@@ -0,0 +1,23 @@
+# 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 argparse
+import os
+import subprocess
+import sys
+
+if __name__ == '__main__':
+  parser = argparse.ArgumentParser(
+      description='A script to execute a command via xcrun.')
+  parser.add_argument('--stamp', action='store', type=str,
+      help='Write a stamp file to this path on success.')
+  args, unknown_args = parser.parse_known_args()
+
+  rv = subprocess.check_call(['xcrun'] + unknown_args)
+  if rv == 0 and args.stamp:
+    if os.path.exists(args.stamp):
+      os.unlink(args.stamp)
+    open(args.stamp, 'w+').close()
+
+  sys.exit(rv)
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
index ea010b32..8c357cb 100644
--- a/build/config/sanitizers/BUILD.gn
+++ b/build/config/sanitizers/BUILD.gn
@@ -67,7 +67,6 @@
   # the sanitizer runtimes, so instrumenting these functions could cause
   # recursive calls into the runtime if there is an error.
   configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
-  configs -= [ "//build/config/sanitizers:default_sanitizer_coverage_flags" ]
 
   if (is_asan) {
     sources += [ "//build/sanitizers/asan_suppressions.cc" ]
@@ -234,6 +233,26 @@
   }
 }
 
+config("coverage_flags") {
+  cflags = []
+
+  if (use_sanitizer_coverage) {
+    cflags += [
+      "-fsanitize-coverage=$sanitizer_coverage_flags",
+      "-mllvm",
+      "-sanitizer-coverage-prune-blocks=1",
+    ]
+    if (target_cpu == "arm") {
+      # http://crbug.com/517105
+      cflags += [
+        "-mllvm",
+        "-sanitizer-coverage-block-threshold=0",
+      ]
+    }
+    defines = [ "SANITIZER_COVERAGE" ]
+  }
+}
+
 config("lsan_flags") {
   if (is_lsan) {
     cflags = [ "-fsanitize=leak" ]
@@ -328,6 +347,20 @@
   }
 }
 
+all_sanitizer_configs = [
+  ":common_sanitizer_flags",
+  ":coverage_flags",
+  ":default_sanitizer_ldflags",
+  ":asan_flags",
+  ":cfi_flags",
+  ":lsan_flags",
+  ":msan_flags",
+  ":tsan_flags",
+  ":ubsan_flags",
+  ":ubsan_security_flags",
+  ":ubsan_vptr_flags",
+]
+
 # This config is applied by default to all targets. It sets the compiler flags
 # for sanitizer usage, or, if no sanitizer is set, does nothing.
 #
@@ -337,18 +370,7 @@
 # :deps if any of their dependencies have not opted out of sanitizers.
 # Keep this list in sync with default_sanitizer_flags_but_ubsan_vptr.
 config("default_sanitizer_flags") {
-  configs = [
-    ":common_sanitizer_flags",
-    ":default_sanitizer_ldflags",
-    ":asan_flags",
-    ":cfi_flags",
-    ":lsan_flags",
-    ":msan_flags",
-    ":tsan_flags",
-    ":ubsan_flags",
-    ":ubsan_security_flags",
-    ":ubsan_vptr_flags",
-  ]
+  configs = all_sanitizer_configs
 }
 
 # This config is equivalent to default_sanitizer_flags, but excludes ubsan_vptr.
@@ -356,35 +378,9 @@
 # if some third_party code is required to be compiled without rtti, which
 # is a requirement for ubsan_vptr.
 config("default_sanitizer_flags_but_ubsan_vptr") {
-  configs = [
-    ":common_sanitizer_flags",
-    ":default_sanitizer_ldflags",
-    ":asan_flags",
-    ":cfi_flags",
-    ":lsan_flags",
-    ":msan_flags",
-    ":tsan_flags",
-    ":ubsan_flags",
-    ":ubsan_security_flags",
-  ]
+  configs = all_sanitizer_configs - [ ":ubsan_vptr_flags" ]
 }
 
-config("default_sanitizer_coverage_flags") {
-  cflags = []
-
-  if (use_sanitizer_coverage) {
-    cflags += [
-      "-fsanitize-coverage=$sanitizer_coverage_flags",
-      "-mllvm",
-      "-sanitizer-coverage-prune-blocks=1",
-    ]
-    if (target_cpu == "arm") {
-      # http://crbug.com/517105
-      cflags += [
-        "-mllvm",
-        "-sanitizer-coverage-block-threshold=0",
-      ]
-    }
-    defines = [ "SANITIZER_COVERAGE" ]
-  }
+config("default_sanitizer_flags_but_coverage") {
+  configs = all_sanitizer_configs - [ ":coverage_flags" ]
 }
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index bfa69be..2aab53d 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -308,7 +308,8 @@
 # https://crbug.com/595702.  Disable incremental linking with clang for now.
 # TODO(thakis): Remove this once that problem is fixed, or when the win_clang
 # bot uses lld.
-if (is_debug && !is_clang) {
+# Disable incremental linking for syzyasan
+if (is_debug && !is_clang && !is_syzyasan) {
   default_incremental_linking_switch = incremental_linking_on_switch
 } else {
   default_incremental_linking_switch = incremental_linking_off_switch
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 534b9e2..8fa60324 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -536,6 +536,13 @@
             '../third_party/codesighs/codesighs.gyp:msmap2tsv',
             '../third_party/pdfium/samples/samples.gyp:pdfium_diff',
           ],
+          'conditions': [
+            ['component!="shared_library" or target_arch!="ia32"', {
+              'dependencies': [
+                '../chrome/installer/mini_installer.gyp:next_version_mini_installer',
+              ],
+            }],
+          ],
         }],
         ['chromecast==1', {
           'dependencies': [
@@ -635,6 +642,15 @@
                 '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests_run',
               ],
             }],
+            ['OS!="android" and OS!="ios" and chromecast==0', {
+              'dependencies': [
+                '../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests_run',
+                '../mojo/mojo_edk_tests.gyp:mojo_js_unittests_run',
+                '../mojo/mojo_edk_tests.gyp:mojo_js_integration_tests_run',
+                '../mojo/mojo_edk_tests.gyp:mojo_system_unittests_run',
+                '../services/shell/shell.gyp:mojo_shell_unittests_run',
+              ],
+            }],
             ['use_ash==1', {
               'dependencies': [
                 '../ash/ash.gyp:ash_unittests_run',
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 0d35c955..cf4cd6a2 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -351,16 +351,18 @@
     "quads/tile_draw_quad.h",
     "quads/yuv_video_draw_quad.cc",
     "quads/yuv_video_draw_quad.h",
-    "raster/bitmap_tile_task_worker_pool.cc",
-    "raster/bitmap_tile_task_worker_pool.h",
+    "raster/bitmap_raster_buffer_provider.cc",
+    "raster/bitmap_raster_buffer_provider.h",
+    "raster/gpu_raster_buffer_provider.cc",
+    "raster/gpu_raster_buffer_provider.h",
     "raster/gpu_rasterizer.cc",
     "raster/gpu_rasterizer.h",
-    "raster/gpu_tile_task_worker_pool.cc",
-    "raster/gpu_tile_task_worker_pool.h",
-    "raster/one_copy_tile_task_worker_pool.cc",
-    "raster/one_copy_tile_task_worker_pool.h",
+    "raster/one_copy_raster_buffer_provider.cc",
+    "raster/one_copy_raster_buffer_provider.h",
     "raster/raster_buffer.cc",
     "raster/raster_buffer.h",
+    "raster/raster_buffer_provider.cc",
+    "raster/raster_buffer_provider.h",
     "raster/scoped_gpu_raster.cc",
     "raster/scoped_gpu_raster.h",
     "raster/single_thread_task_graph_runner.cc",
@@ -381,10 +383,8 @@
     "raster/texture_compressor_etc1.h",
     "raster/tile_task.cc",
     "raster/tile_task.h",
-    "raster/tile_task_worker_pool.cc",
-    "raster/tile_task_worker_pool.h",
-    "raster/zero_copy_tile_task_worker_pool.cc",
-    "raster/zero_copy_tile_task_worker_pool.h",
+    "raster/zero_copy_raster_buffer_provider.cc",
+    "raster/zero_copy_raster_buffer_provider.h",
     "resources/memory_history.cc",
     "resources/memory_history.h",
     "resources/platform_color.h",
@@ -465,6 +465,8 @@
     "tiles/tile_manager.h",
     "tiles/tile_priority.cc",
     "tiles/tile_priority.h",
+    "tiles/tile_task_manager.cc",
+    "tiles/tile_task_manager.h",
     "tiles/tiling_set_eviction_queue.cc",
     "tiles/tiling_set_eviction_queue.h",
     "tiles/tiling_set_raster_queue_all.cc",
@@ -618,6 +620,8 @@
     "test/fake_picture_layer_tiling_client.h",
     "test/fake_proxy.cc",
     "test/fake_proxy.h",
+    "test/fake_raster_buffer_provider.cc",
+    "test/fake_raster_buffer_provider.h",
     "test/fake_raster_source.cc",
     "test/fake_raster_source.h",
     "test/fake_recording_source.cc",
@@ -634,6 +638,8 @@
     "test/fake_tile_manager.h",
     "test/fake_tile_manager_client.cc",
     "test/fake_tile_manager_client.h",
+    "test/fake_tile_task_manager.cc",
+    "test/fake_tile_task_manager.h",
     "test/fake_ui_resource_layer_tree_host_impl.cc",
     "test/fake_ui_resource_layer_tree_host_impl.h",
     "test/fake_video_frame_provider.cc",
@@ -845,11 +851,11 @@
     "quads/draw_polygon_unittest.cc",
     "quads/draw_quad_unittest.cc",
     "quads/render_pass_unittest.cc",
+    "raster/raster_buffer_provider_unittest.cc",
     "raster/scoped_gpu_raster_unittest.cc",
     "raster/single_thread_task_graph_runner_unittest.cc",
     "raster/synchronous_task_graph_runner_unittest.cc",
     "raster/texture_compressor_etc1_unittest.cc",
-    "raster/tile_task_worker_pool_unittest.cc",
     "resources/platform_color_unittest.cc",
     "resources/resource_pool_unittest.cc",
     "resources/resource_provider_unittest.cc",
@@ -963,9 +969,9 @@
     "layers/layer_perftest.cc",
     "layers/picture_layer_impl_perftest.cc",
     "quads/draw_quad_perftest.cc",
+    "raster/raster_buffer_provider_perftest.cc",
     "raster/task_graph_runner_perftest.cc",
     "raster/texture_compressor_perftest.cc",
-    "raster/tile_task_worker_pool_perftest.cc",
     "surfaces/surface_aggregator_perftest.cc",
     "test/cc_test_suite.cc",
     "test/run_all_perftests.cc",
diff --git a/cc/cc.gyp b/cc/cc.gyp
index f4a0991..b3b0e78 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -412,16 +412,18 @@
         'quads/tile_draw_quad.h',
         'quads/yuv_video_draw_quad.cc',
         'quads/yuv_video_draw_quad.h',
-        'raster/bitmap_tile_task_worker_pool.cc',
-        'raster/bitmap_tile_task_worker_pool.h',
+        'raster/bitmap_raster_buffer_provider.cc',
+        'raster/bitmap_raster_buffer_provider.h',
+        'raster/gpu_raster_buffer_provider.cc',
+        'raster/gpu_raster_buffer_provider.h',
         'raster/gpu_rasterizer.cc',
         'raster/gpu_rasterizer.h',
-        'raster/gpu_tile_task_worker_pool.cc',
-        'raster/gpu_tile_task_worker_pool.h',
-        'raster/one_copy_tile_task_worker_pool.cc',
-        'raster/one_copy_tile_task_worker_pool.h',
+        'raster/one_copy_raster_buffer_provider.cc',
+        'raster/one_copy_raster_buffer_provider.h',
         'raster/raster_buffer.cc',
         'raster/raster_buffer.h',
+        'raster/raster_buffer_provider.cc',
+        'raster/raster_buffer_provider.h',
         'raster/scoped_gpu_raster.cc',
         'raster/scoped_gpu_raster.h',
         'raster/single_thread_task_graph_runner.cc',
@@ -442,10 +444,8 @@
         'raster/texture_compressor_etc1.h',
         'raster/tile_task.cc',
         'raster/tile_task.h',
-        'raster/tile_task_worker_pool.cc',
-        'raster/tile_task_worker_pool.h',
-        'raster/zero_copy_tile_task_worker_pool.cc',
-        'raster/zero_copy_tile_task_worker_pool.h',
+        'raster/zero_copy_raster_buffer_provider.cc',
+        'raster/zero_copy_raster_buffer_provider.h',
         'resources/memory_history.cc',
         'resources/memory_history.h',
         'resources/platform_color.h',
@@ -526,6 +526,8 @@
         'tiles/tile_manager.h',
         'tiles/tile_priority.cc',
         'tiles/tile_priority.h',
+        'tiles/tile_task_manager.cc',
+        'tiles/tile_task_manager.h',
         'tiles/tiling_set_eviction_queue.cc',
         'tiles/tiling_set_eviction_queue.h',
         'tiles/tiling_set_raster_queue_all.cc',
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index d9c2fea..06d2f9e 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -94,11 +94,11 @@
       'quads/draw_polygon_unittest.cc',
       'quads/draw_quad_unittest.cc',
       'quads/render_pass_unittest.cc',
+      'raster/raster_buffer_provider_unittest.cc',
       'raster/scoped_gpu_raster_unittest.cc',
       'raster/single_thread_task_graph_runner_unittest.cc',
       'raster/synchronous_task_graph_runner_unittest.cc',
       'raster/texture_compressor_etc1_unittest.cc',
-      'raster/tile_task_worker_pool_unittest.cc',
       'resources/platform_color_unittest.cc',
       'resources/resource_pool_unittest.cc',
       'resources/resource_provider_unittest.cc',
@@ -211,6 +211,8 @@
       'test/fake_picture_layer_tiling_client.h',
       'test/fake_proxy.cc',
       'test/fake_proxy.h',
+      'test/fake_raster_buffer_provider.cc',
+      'test/fake_raster_buffer_provider.h',
       'test/fake_raster_source.cc',
       'test/fake_raster_source.h',
       'test/fake_recording_source.cc',
@@ -227,6 +229,8 @@
       'test/fake_tile_manager.h',
       'test/fake_tile_manager_client.cc',
       'test/fake_tile_manager_client.h',
+      'test/fake_tile_task_manager.cc',
+      'test/fake_tile_task_manager.h',
       'test/fake_ui_resource_layer_tree_host_impl.cc',
       'test/fake_ui_resource_layer_tree_host_impl.h',
       'test/fake_video_frame_provider.cc',
@@ -378,9 +382,9 @@
         'layers/layer_perftest.cc',
         'layers/picture_layer_impl_perftest.cc',
         'quads/draw_quad_perftest.cc',
+        'raster/raster_buffer_provider_perftest.cc',
         'raster/task_graph_runner_perftest.cc',
         'raster/texture_compressor_perftest.cc',
-        'raster/tile_task_worker_pool_perftest.cc',
         'surfaces/surface_aggregator_perftest.cc',
         'test/cc_test_suite.cc',
         'test/run_all_perftests.cc',
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc
index 7264d5c..2ba74e3 100644
--- a/cc/debug/rasterize_and_record_benchmark_impl.cc
+++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -13,7 +13,7 @@
 #include "cc/debug/lap_timer.h"
 #include "cc/layers/layer_impl.h"
 #include "cc/layers/picture_layer_impl.h"
-#include "cc/raster/tile_task_worker_pool.h"
+#include "cc/raster/raster_buffer_provider.h"
 #include "cc/trees/layer_tree_host_common.h"
 #include "cc/trees/layer_tree_host_impl.h"
 #include "cc/trees/layer_tree_impl.h"
diff --git a/cc/layers/layer_iterator_unittest.cc b/cc/layers/layer_iterator_unittest.cc
index 9c23d32..3e8cb099 100644
--- a/cc/layers/layer_iterator_unittest.cc
+++ b/cc/layers/layer_iterator_unittest.cc
@@ -141,7 +141,7 @@
   LayerImplList render_surface_layer_list;
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_ptr, root_ptr->bounds(), &render_surface_layer_list);
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   IterateFrontToBack(&render_surface_layer_list);
   EXPECT_COUNT(root_ptr, 5, -1, 4);
@@ -186,7 +186,7 @@
   LayerImplList render_surface_layer_list;
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_ptr, root_ptr->bounds(), &render_surface_layer_list);
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   IterateFrontToBack(&render_surface_layer_list);
   EXPECT_COUNT(root_ptr, 9, -1, 8);
@@ -239,7 +239,7 @@
   LayerImplList render_surface_layer_list;
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_ptr, root_ptr->bounds(), &render_surface_layer_list);
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   IterateFrontToBack(&render_surface_layer_list);
   EXPECT_COUNT(root_ptr, 14, -1, 13);
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc
index 104d8e618..c142cfa 100644
--- a/cc/layers/layer_position_constraint_unittest.cc
+++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -54,7 +54,7 @@
       root_layer->layer_tree_impl()->InnerViewportScrollLayer();
   inputs.outer_viewport_scroll_layer =
       root_layer->layer_tree_impl()->OuterViewportScrollLayer();
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 }
 
 class LayerPositionConstraintTest : public testing::Test {
diff --git a/cc/layers/texture_layer.cc b/cc/layers/texture_layer.cc
index b5b3173..eab540e 100644
--- a/cc/layers/texture_layer.cc
+++ b/cc/layers/texture_layer.cc
@@ -154,26 +154,6 @@
                             requires_commit, allow_mailbox_reuse);
 }
 
-static void IgnoreReleaseCallback(const gpu::SyncToken& sync_token, bool lost) {
-}
-
-void TextureLayer::SetTextureMailboxWithoutReleaseCallback(
-    const TextureMailbox& mailbox) {
-  // We allow reuse of the mailbox if there is a new sync point signalling new
-  // content, and the release callback goes nowhere since we'll be calling it
-  // multiple times for the same mailbox.
-  DCHECK(!mailbox.IsValid() || !holder_ref_ ||
-         !mailbox.Equals(holder_ref_->holder()->mailbox()) ||
-         mailbox.sync_token() != holder_ref_->holder()->mailbox().sync_token());
-  std::unique_ptr<SingleReleaseCallback> release;
-  bool requires_commit = true;
-  bool allow_mailbox_reuse = true;
-  if (mailbox.IsValid())
-    release = SingleReleaseCallback::Create(base::Bind(&IgnoreReleaseCallback));
-  SetTextureMailboxInternal(mailbox, std::move(release), requires_commit,
-                            allow_mailbox_reuse);
-}
-
 void TextureLayer::SetNeedsDisplayRect(const gfx::Rect& dirty_rect) {
   Layer::SetNeedsDisplayRect(dirty_rect);
 }
diff --git a/cc/layers/texture_layer.h b/cc/layers/texture_layer.h
index 4fa239f83..2d5b6bb 100644
--- a/cc/layers/texture_layer.h
+++ b/cc/layers/texture_layer.h
@@ -133,12 +133,6 @@
       const TextureMailbox& mailbox,
       std::unique_ptr<SingleReleaseCallback> release_callback);
 
-  // Use this for special cases where the same texture is used to back the
-  // TextureLayer across all frames.
-  // WARNING: DON'T ACTUALLY USE THIS WHAT YOU ARE DOING IS WRONG.
-  // TODO(danakj): Remove this when pepper doesn't need it. crbug.com/350204
-  void SetTextureMailboxWithoutReleaseCallback(const TextureMailbox& mailbox);
-
   void SetNeedsDisplayRect(const gfx::Rect& dirty_rect) override;
 
   void SetLayerTreeHost(LayerTreeHost* layer_tree_host) override;
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 3f35427..bc139cd 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -332,33 +332,6 @@
       SingleReleaseCallback::Create(test_data_.release_mailbox1_));
 }
 
-TEST_F(TextureLayerTest, SetTextureMailboxWithoutReleaseCallback) {
-  scoped_refptr<TextureLayer> test_layer =
-      TextureLayer::CreateForMailbox(nullptr);
-  ASSERT_TRUE(test_layer.get());
-
-  // These use the same gpu::Mailbox, but different sync points.
-  TextureMailbox mailbox1(MailboxFromChar('a'), SyncTokenFromUInt(1),
-                          GL_TEXTURE_2D);
-  TextureMailbox mailbox2(MailboxFromChar('a'), SyncTokenFromUInt(2),
-                          GL_TEXTURE_2D);
-
-  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber());
-  layer_tree_host_->SetRootLayer(test_layer);
-  Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
-  // Set the mailbox the first time. It should cause a commit.
-  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
-  test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox1);
-  Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-
-  // Set the mailbox again with a new sync point, as the backing texture has
-  // been updated. It should cause a new commit.
-  EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1));
-  test_layer->SetTextureMailboxWithoutReleaseCallback(mailbox2);
-  Mock::VerifyAndClearExpectations(layer_tree_host_.get());
-}
-
 class TextureLayerMailboxHolderTest : public TextureLayerTest {
  public:
   TextureLayerMailboxHolderTest()
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index 70a6578..1025ace 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
-#include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "cc/base/math_util.h"
 #include "cc/output/compositor_frame_metadata.h"
@@ -1880,89 +1879,6 @@
   renderer_->SwapBuffers(CompositorFrameMetadata());
 }
 
-class GLRendererTestSyncPoint : public GLRendererPixelTest {
- protected:
-  static void SyncTokenCallback(int* callback_count) {
-    ++(*callback_count);
-    base::MessageLoop::current()->QuitWhenIdle();
-  }
-
-  static void OtherCallback(int* callback_count) {
-    ++(*callback_count);
-    base::MessageLoop::current()->QuitWhenIdle();
-  }
-};
-
-#if !defined(OS_ANDROID)
-TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
-  int sync_token_callback_count = 0;
-  int other_callback_count = 0;
-  gpu::gles2::GLES2Interface* gl =
-      output_surface_->context_provider()->ContextGL();
-  gpu::ContextSupport* context_support =
-      output_surface_->context_provider()->ContextSupport();
-
-  const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
-  gl->ShallowFlushCHROMIUM();
-
-  gpu::SyncToken sync_token;
-  gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
-
-  gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
-                          GL_INNOCENT_CONTEXT_RESET_ARB);
-
-  context_support->SignalSyncToken(
-      sync_token, base::Bind(&SyncTokenCallback, &sync_token_callback_count));
-  EXPECT_EQ(0, sync_token_callback_count);
-  EXPECT_EQ(0, other_callback_count);
-
-  // Make the sync point happen.
-  gl->Finish();
-  // Post a task after the sync point.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
-
-  base::MessageLoop::current()->Run();
-
-  // The sync point shouldn't have happened since the context was lost.
-  EXPECT_EQ(0, sync_token_callback_count);
-  EXPECT_EQ(1, other_callback_count);
-}
-
-TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
-  int sync_token_callback_count = 0;
-  int other_callback_count = 0;
-
-  gpu::gles2::GLES2Interface* gl =
-      output_surface_->context_provider()->ContextGL();
-  gpu::ContextSupport* context_support =
-      output_surface_->context_provider()->ContextSupport();
-
-  const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
-  gl->ShallowFlushCHROMIUM();
-
-  gpu::SyncToken sync_token;
-  gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
-
-  context_support->SignalSyncToken(
-      sync_token, base::Bind(&SyncTokenCallback, &sync_token_callback_count));
-  EXPECT_EQ(0, sync_token_callback_count);
-  EXPECT_EQ(0, other_callback_count);
-
-  // Make the sync point happen.
-  gl->Finish();
-  // Post a task after the sync point.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
-
-  base::MessageLoop::current()->Run();
-
-  // The sync point should have happened.
-  EXPECT_EQ(1, sync_token_callback_count);
-  EXPECT_EQ(1, other_callback_count);
-}
-#endif  // OS_ANDROID
-
 class TestOverlayProcessor : public OverlayProcessor {
  public:
   class Strategy : public OverlayProcessor::Strategy {
diff --git a/cc/output/program_binding.cc b/cc/output/program_binding.cc
index c05447c7..7f6bf17 100644
--- a/cc/output/program_binding.cc
+++ b/cc/output/program_binding.cc
@@ -88,7 +88,7 @@
       shader_source_str,
       shader_length);
   context->CompileShader(shader);
-#ifndef NDEBUG
+#if DCHECK_IS_ON()
   int compiled = 0;
   context->GetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
   if (!compiled)
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc
new file mode 100644
index 0000000..b148860b
--- /dev/null
+++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -0,0 +1,112 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/raster/bitmap_raster_buffer_provider.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <algorithm>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "cc/debug/traced_value.h"
+#include "cc/playback/raster_source.h"
+#include "cc/resources/platform_color.h"
+#include "cc/resources/resource.h"
+
+namespace cc {
+namespace {
+
+class RasterBufferImpl : public RasterBuffer {
+ public:
+  RasterBufferImpl(ResourceProvider* resource_provider,
+                   const Resource* resource,
+                   uint64_t resource_content_id,
+                   uint64_t previous_content_id)
+      : lock_(resource_provider, resource->id()),
+        resource_(resource),
+        resource_has_previous_content_(
+            resource_content_id && resource_content_id == previous_content_id) {
+  }
+
+  // Overridden from RasterBuffer:
+  void Playback(
+      const RasterSource* raster_source,
+      const gfx::Rect& raster_full_rect,
+      const gfx::Rect& raster_dirty_rect,
+      uint64_t new_content_id,
+      float scale,
+      const RasterSource::PlaybackSettings& playback_settings) override {
+    gfx::Rect playback_rect = raster_full_rect;
+    if (resource_has_previous_content_) {
+      playback_rect.Intersect(raster_dirty_rect);
+    }
+    DCHECK(!playback_rect.IsEmpty())
+        << "Why are we rastering a tile that's not dirty?";
+
+    size_t stride = 0u;
+    RasterBufferProvider::PlaybackToMemory(
+        lock_.sk_bitmap().getPixels(), resource_->format(), resource_->size(),
+        stride, raster_source, raster_full_rect, playback_rect, scale,
+        playback_settings);
+  }
+
+ private:
+  ResourceProvider::ScopedWriteLockSoftware lock_;
+  const Resource* resource_;
+  bool resource_has_previous_content_;
+
+  DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
+};
+
+}  // namespace
+
+// static
+std::unique_ptr<RasterBufferProvider> BitmapRasterBufferProvider::Create(
+    ResourceProvider* resource_provider) {
+  return base::WrapUnique<RasterBufferProvider>(
+      new BitmapRasterBufferProvider(resource_provider));
+}
+
+BitmapRasterBufferProvider::BitmapRasterBufferProvider(
+    ResourceProvider* resource_provider)
+    : resource_provider_(resource_provider) {}
+
+BitmapRasterBufferProvider::~BitmapRasterBufferProvider() {}
+
+std::unique_ptr<RasterBuffer>
+BitmapRasterBufferProvider::AcquireBufferForRaster(
+    const Resource* resource,
+    uint64_t resource_content_id,
+    uint64_t previous_content_id) {
+  return std::unique_ptr<RasterBuffer>(new RasterBufferImpl(
+      resource_provider_, resource, resource_content_id, previous_content_id));
+}
+
+void BitmapRasterBufferProvider::ReleaseBufferForRaster(
+    std::unique_ptr<RasterBuffer> buffer) {
+  // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
+}
+
+void BitmapRasterBufferProvider::OrderingBarrier() {
+  // No need to sync resources as this provider does not use GL context.
+}
+
+ResourceFormat BitmapRasterBufferProvider::GetResourceFormat(
+    bool must_support_alpha) const {
+  return resource_provider_->best_texture_format();
+}
+
+bool BitmapRasterBufferProvider::GetResourceRequiresSwizzle(
+    bool must_support_alpha) const {
+  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
+}
+
+void BitmapRasterBufferProvider::Shutdown() {}
+
+}  // namespace cc
diff --git a/cc/raster/bitmap_raster_buffer_provider.h b/cc/raster/bitmap_raster_buffer_provider.h
new file mode 100644
index 0000000..045622626
--- /dev/null
+++ b/cc/raster/bitmap_raster_buffer_provider.h
@@ -0,0 +1,55 @@
+// Copyright 2014 The Chromium 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 CC_RASTER_BITMAP_RASTER_BUFFER_PROVIDER_H_
+#define CC_RASTER_BITMAP_RASTER_BUFFER_PROVIDER_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/values.h"
+#include "cc/raster/raster_buffer_provider.h"
+
+namespace base {
+namespace trace_event {
+class ConvertableToTraceFormat;
+}
+}
+
+namespace cc {
+class ResourceProvider;
+
+class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider {
+ public:
+  ~BitmapRasterBufferProvider() override;
+
+  static std::unique_ptr<RasterBufferProvider> Create(
+      ResourceProvider* resource_provider);
+
+  // Overridden from RasterBufferProvider:
+  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
+      const Resource* resource,
+      uint64_t resource_content_id,
+      uint64_t previous_content_id) override;
+  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
+  void OrderingBarrier() override;
+  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
+  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
+  void Shutdown() override;
+
+ protected:
+  explicit BitmapRasterBufferProvider(ResourceProvider* resource_provider);
+
+ private:
+  std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
+      const;
+
+  ResourceProvider* resource_provider_;
+
+  DISALLOW_COPY_AND_ASSIGN(BitmapRasterBufferProvider);
+};
+
+}  // namespace cc
+
+#endif  // CC_RASTER_BITMAP_RASTER_BUFFER_PROVIDER_H_
diff --git a/cc/raster/bitmap_tile_task_worker_pool.cc b/cc/raster/bitmap_tile_task_worker_pool.cc
deleted file mode 100644
index c08bdcd..0000000
--- a/cc/raster/bitmap_tile_task_worker_pool.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/raster/bitmap_tile_task_worker_pool.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "cc/debug/traced_value.h"
-#include "cc/playback/raster_source.h"
-#include "cc/resources/platform_color.h"
-#include "cc/resources/resource.h"
-
-namespace cc {
-namespace {
-
-class RasterBufferImpl : public RasterBuffer {
- public:
-  RasterBufferImpl(ResourceProvider* resource_provider,
-                   const Resource* resource,
-                   uint64_t resource_content_id,
-                   uint64_t previous_content_id)
-      : lock_(resource_provider, resource->id()),
-        resource_(resource),
-        resource_has_previous_content_(
-            resource_content_id && resource_content_id == previous_content_id) {
-  }
-
-  // Overridden from RasterBuffer:
-  void Playback(
-      const RasterSource* raster_source,
-      const gfx::Rect& raster_full_rect,
-      const gfx::Rect& raster_dirty_rect,
-      uint64_t new_content_id,
-      float scale,
-      const RasterSource::PlaybackSettings& playback_settings) override {
-    gfx::Rect playback_rect = raster_full_rect;
-    if (resource_has_previous_content_) {
-      playback_rect.Intersect(raster_dirty_rect);
-    }
-    DCHECK(!playback_rect.IsEmpty())
-        << "Why are we rastering a tile that's not dirty?";
-
-    size_t stride = 0u;
-    TileTaskWorkerPool::PlaybackToMemory(
-        lock_.sk_bitmap().getPixels(), resource_->format(), resource_->size(),
-        stride, raster_source, raster_full_rect, playback_rect, scale,
-        playback_settings);
-  }
-
- private:
-  ResourceProvider::ScopedWriteLockSoftware lock_;
-  const Resource* resource_;
-  bool resource_has_previous_content_;
-
-  DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
-};
-
-}  // namespace
-
-// static
-std::unique_ptr<TileTaskWorkerPool> BitmapTileTaskWorkerPool::Create(
-    base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
-    ResourceProvider* resource_provider) {
-  return base::WrapUnique<TileTaskWorkerPool>(new BitmapTileTaskWorkerPool(
-      task_runner, task_graph_runner, resource_provider));
-}
-
-BitmapTileTaskWorkerPool::BitmapTileTaskWorkerPool(
-    base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
-    ResourceProvider* resource_provider)
-    : task_runner_(task_runner),
-      task_graph_runner_(task_graph_runner),
-      namespace_token_(task_graph_runner->GetNamespaceToken()),
-      resource_provider_(resource_provider) {}
-
-BitmapTileTaskWorkerPool::~BitmapTileTaskWorkerPool() {
-}
-
-void BitmapTileTaskWorkerPool::Shutdown() {
-  TRACE_EVENT0("cc", "BitmapTileTaskWorkerPool::Shutdown");
-
-  TaskGraph empty;
-  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
-  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
-}
-
-void BitmapTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) {
-  TRACE_EVENT0("cc", "BitmapTileTaskWorkerPool::ScheduleTasks");
-
-  ScheduleTasksOnOriginThread(this, graph);
-  task_graph_runner_->ScheduleTasks(namespace_token_, graph);
-}
-
-void BitmapTileTaskWorkerPool::CheckForCompletedTasks() {
-  TRACE_EVENT0("cc", "BitmapTileTaskWorkerPool::CheckForCompletedTasks");
-
-  task_graph_runner_->CollectCompletedTasks(namespace_token_,
-                                            &completed_tasks_);
-  for (Task::Vector::const_iterator it = completed_tasks_.begin();
-       it != completed_tasks_.end(); ++it) {
-    TileTask* task = static_cast<TileTask*>(it->get());
-
-    task->WillComplete();
-    task->CompleteOnOriginThread(this);
-    task->DidComplete();
-  }
-  completed_tasks_.clear();
-}
-
-ResourceFormat BitmapTileTaskWorkerPool::GetResourceFormat(
-    bool must_support_alpha) const {
-  return resource_provider_->best_texture_format();
-}
-
-bool BitmapTileTaskWorkerPool::GetResourceRequiresSwizzle(
-    bool must_support_alpha) const {
-  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
-}
-
-RasterBufferProvider* BitmapTileTaskWorkerPool::AsRasterBufferProvider() {
-  return this;
-}
-
-std::unique_ptr<RasterBuffer> BitmapTileTaskWorkerPool::AcquireBufferForRaster(
-    const Resource* resource,
-    uint64_t resource_content_id,
-    uint64_t previous_content_id) {
-  return std::unique_ptr<RasterBuffer>(new RasterBufferImpl(
-      resource_provider_, resource, resource_content_id, previous_content_id));
-}
-
-void BitmapTileTaskWorkerPool::ReleaseBufferForRaster(
-    std::unique_ptr<RasterBuffer> buffer) {
-  // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
-}
-
-}  // namespace cc
diff --git a/cc/raster/bitmap_tile_task_worker_pool.h b/cc/raster/bitmap_tile_task_worker_pool.h
deleted file mode 100644
index 5d7e409..0000000
--- a/cc/raster/bitmap_tile_task_worker_pool.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RASTER_BITMAP_TILE_TASK_WORKER_POOL_H_
-#define CC_RASTER_BITMAP_TILE_TASK_WORKER_POOL_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/values.h"
-#include "cc/raster/tile_task_worker_pool.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-}
-}
-
-namespace cc {
-class ResourceProvider;
-
-class CC_EXPORT BitmapTileTaskWorkerPool : public TileTaskWorkerPool,
-                                           public RasterBufferProvider {
- public:
-  ~BitmapTileTaskWorkerPool() override;
-
-  static std::unique_ptr<TileTaskWorkerPool> Create(
-      base::SequencedTaskRunner* task_runner,
-      TaskGraphRunner* task_graph_runner,
-      ResourceProvider* resource_provider);
-
-  // Overridden from TileTaskWorkerPool:
-  void Shutdown() override;
-  void ScheduleTasks(TaskGraph* graph) override;
-  void CheckForCompletedTasks() override;
-  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
-  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
-  RasterBufferProvider* AsRasterBufferProvider() override;
-
-  // Overridden from RasterBufferProvider:
-  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
-      const Resource* resource,
-      uint64_t resource_content_id,
-      uint64_t previous_content_id) override;
-  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
-
- protected:
-  BitmapTileTaskWorkerPool(base::SequencedTaskRunner* task_runner,
-                           TaskGraphRunner* task_graph_runner,
-                           ResourceProvider* resource_provider);
-
- private:
-  std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
-      const;
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  TaskGraphRunner* task_graph_runner_;
-  const NamespaceToken namespace_token_;
-  ResourceProvider* resource_provider_;
-
-  Task::Vector completed_tasks_;
-
-  DISALLOW_COPY_AND_ASSIGN(BitmapTileTaskWorkerPool);
-};
-
-}  // namespace cc
-
-#endif  // CC_RASTER_BITMAP_TILE_TASK_WORKER_POOL_H_
diff --git a/cc/raster/gpu_tile_task_worker_pool.cc b/cc/raster/gpu_raster_buffer_provider.cc
similarity index 65%
rename from cc/raster/gpu_tile_task_worker_pool.cc
rename to cc/raster/gpu_raster_buffer_provider.cc
index c1f82d1b..51d8898 100644
--- a/cc/raster/gpu_tile_task_worker_pool.cc
+++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "cc/raster/gpu_tile_task_worker_pool.h"
+#include "cc/raster/gpu_raster_buffer_provider.h"
 
 #include <stdint.h>
 
@@ -89,96 +89,29 @@
 }  // namespace
 
 // static
-std::unique_ptr<TileTaskWorkerPool> GpuTileTaskWorkerPool::Create(
-    base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
+std::unique_ptr<RasterBufferProvider> GpuRasterBufferProvider::Create(
     ContextProvider* context_provider,
     ResourceProvider* resource_provider,
     bool use_distance_field_text,
     int gpu_rasterization_msaa_sample_count) {
-  return base::WrapUnique<TileTaskWorkerPool>(new GpuTileTaskWorkerPool(
-      task_runner, task_graph_runner, context_provider, resource_provider,
-      use_distance_field_text, gpu_rasterization_msaa_sample_count));
+  return base::WrapUnique<RasterBufferProvider>(new GpuRasterBufferProvider(
+      context_provider, resource_provider, use_distance_field_text,
+      gpu_rasterization_msaa_sample_count));
 }
 
-GpuTileTaskWorkerPool::GpuTileTaskWorkerPool(
-    base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
+GpuRasterBufferProvider::GpuRasterBufferProvider(
     ContextProvider* context_provider,
     ResourceProvider* resource_provider,
     bool use_distance_field_text,
     int gpu_rasterization_msaa_sample_count)
-    : task_runner_(task_runner),
-      task_graph_runner_(task_graph_runner),
-      namespace_token_(task_graph_runner_->GetNamespaceToken()),
-      rasterizer_(new GpuRasterizer(context_provider,
+    : rasterizer_(new GpuRasterizer(context_provider,
                                     resource_provider,
                                     use_distance_field_text,
                                     gpu_rasterization_msaa_sample_count)) {}
 
-GpuTileTaskWorkerPool::~GpuTileTaskWorkerPool() {
-  DCHECK_EQ(0u, completed_tasks_.size());
-}
+GpuRasterBufferProvider::~GpuRasterBufferProvider() {}
 
-void GpuTileTaskWorkerPool::Shutdown() {
-  TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::Shutdown");
-
-  TaskGraph empty;
-  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
-  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
-}
-
-void GpuTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) {
-  TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::ScheduleTasks");
-
-  ScheduleTasksOnOriginThread(this, graph);
-
-  // Barrier to sync any new resources to the worker context.
-  rasterizer_->resource_provider()
-      ->output_surface()
-      ->context_provider()
-      ->ContextGL()
-      ->OrderingBarrierCHROMIUM();
-
-  task_graph_runner_->ScheduleTasks(namespace_token_, graph);
-}
-
-void GpuTileTaskWorkerPool::CheckForCompletedTasks() {
-  TRACE_EVENT0("cc", "GpuTileTaskWorkerPool::CheckForCompletedTasks");
-
-  task_graph_runner_->CollectCompletedTasks(namespace_token_,
-                                            &completed_tasks_);
-  CompleteTasks(completed_tasks_);
-  completed_tasks_.clear();
-}
-
-ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat(
-    bool must_support_alpha) const {
-  return rasterizer_->resource_provider()->best_render_buffer_format();
-}
-
-bool GpuTileTaskWorkerPool::GetResourceRequiresSwizzle(
-    bool must_support_alpha) const {
-  // This doesn't require a swizzle because we rasterize to the correct format.
-  return false;
-}
-
-RasterBufferProvider* GpuTileTaskWorkerPool::AsRasterBufferProvider() {
-  return this;
-}
-
-void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) {
-  for (auto& task : tasks) {
-    TileTask* tile_task = static_cast<TileTask*>(task.get());
-
-    tile_task->WillComplete();
-    tile_task->CompleteOnOriginThread(this);
-    tile_task->DidComplete();
-  }
-  completed_tasks_.clear();
-}
-
-std::unique_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster(
+std::unique_ptr<RasterBuffer> GpuRasterBufferProvider::AcquireBufferForRaster(
     const Resource* resource,
     uint64_t resource_content_id,
     uint64_t previous_content_id) {
@@ -186,9 +119,32 @@
       rasterizer_.get(), resource, resource_content_id, previous_content_id));
 }
 
-void GpuTileTaskWorkerPool::ReleaseBufferForRaster(
+void GpuRasterBufferProvider::ReleaseBufferForRaster(
     std::unique_ptr<RasterBuffer> buffer) {
   // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
 }
 
+void GpuRasterBufferProvider::OrderingBarrier() {
+  TRACE_EVENT0("cc", "GpuRasterBufferProvider::OrderingBarrier");
+
+  rasterizer_->resource_provider()
+      ->output_surface()
+      ->context_provider()
+      ->ContextGL()
+      ->OrderingBarrierCHROMIUM();
+}
+
+ResourceFormat GpuRasterBufferProvider::GetResourceFormat(
+    bool must_support_alpha) const {
+  return rasterizer_->resource_provider()->best_render_buffer_format();
+}
+
+bool GpuRasterBufferProvider::GetResourceRequiresSwizzle(
+    bool must_support_alpha) const {
+  // This doesn't require a swizzle because we rasterize to the correct format.
+  return false;
+}
+
+void GpuRasterBufferProvider::Shutdown() {}
+
 }  // namespace cc
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h
new file mode 100644
index 0000000..3bbc806
--- /dev/null
+++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -0,0 +1,52 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_RASTER_GPU_RASTER_BUFFER_PROVIDER_H_
+#define CC_RASTER_GPU_RASTER_BUFFER_PROVIDER_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "cc/raster/raster_buffer_provider.h"
+
+namespace cc {
+class ContextProvider;
+class GpuRasterizer;
+class ResourceProvider;
+
+class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
+ public:
+  ~GpuRasterBufferProvider() override;
+
+  static std::unique_ptr<RasterBufferProvider> Create(
+      ContextProvider* context_provider,
+      ResourceProvider* resource_provider,
+      bool use_distance_field_text,
+      int gpu_rasterization_msaa_sample_count);
+
+  // Overridden from RasterBufferProvider:
+  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
+      const Resource* resource,
+      uint64_t resource_content_id,
+      uint64_t previous_content_id) override;
+  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
+  void OrderingBarrier() override;
+  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
+  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
+  void Shutdown() override;
+
+ private:
+  GpuRasterBufferProvider(ContextProvider* context_provider,
+                          ResourceProvider* resource_provider,
+                          bool use_distance_field_text,
+                          int gpu_rasterization_msaa_sample_count);
+
+  std::unique_ptr<GpuRasterizer> rasterizer_;
+
+  DISALLOW_COPY_AND_ASSIGN(GpuRasterBufferProvider);
+};
+
+}  // namespace cc
+
+#endif  // CC_RASTER_GPU_RASTER_BUFFER_PROVIDER_H_
diff --git a/cc/raster/gpu_rasterizer.h b/cc/raster/gpu_rasterizer.h
index d195143..3e2c9e9d 100644
--- a/cc/raster/gpu_rasterizer.h
+++ b/cc/raster/gpu_rasterizer.h
@@ -44,7 +44,7 @@
   bool use_distance_field_text_;
   int msaa_sample_count_;
 
-  friend class GpuTileTaskWorkerPool;
+  friend class GpuRasterBufferProvider;
   DISALLOW_COPY_AND_ASSIGN(GpuRasterizer);
 };
 
diff --git a/cc/raster/gpu_tile_task_worker_pool.h b/cc/raster/gpu_tile_task_worker_pool.h
deleted file mode 100644
index a0a7291..0000000
--- a/cc/raster/gpu_tile_task_worker_pool.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RASTER_GPU_TILE_TASK_WORKER_POOL_H_
-#define CC_RASTER_GPU_TILE_TASK_WORKER_POOL_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "cc/raster/tile_task_worker_pool.h"
-
-namespace cc {
-class ContextProvider;
-class GpuRasterizer;
-class ResourceProvider;
-
-class CC_EXPORT GpuTileTaskWorkerPool : public TileTaskWorkerPool,
-                                        public RasterBufferProvider {
- public:
-  ~GpuTileTaskWorkerPool() override;
-
-  static std::unique_ptr<TileTaskWorkerPool> Create(
-      base::SequencedTaskRunner* task_runner,
-      TaskGraphRunner* task_graph_runner,
-      ContextProvider* context_provider,
-      ResourceProvider* resource_provider,
-      bool use_distance_field_text,
-      int gpu_rasterization_msaa_sample_count);
-
-  // Overridden from TileTaskWorkerPool:
-  void Shutdown() override;
-  void ScheduleTasks(TaskGraph* graph) override;
-  void CheckForCompletedTasks() override;
-  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
-  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
-  RasterBufferProvider* AsRasterBufferProvider() override;
-
-  // Overridden from RasterBufferProvider:
-  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
-      const Resource* resource,
-      uint64_t resource_content_id,
-      uint64_t previous_content_id) override;
-  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
-
- private:
-  GpuTileTaskWorkerPool(base::SequencedTaskRunner* task_runner,
-                        TaskGraphRunner* task_graph_runner,
-                        ContextProvider* context_provider,
-                        ResourceProvider* resource_provider,
-                        bool use_distance_field_text,
-                        int gpu_rasterization_msaa_sample_count);
-
-  void CompleteTasks(const Task::Vector& tasks);
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  TaskGraphRunner* task_graph_runner_;
-  const NamespaceToken namespace_token_;
-  std::unique_ptr<GpuRasterizer> rasterizer_;
-
-  Task::Vector completed_tasks_;
-
-  DISALLOW_COPY_AND_ASSIGN(GpuTileTaskWorkerPool);
-};
-
-}  // namespace cc
-
-#endif  // CC_RASTER_GPU_TILE_TASK_WORKER_POOL_H_
diff --git a/cc/raster/one_copy_tile_task_worker_pool.cc b/cc/raster/one_copy_raster_buffer_provider.cc
similarity index 81%
rename from cc/raster/one_copy_tile_task_worker_pool.cc
rename to cc/raster/one_copy_raster_buffer_provider.cc
index 3c12301f..816820b 100644
--- a/cc/raster/one_copy_tile_task_worker_pool.cc
+++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "cc/raster/one_copy_tile_task_worker_pool.h"
+#include "cc/raster/one_copy_raster_buffer_provider.h"
 
 #include <stdint.h>
 
@@ -27,7 +27,7 @@
 
 class RasterBufferImpl : public RasterBuffer {
  public:
-  RasterBufferImpl(OneCopyTileTaskWorkerPool* worker_pool,
+  RasterBufferImpl(OneCopyRasterBufferProvider* worker_pool,
                    ResourceProvider* resource_provider,
                    ResourceFormat resource_format,
                    const Resource* resource,
@@ -53,7 +53,7 @@
   }
 
  private:
-  OneCopyTileTaskWorkerPool* worker_pool_;
+  OneCopyRasterBufferProvider* worker_pool_;
   const Resource* resource_;
   ResourceProvider::ScopedWriteLockGL lock_;
   uint64_t previous_content_id_;
@@ -68,32 +68,28 @@
 }  // namespace
 
 // static
-std::unique_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create(
+std::unique_ptr<RasterBufferProvider> OneCopyRasterBufferProvider::Create(
     base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
     ContextProvider* context_provider,
     ResourceProvider* resource_provider,
     int max_copy_texture_chromium_size,
     bool use_partial_raster,
     int max_staging_buffer_usage_in_bytes,
     ResourceFormat preferred_tile_format) {
-  return base::WrapUnique<TileTaskWorkerPool>(new OneCopyTileTaskWorkerPool(
-      task_runner, task_graph_runner, resource_provider,
-      max_copy_texture_chromium_size, use_partial_raster,
-      max_staging_buffer_usage_in_bytes, preferred_tile_format));
+  return base::WrapUnique<RasterBufferProvider>(new OneCopyRasterBufferProvider(
+      task_runner, resource_provider, max_copy_texture_chromium_size,
+      use_partial_raster, max_staging_buffer_usage_in_bytes,
+      preferred_tile_format));
 }
 
-OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool(
+OneCopyRasterBufferProvider::OneCopyRasterBufferProvider(
     base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
     ResourceProvider* resource_provider,
     int max_copy_texture_chromium_size,
     bool use_partial_raster,
     int max_staging_buffer_usage_in_bytes,
     ResourceFormat preferred_tile_format)
-    : task_graph_runner_(task_graph_runner),
-      namespace_token_(task_graph_runner->GetNamespaceToken()),
-      resource_provider_(resource_provider),
+    : resource_provider_(resource_provider),
       max_bytes_per_copy_operation_(
           max_copy_texture_chromium_size
               ? std::min(kMaxBytesPerCopyOperation,
@@ -107,71 +103,10 @@
                                             max_staging_buffer_usage_in_bytes);
 }
 
-OneCopyTileTaskWorkerPool::~OneCopyTileTaskWorkerPool() {
-}
+OneCopyRasterBufferProvider::~OneCopyRasterBufferProvider() {}
 
-void OneCopyTileTaskWorkerPool::Shutdown() {
-  TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::Shutdown");
-
-  TaskGraph empty;
-  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
-  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
-
-  staging_pool_->Shutdown();
-}
-
-void OneCopyTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) {
-  TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::ScheduleTasks");
-
-  ScheduleTasksOnOriginThread(this, graph);
-
-  // Barrier to sync any new resources to the worker context.
-  resource_provider_->output_surface()
-      ->context_provider()
-      ->ContextGL()
-      ->OrderingBarrierCHROMIUM();
-
-  task_graph_runner_->ScheduleTasks(namespace_token_, graph);
-}
-
-void OneCopyTileTaskWorkerPool::CheckForCompletedTasks() {
-  TRACE_EVENT0("cc", "OneCopyTileTaskWorkerPool::CheckForCompletedTasks");
-
-  task_graph_runner_->CollectCompletedTasks(namespace_token_,
-                                            &completed_tasks_);
-
-  for (Task::Vector::const_iterator it = completed_tasks_.begin();
-       it != completed_tasks_.end(); ++it) {
-    TileTask* task = static_cast<TileTask*>(it->get());
-
-    task->WillComplete();
-    task->CompleteOnOriginThread(this);
-    task->DidComplete();
-  }
-  completed_tasks_.clear();
-}
-
-ResourceFormat OneCopyTileTaskWorkerPool::GetResourceFormat(
-    bool must_support_alpha) const {
-  if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) &&
-      (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
-       !must_support_alpha)) {
-    return preferred_tile_format_;
-  }
-
-  return resource_provider_->best_texture_format();
-}
-
-bool OneCopyTileTaskWorkerPool::GetResourceRequiresSwizzle(
-    bool must_support_alpha) const {
-  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
-}
-
-RasterBufferProvider* OneCopyTileTaskWorkerPool::AsRasterBufferProvider() {
-  return this;
-}
-
-std::unique_ptr<RasterBuffer> OneCopyTileTaskWorkerPool::AcquireBufferForRaster(
+std::unique_ptr<RasterBuffer>
+OneCopyRasterBufferProvider::AcquireBufferForRaster(
     const Resource* resource,
     uint64_t resource_content_id,
     uint64_t previous_content_id) {
@@ -182,12 +117,41 @@
                            resource, previous_content_id));
 }
 
-void OneCopyTileTaskWorkerPool::ReleaseBufferForRaster(
+void OneCopyRasterBufferProvider::ReleaseBufferForRaster(
     std::unique_ptr<RasterBuffer> buffer) {
   // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
 }
 
-void OneCopyTileTaskWorkerPool::PlaybackAndCopyOnWorkerThread(
+void OneCopyRasterBufferProvider::OrderingBarrier() {
+  TRACE_EVENT0("cc", "OneCopyRasterBufferProvider::OrderingBarrier");
+
+  resource_provider_->output_surface()
+      ->context_provider()
+      ->ContextGL()
+      ->OrderingBarrierCHROMIUM();
+}
+
+ResourceFormat OneCopyRasterBufferProvider::GetResourceFormat(
+    bool must_support_alpha) const {
+  if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) &&
+      (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
+       !must_support_alpha)) {
+    return preferred_tile_format_;
+  }
+
+  return resource_provider_->best_texture_format();
+}
+
+bool OneCopyRasterBufferProvider::GetResourceRequiresSwizzle(
+    bool must_support_alpha) const {
+  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
+}
+
+void OneCopyRasterBufferProvider::Shutdown() {
+  staging_pool_->Shutdown();
+}
+
+void OneCopyRasterBufferProvider::PlaybackAndCopyOnWorkerThread(
     const Resource* resource,
     ResourceProvider::ScopedWriteLockGL* resource_lock,
     const RasterSource* raster_source,
@@ -211,7 +175,7 @@
   staging_pool_->ReleaseStagingBuffer(std::move(staging_buffer));
 }
 
-void OneCopyTileTaskWorkerPool::PlaybackToStagingBuffer(
+void OneCopyRasterBufferProvider::PlaybackToStagingBuffer(
     StagingBuffer* staging_buffer,
     const Resource* resource,
     const RasterSource* raster_source,
@@ -248,12 +212,12 @@
     bool rv = buffer->Map();
     DCHECK(rv);
     DCHECK(buffer->memory(0));
-    // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides.
+    // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
     DCHECK_GE(buffer->stride(0), 0);
 
     DCHECK(!playback_rect.IsEmpty())
         << "Why are we rastering a tile that's not dirty?";
-    TileTaskWorkerPool::PlaybackToMemory(
+    RasterBufferProvider::PlaybackToMemory(
         buffer->memory(0), resource->format(), staging_buffer->size,
         buffer->stride(0), raster_source, raster_full_rect, playback_rect,
         scale, playback_settings);
@@ -262,7 +226,7 @@
   }
 }
 
-void OneCopyTileTaskWorkerPool::CopyOnWorkerThread(
+void OneCopyRasterBufferProvider::CopyOnWorkerThread(
     StagingBuffer* staging_buffer,
     const Resource* resource,
     ResourceProvider::ScopedWriteLockGL* resource_lock,
diff --git a/cc/raster/one_copy_tile_task_worker_pool.h b/cc/raster/one_copy_raster_buffer_provider.h
similarity index 67%
rename from cc/raster/one_copy_tile_task_worker_pool.h
rename to cc/raster/one_copy_raster_buffer_provider.h
index da41020e..0c129fa 100644
--- a/cc/raster/one_copy_tile_task_worker_pool.h
+++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CC_RASTER_ONE_COPY_TILE_TASK_WORKER_POOL_H_
-#define CC_RASTER_ONE_COPY_TILE_TASK_WORKER_POOL_H_
+#ifndef CC_RASTER_ONE_COPY_RASTER_BUFFER_PROVIDER_H_
+#define CC_RASTER_ONE_COPY_RASTER_BUFFER_PROVIDER_H_
 
 #include <stdint.h>
 
 #include "base/macros.h"
 #include "cc/output/context_provider.h"
-#include "cc/raster/tile_task_worker_pool.h"
+#include "cc/raster/raster_buffer_provider.h"
 #include "cc/resources/resource_provider.h"
 
 namespace cc {
@@ -17,14 +17,12 @@
 class StagingBufferPool;
 class ResourcePool;
 
-class CC_EXPORT OneCopyTileTaskWorkerPool : public TileTaskWorkerPool,
-                                            public RasterBufferProvider {
+class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
  public:
-  ~OneCopyTileTaskWorkerPool() override;
+  ~OneCopyRasterBufferProvider() override;
 
-  static std::unique_ptr<TileTaskWorkerPool> Create(
+  static std::unique_ptr<RasterBufferProvider> Create(
       base::SequencedTaskRunner* task_runner,
-      TaskGraphRunner* task_graph_runner,
       ContextProvider* context_provider,
       ResourceProvider* resource_provider,
       int max_copy_texture_chromium_size,
@@ -32,20 +30,16 @@
       int max_staging_buffer_usage_in_bytes,
       ResourceFormat preferred_tile_format);
 
-  // Overridden from TileTaskWorkerPool:
-  void Shutdown() override;
-  void ScheduleTasks(TaskGraph* graph) override;
-  void CheckForCompletedTasks() override;
-  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
-  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
-  RasterBufferProvider* AsRasterBufferProvider() override;
-
   // Overridden from RasterBufferProvider:
   std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
       const Resource* resource,
       uint64_t resource_content_id,
       uint64_t previous_content_id) override;
   void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
+  void OrderingBarrier() override;
+  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
+  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
+  void Shutdown() override;
 
   // Playback raster source and copy result into |resource|.
   void PlaybackAndCopyOnWorkerThread(
@@ -60,13 +54,12 @@
       uint64_t new_content_id);
 
  protected:
-  OneCopyTileTaskWorkerPool(base::SequencedTaskRunner* task_runner,
-                            TaskGraphRunner* task_graph_runner,
-                            ResourceProvider* resource_provider,
-                            int max_copy_texture_chromium_size,
-                            bool use_partial_raster,
-                            int max_staging_buffer_usage_in_bytes,
-                            ResourceFormat preferred_tile_format);
+  OneCopyRasterBufferProvider(base::SequencedTaskRunner* task_runner,
+                              ResourceProvider* resource_provider,
+                              int max_copy_texture_chromium_size,
+                              bool use_partial_raster,
+                              int max_staging_buffer_usage_in_bytes,
+                              ResourceFormat preferred_tile_format);
 
  private:
   void PlaybackToStagingBuffer(
@@ -86,8 +79,6 @@
                           uint64_t previous_content_id,
                           uint64_t new_content_id);
 
-  TaskGraphRunner* task_graph_runner_;
-  const NamespaceToken namespace_token_;
   ResourceProvider* const resource_provider_;
   const int max_bytes_per_copy_operation_;
   bool use_partial_raster_;
@@ -98,11 +89,9 @@
   ResourceFormat preferred_tile_format_;
   std::unique_ptr<StagingBufferPool> staging_pool_;
 
-  Task::Vector completed_tasks_;
-
-  DISALLOW_COPY_AND_ASSIGN(OneCopyTileTaskWorkerPool);
+  DISALLOW_COPY_AND_ASSIGN(OneCopyRasterBufferProvider);
 };
 
 }  // namespace cc
 
-#endif  // CC_RASTER_ONE_COPY_TILE_TASK_WORKER_POOL_H_
+#endif  // CC_RASTER_ONE_COPY_RASTER_BUFFER_PROVIDER_H_
diff --git a/cc/raster/raster_buffer.h b/cc/raster/raster_buffer.h
index 54c5b9e..04972f9d 100644
--- a/cc/raster/raster_buffer.h
+++ b/cc/raster/raster_buffer.h
@@ -12,20 +12,6 @@
 #include "ui/gfx/geometry/rect.h"
 
 namespace cc {
-class RasterBuffer;
-class Resource;
-
-class CC_EXPORT RasterBufferProvider {
- public:
-  virtual std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
-      const Resource* resource,
-      uint64_t resource_content_id,
-      uint64_t previous_content_id) = 0;
-  virtual void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) = 0;
-
- protected:
-  virtual ~RasterBufferProvider() {}
-};
 
 class CC_EXPORT RasterBuffer {
  public:
diff --git a/cc/raster/tile_task_worker_pool.cc b/cc/raster/raster_buffer_provider.cc
similarity index 80%
rename from cc/raster/tile_task_worker_pool.cc
rename to cc/raster/raster_buffer_provider.cc
index b14cd836..67b839c2 100644
--- a/cc/raster/tile_task_worker_pool.cc
+++ b/cc/raster/raster_buffer_provider.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "cc/raster/tile_task_worker_pool.h"
+#include "cc/raster/raster_buffer_provider.h"
 
 #include <stddef.h>
 
@@ -15,28 +15,9 @@
 
 namespace cc {
 
-TileTaskWorkerPool::TileTaskWorkerPool() {}
+RasterBufferProvider::RasterBufferProvider() {}
 
-TileTaskWorkerPool::~TileTaskWorkerPool() {}
-
-// static
-void TileTaskWorkerPool::ScheduleTasksOnOriginThread(
-    RasterBufferProvider* provider,
-    TaskGraph* graph) {
-  TRACE_EVENT0("cc", "TileTaskWorkerPool::ScheduleTasksOnOriginThread");
-
-  for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin();
-       it != graph->nodes.end(); ++it) {
-    TaskGraph::Node& node = *it;
-    TileTask* task = static_cast<TileTask*>(node.task);
-
-    if (!task->HasBeenScheduled()) {
-      task->WillSchedule();
-      task->ScheduleOnOriginThread(provider);
-      task->DidSchedule();
-    }
-  }
-}
+RasterBufferProvider::~RasterBufferProvider() {}
 
 namespace {
 
@@ -61,7 +42,7 @@
 }  // anonymous namespace
 
 // static
-void TileTaskWorkerPool::PlaybackToMemory(
+void RasterBufferProvider::PlaybackToMemory(
     void* memory,
     ResourceFormat format,
     const gfx::Size& size,
@@ -71,7 +52,7 @@
     const gfx::Rect& canvas_playback_rect,
     float scale,
     const RasterSource::PlaybackSettings& playback_settings) {
-  TRACE_EVENT0("cc", "TileTaskWorkerPool::PlaybackToMemory");
+  TRACE_EVENT0("cc", "RasterBufferProvider::PlaybackToMemory");
 
   DCHECK(IsSupportedPlaybackToMemoryFormat(format)) << format;
 
@@ -111,7 +92,7 @@
 
       if (format == ETC1) {
         TRACE_EVENT0("cc",
-                     "TileTaskWorkerPool::PlaybackToMemory::CompressETC1");
+                     "RasterBufferProvider::PlaybackToMemory::CompressETC1");
         DCHECK_EQ(size.width() % 4, 0);
         DCHECK_EQ(size.height() % 4, 0);
         std::unique_ptr<TextureCompressor> texture_compressor =
@@ -124,7 +105,7 @@
             TextureCompressor::kQualityHigh);
       } else {
         TRACE_EVENT0("cc",
-                     "TileTaskWorkerPool::PlaybackToMemory::ConvertRGBA4444");
+                     "RasterBufferProvider::PlaybackToMemory::ConvertRGBA4444");
         SkImageInfo dst_info =
             SkImageInfo::Make(info.width(), info.height(),
                               ResourceFormatToClosestSkColorType(format),
@@ -146,7 +127,8 @@
   NOTREACHED();
 }
 
-bool TileTaskWorkerPool::ResourceFormatRequiresSwizzle(ResourceFormat format) {
+bool RasterBufferProvider::ResourceFormatRequiresSwizzle(
+    ResourceFormat format) {
   switch (format) {
     case RGBA_8888:
     case BGRA_8888:
diff --git a/cc/raster/raster_buffer_provider.h b/cc/raster/raster_buffer_provider.h
new file mode 100644
index 0000000..061740a
--- /dev/null
+++ b/cc/raster/raster_buffer_provider.h
@@ -0,0 +1,75 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_RASTER_RASTER_BUFFER_PROVIDER_H_
+#define CC_RASTER_RASTER_BUFFER_PROVIDER_H_
+
+#include <stddef.h>
+
+#include "cc/playback/raster_source.h"
+#include "cc/raster/raster_buffer.h"
+#include "cc/raster/task_graph_runner.h"
+#include "cc/raster/tile_task.h"
+#include "cc/resources/resource_format.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace base {
+class SequencedTaskRunner;
+}
+
+namespace cc {
+class Resource;
+
+class CC_EXPORT RasterBufferProvider {
+ public:
+  RasterBufferProvider();
+  virtual ~RasterBufferProvider();
+
+  // Utility function that will create a temporary bitmap and copy pixels to
+  // |memory| when necessary. The |canvas_bitmap_rect| is the rect of the bitmap
+  // being played back in the pixel space of the source, ie a rect in the source
+  // that will cover the resulting |memory|. The |canvas_playback_rect| can be a
+  // smaller contained rect inside the |canvas_bitmap_rect| if the |memory| is
+  // already partially complete, and only the subrect needs to be played back.
+  static void PlaybackToMemory(
+      void* memory,
+      ResourceFormat format,
+      const gfx::Size& size,
+      size_t stride,
+      const RasterSource* raster_source,
+      const gfx::Rect& canvas_bitmap_rect,
+      const gfx::Rect& canvas_playback_rect,
+      float scale,
+      const RasterSource::PlaybackSettings& playback_settings);
+
+  // Acquire raster buffer.
+  virtual std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
+      const Resource* resource,
+      uint64_t resource_content_id,
+      uint64_t previous_content_id) = 0;
+
+  // Release raster buffer.
+  virtual void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) = 0;
+
+  // Barrier to sync resources to the worker context.
+  virtual void OrderingBarrier() = 0;
+
+  // Returns the format to use for the tiles.
+  virtual ResourceFormat GetResourceFormat(bool must_support_alpha) const = 0;
+
+  // Determine if the resource requires swizzling.
+  virtual bool GetResourceRequiresSwizzle(bool must_support_alpha) const = 0;
+
+  // Shutdown for doing cleanup.
+  virtual void Shutdown() = 0;
+
+ protected:
+  // Check if resource format matches output format.
+  static bool ResourceFormatRequiresSwizzle(ResourceFormat format);
+};
+
+}  // namespace cc
+
+#endif  // CC_RASTER_RASTER_BUFFER_PROVIDER_H_
diff --git a/cc/raster/tile_task_worker_pool_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc
similarity index 73%
rename from cc/raster/tile_task_worker_pool_perftest.cc
rename to cc/raster/raster_buffer_provider_perftest.cc
index 12dd63d..c031b4c 100644
--- a/cc/raster/tile_task_worker_pool_perftest.cc
+++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -11,13 +11,13 @@
 #include "base/time/time.h"
 #include "cc/debug/lap_timer.h"
 #include "cc/output/context_provider.h"
-#include "cc/raster/bitmap_tile_task_worker_pool.h"
+#include "cc/raster/bitmap_raster_buffer_provider.h"
+#include "cc/raster/gpu_raster_buffer_provider.h"
 #include "cc/raster/gpu_rasterizer.h"
-#include "cc/raster/gpu_tile_task_worker_pool.h"
-#include "cc/raster/one_copy_tile_task_worker_pool.h"
+#include "cc/raster/one_copy_raster_buffer_provider.h"
+#include "cc/raster/raster_buffer_provider.h"
 #include "cc/raster/synchronous_task_graph_runner.h"
-#include "cc/raster/tile_task_worker_pool.h"
-#include "cc/raster/zero_copy_tile_task_worker_pool.h"
+#include "cc/raster/zero_copy_raster_buffer_provider.h"
 #include "cc/resources/resource_pool.h"
 #include "cc/resources/resource_provider.h"
 #include "cc/resources/scoped_resource.h"
@@ -28,6 +28,7 @@
 #include "cc/test/test_gpu_memory_buffer_manager.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_web_graphics_context_3d.h"
+#include "cc/tiles/tile_task_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_test.h"
 #include "third_party/khronos/GLES2/gl2.h"
@@ -110,11 +111,11 @@
   base::Lock context_lock_;
 };
 
-enum TileTaskWorkerPoolType {
-  TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
-  TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
-  TILE_TASK_WORKER_POOL_TYPE_GPU,
-  TILE_TASK_WORKER_POOL_TYPE_BITMAP
+enum RasterBufferProviderType {
+  RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY,
+  RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY,
+  RASTER_BUFFER_PROVIDER_TYPE_GPU,
+  RASTER_BUFFER_PROVIDER_TYPE_BITMAP
 };
 
 static const int kTimeLimitMillis = 2000;
@@ -180,13 +181,13 @@
   DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
 };
 
-class TileTaskWorkerPoolPerfTestBase {
+class RasterBufferProviderPerfTestBase {
  public:
   typedef std::vector<scoped_refptr<TileTask>> RasterTaskVector;
 
   enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL };
 
-  TileTaskWorkerPoolPerfTestBase()
+  RasterBufferProviderPerfTestBase()
       : context_provider_(make_scoped_refptr(new PerfContextProvider)),
         task_runner_(new base::TestSimpleTaskRunner),
         task_graph_runner_(new SynchronousTaskGraphRunner),
@@ -201,20 +202,19 @@
   }
 
   void CreateRasterTasks(unsigned num_raster_tasks,
-                         unsigned num_image_decode_tasks,
+                         const TileTask::Vector& image_decode_tasks,
                          RasterTaskVector* raster_tasks) {
     const gfx::Size size(1, 1);
 
     for (unsigned i = 0; i < num_raster_tasks; ++i) {
-      TileTask::Vector image_decode_tasks;
-      CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
       std::unique_ptr<ScopedResource> resource(
           ScopedResource::Create(resource_provider_.get()));
       resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
                          RGBA_8888);
 
+      TileTask::Vector dependencies = image_decode_tasks;
       raster_tasks->push_back(
-          new PerfRasterTaskImpl(std::move(resource), &image_decode_tasks));
+          new PerfRasterTaskImpl(std::move(resource), &dependencies));
     }
   }
 
@@ -226,10 +226,20 @@
       priority++;
 
       for (auto& decode_task : raster_task->dependencies()) {
-        graph->nodes.push_back(
-            TaskGraph::Node(decode_task.get(), 0u /* group */, priority, 0u));
+        // Add decode task if it doesn't already exist in graph.
+        TaskGraph::Node::Vector::iterator decode_it =
+            std::find_if(graph->nodes.begin(), graph->nodes.end(),
+                         [decode_task](const TaskGraph::Node& node) {
+                           return node.task == decode_task;
+                         });
+
+        if (decode_it == graph->nodes.end()) {
+          graph->nodes.push_back(
+              TaskGraph::Node(decode_task.get(), 0u /* group */, priority, 0u));
+        }
+
         graph->edges.push_back(
-            TaskGraph::Edge(raster_task.get(), decode_task.get()));
+            TaskGraph::Edge(decode_task.get(), raster_task.get()));
       }
 
       graph->nodes.push_back(TaskGraph::Node(
@@ -248,47 +258,47 @@
   LapTimer timer_;
 };
 
-class TileTaskWorkerPoolPerfTest
-    : public TileTaskWorkerPoolPerfTestBase,
-      public testing::TestWithParam<TileTaskWorkerPoolType> {
+class RasterBufferProviderPerfTest
+    : public RasterBufferProviderPerfTestBase,
+      public testing::TestWithParam<RasterBufferProviderType> {
  public:
   // Overridden from testing::Test:
   void SetUp() override {
+    std::unique_ptr<RasterBufferProvider> raster_buffer_provider;
     switch (GetParam()) {
-      case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
+      case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY:
         Create3dOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create(
-            task_runner_.get(), task_graph_runner_.get(),
+        raster_buffer_provider = ZeroCopyRasterBufferProvider::Create(
             resource_provider_.get(), PlatformColor::BestTextureFormat());
         break;
-      case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
+      case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY:
         Create3dOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
-            task_runner_.get(), task_graph_runner_.get(),
-            context_provider_.get(), resource_provider_.get(),
-            std::numeric_limits<int>::max(), false,
+        raster_buffer_provider = OneCopyRasterBufferProvider::Create(
+            task_runner_.get(), context_provider_.get(),
+            resource_provider_.get(), std::numeric_limits<int>::max(), false,
             std::numeric_limits<int>::max(),
             PlatformColor::BestTextureFormat());
         break;
-      case TILE_TASK_WORKER_POOL_TYPE_GPU:
+      case RASTER_BUFFER_PROVIDER_TYPE_GPU:
         Create3dOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create(
-            task_runner_.get(), task_graph_runner_.get(),
+        raster_buffer_provider = GpuRasterBufferProvider::Create(
             context_provider_.get(), resource_provider_.get(), false, 0);
         break;
-      case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
+      case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
         CreateSoftwareOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create(
-            task_runner_.get(), task_graph_runner_.get(),
-            resource_provider_.get());
+        raster_buffer_provider =
+            BitmapRasterBufferProvider::Create(resource_provider_.get());
         break;
     }
 
-    DCHECK(tile_task_worker_pool_);
+    DCHECK(raster_buffer_provider);
+
+    tile_task_manager_ = TileTaskManagerImpl::Create(
+        std::move(raster_buffer_provider), task_graph_runner_.get());
   }
   void TearDown() override {
-    tile_task_worker_pool_->Shutdown();
-    tile_task_worker_pool_->CheckForCompletedTasks();
+    tile_task_manager_->Shutdown();
+    tile_task_manager_->CheckForCompletedTasks();
   }
 
   void RunMessageLoopUntilAllTasksHaveCompleted() {
@@ -299,8 +309,10 @@
   void RunScheduleTasksTest(const std::string& test_name,
                             unsigned num_raster_tasks,
                             unsigned num_image_decode_tasks) {
+    TileTask::Vector image_decode_tasks;
     RasterTaskVector raster_tasks;
-    CreateRasterTasks(num_raster_tasks, num_image_decode_tasks, &raster_tasks);
+    CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
+    CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
 
     // Avoid unnecessary heap allocations by reusing the same graph.
     TaskGraph graph;
@@ -309,13 +321,13 @@
     do {
       graph.Reset();
       BuildTileTaskGraph(&graph, raster_tasks);
-      tile_task_worker_pool_->ScheduleTasks(&graph);
-      tile_task_worker_pool_->CheckForCompletedTasks();
+      tile_task_manager_->ScheduleTasks(&graph);
+      tile_task_manager_->CheckForCompletedTasks();
       timer_.NextLap();
     } while (!timer_.HasTimeLimitExpired());
 
     TaskGraph empty;
-    tile_task_worker_pool_->ScheduleTasks(&empty);
+    tile_task_manager_->ScheduleTasks(&empty);
     RunMessageLoopUntilAllTasksHaveCompleted();
 
     perf_test::PrintResult("schedule_tasks", TestModifierString(), test_name,
@@ -326,9 +338,11 @@
                                      unsigned num_raster_tasks,
                                      unsigned num_image_decode_tasks) {
     const size_t kNumVersions = 2;
+    TileTask::Vector image_decode_tasks[kNumVersions];
     RasterTaskVector raster_tasks[kNumVersions];
     for (size_t i = 0; i < kNumVersions; ++i) {
-      CreateRasterTasks(num_raster_tasks, num_image_decode_tasks,
+      CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]);
+      CreateRasterTasks(num_raster_tasks, image_decode_tasks[i],
                         &raster_tasks[i]);
     }
 
@@ -340,14 +354,14 @@
     do {
       graph.Reset();
       BuildTileTaskGraph(&graph, raster_tasks[count % kNumVersions]);
-      tile_task_worker_pool_->ScheduleTasks(&graph);
-      tile_task_worker_pool_->CheckForCompletedTasks();
+      tile_task_manager_->ScheduleTasks(&graph);
+      tile_task_manager_->CheckForCompletedTasks();
       ++count;
       timer_.NextLap();
     } while (!timer_.HasTimeLimitExpired());
 
     TaskGraph empty;
-    tile_task_worker_pool_->ScheduleTasks(&empty);
+    tile_task_manager_->ScheduleTasks(&empty);
     RunMessageLoopUntilAllTasksHaveCompleted();
 
     perf_test::PrintResult("schedule_alternate_tasks", TestModifierString(),
@@ -357,8 +371,10 @@
   void RunScheduleAndExecuteTasksTest(const std::string& test_name,
                                       unsigned num_raster_tasks,
                                       unsigned num_image_decode_tasks) {
+    TileTask::Vector image_decode_tasks;
     RasterTaskVector raster_tasks;
-    CreateRasterTasks(num_raster_tasks, num_image_decode_tasks, &raster_tasks);
+    CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
+    CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
 
     // Avoid unnecessary heap allocations by reusing the same graph.
     TaskGraph graph;
@@ -367,13 +383,13 @@
     do {
       graph.Reset();
       BuildTileTaskGraph(&graph, raster_tasks);
-      tile_task_worker_pool_->ScheduleTasks(&graph);
+      tile_task_manager_->ScheduleTasks(&graph);
       RunMessageLoopUntilAllTasksHaveCompleted();
       timer_.NextLap();
     } while (!timer_.HasTimeLimitExpired());
 
     TaskGraph empty;
-    tile_task_worker_pool_->ScheduleTasks(&empty);
+    tile_task_manager_->ScheduleTasks(&empty);
     RunMessageLoopUntilAllTasksHaveCompleted();
 
     perf_test::PrintResult("schedule_and_execute_tasks", TestModifierString(),
@@ -398,25 +414,25 @@
 
   std::string TestModifierString() const {
     switch (GetParam()) {
-      case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
-        return std::string("_zero_copy_tile_task_worker_pool");
-      case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
-        return std::string("_one_copy_tile_task_worker_pool");
-      case TILE_TASK_WORKER_POOL_TYPE_GPU:
-        return std::string("_gpu_tile_task_worker_pool");
-      case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
-        return std::string("_bitmap_tile_task_worker_pool");
+      case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY:
+        return std::string("_zero_copy_raster_buffer_provider");
+      case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY:
+        return std::string("_one_copy_raster_buffer_provider");
+      case RASTER_BUFFER_PROVIDER_TYPE_GPU:
+        return std::string("_gpu_raster_buffer_provider");
+      case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
+        return std::string("_bitmap_raster_buffer_provider");
     }
     NOTREACHED();
     return std::string();
   }
 
-  std::unique_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
+  std::unique_ptr<TileTaskManager> tile_task_manager_;
   TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
   TestSharedBitmapManager shared_bitmap_manager_;
 };
 
-TEST_P(TileTaskWorkerPoolPerfTest, ScheduleTasks) {
+TEST_P(RasterBufferProviderPerfTest, ScheduleTasks) {
   RunScheduleTasksTest("1_0", 1, 0);
   RunScheduleTasksTest("32_0", 32, 0);
   RunScheduleTasksTest("1_1", 1, 1);
@@ -425,7 +441,7 @@
   RunScheduleTasksTest("32_4", 32, 4);
 }
 
-TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAlternateTasks) {
+TEST_P(RasterBufferProviderPerfTest, ScheduleAlternateTasks) {
   RunScheduleAlternateTasksTest("1_0", 1, 0);
   RunScheduleAlternateTasksTest("32_0", 32, 0);
   RunScheduleAlternateTasksTest("1_1", 1, 1);
@@ -434,7 +450,7 @@
   RunScheduleAlternateTasksTest("32_4", 32, 4);
 }
 
-TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
+TEST_P(RasterBufferProviderPerfTest, ScheduleAndExecuteTasks) {
   RunScheduleAndExecuteTasksTest("1_0", 1, 0);
   RunScheduleAndExecuteTasksTest("32_0", 32, 0);
   RunScheduleAndExecuteTasksTest("1_1", 1, 1);
@@ -443,15 +459,16 @@
   RunScheduleAndExecuteTasksTest("32_4", 32, 4);
 }
 
-INSTANTIATE_TEST_CASE_P(TileTaskWorkerPoolPerfTests,
-                        TileTaskWorkerPoolPerfTest,
-                        ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
-                                          TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
-                                          TILE_TASK_WORKER_POOL_TYPE_GPU,
-                                          TILE_TASK_WORKER_POOL_TYPE_BITMAP));
+INSTANTIATE_TEST_CASE_P(RasterBufferProviderPerfTests,
+                        RasterBufferProviderPerfTest,
+                        ::testing::Values(RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY,
+                                          RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY,
+                                          RASTER_BUFFER_PROVIDER_TYPE_GPU,
+                                          RASTER_BUFFER_PROVIDER_TYPE_BITMAP));
 
-class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase,
-                                         public testing::Test {
+class RasterBufferProviderCommonPerfTest
+    : public RasterBufferProviderPerfTestBase,
+      public testing::Test {
  public:
   // Overridden from testing::Test:
   void SetUp() override {
@@ -464,8 +481,10 @@
   void RunBuildTileTaskGraphTest(const std::string& test_name,
                                  unsigned num_raster_tasks,
                                  unsigned num_image_decode_tasks) {
+    TileTask::Vector image_decode_tasks;
     RasterTaskVector raster_tasks;
-    CreateRasterTasks(num_raster_tasks, num_image_decode_tasks, &raster_tasks);
+    CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
+    CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
 
     // Avoid unnecessary heap allocations by reusing the same graph.
     TaskGraph graph;
@@ -482,7 +501,7 @@
   }
 };
 
-TEST_F(TileTaskWorkerPoolCommonPerfTest, BuildTileTaskGraph) {
+TEST_F(RasterBufferProviderCommonPerfTest, BuildTileTaskGraph) {
   RunBuildTileTaskGraphTest("1_0", 1, 0);
   RunBuildTileTaskGraphTest("32_0", 32, 0);
   RunBuildTileTaskGraphTest("1_1", 1, 1);
diff --git a/cc/raster/tile_task_worker_pool_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc
similarity index 78%
rename from cc/raster/tile_task_worker_pool_unittest.cc
rename to cc/raster/raster_buffer_provider_unittest.cc
index 53c2ae2..6890dd2 100644
--- a/cc/raster/tile_task_worker_pool_unittest.cc
+++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "cc/raster/tile_task_worker_pool.h"
+#include "cc/raster/raster_buffer_provider.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -18,12 +18,12 @@
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "cc/base/unique_notifier.h"
-#include "cc/raster/bitmap_tile_task_worker_pool.h"
+#include "cc/raster/bitmap_raster_buffer_provider.h"
+#include "cc/raster/gpu_raster_buffer_provider.h"
 #include "cc/raster/gpu_rasterizer.h"
-#include "cc/raster/gpu_tile_task_worker_pool.h"
-#include "cc/raster/one_copy_tile_task_worker_pool.h"
+#include "cc/raster/one_copy_raster_buffer_provider.h"
 #include "cc/raster/synchronous_task_graph_runner.h"
-#include "cc/raster/zero_copy_tile_task_worker_pool.h"
+#include "cc/raster/zero_copy_raster_buffer_provider.h"
 #include "cc/resources/resource_pool.h"
 #include "cc/resources/resource_provider.h"
 #include "cc/resources/scoped_resource.h"
@@ -34,6 +34,7 @@
 #include "cc/test/test_gpu_memory_buffer_manager.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_web_graphics_context_3d.h"
+#include "cc/tiles/tile_task_manager.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -43,11 +44,11 @@
 const size_t kMaxBytesPerCopyOperation = 1000U;
 const size_t kMaxStagingBuffers = 32U;
 
-enum TileTaskWorkerPoolType {
-  TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
-  TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
-  TILE_TASK_WORKER_POOL_TYPE_GPU,
-  TILE_TASK_WORKER_POOL_TYPE_BITMAP
+enum RasterBufferProviderType {
+  RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY,
+  RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY,
+  RASTER_BUFFER_PROVIDER_TYPE_GPU,
+  RASTER_BUFFER_PROVIDER_TYPE_BITMAP
 };
 
 class TestRasterTaskImpl : public TileTask {
@@ -116,8 +117,8 @@
   DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterTaskImpl);
 };
 
-class TileTaskWorkerPoolTest
-    : public testing::TestWithParam<TileTaskWorkerPoolType> {
+class RasterBufferProviderTest
+    : public testing::TestWithParam<RasterBufferProviderType> {
  public:
   struct RasterTaskResult {
     unsigned id;
@@ -128,64 +129,63 @@
 
   enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL };
 
-  TileTaskWorkerPoolTest()
+  RasterBufferProviderTest()
       : context_provider_(TestContextProvider::Create()),
         worker_context_provider_(TestContextProvider::CreateWorker()),
         all_tile_tasks_finished_(
-            base::ThreadTaskRunnerHandle::Get()
-                .get(),
-            base::Bind(&TileTaskWorkerPoolTest::AllTileTasksFinished,
+            base::ThreadTaskRunnerHandle::Get().get(),
+            base::Bind(&RasterBufferProviderTest::AllTileTasksFinished,
                        base::Unretained(this))),
         timeout_seconds_(5),
         timed_out_(false) {}
 
   // Overridden from testing::Test:
   void SetUp() override {
+    std::unique_ptr<RasterBufferProvider> raster_buffer_provider;
     switch (GetParam()) {
-      case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
+      case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY:
         Create3dOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create(
-            base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_,
+        raster_buffer_provider = ZeroCopyRasterBufferProvider::Create(
             resource_provider_.get(), PlatformColor::BestTextureFormat());
         break;
-      case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
+      case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY:
         Create3dOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
-            base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_,
-            context_provider_.get(), resource_provider_.get(),
-            kMaxBytesPerCopyOperation, false, kMaxStagingBuffers,
-            PlatformColor::BestTextureFormat());
+        raster_buffer_provider = OneCopyRasterBufferProvider::Create(
+            base::ThreadTaskRunnerHandle::Get().get(), context_provider_.get(),
+            resource_provider_.get(), kMaxBytesPerCopyOperation, false,
+            kMaxStagingBuffers, PlatformColor::BestTextureFormat());
         break;
-      case TILE_TASK_WORKER_POOL_TYPE_GPU:
+      case RASTER_BUFFER_PROVIDER_TYPE_GPU:
         Create3dOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create(
-            base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_,
+        raster_buffer_provider = GpuRasterBufferProvider::Create(
             context_provider_.get(), resource_provider_.get(), false, 0);
         break;
-      case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
+      case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
         CreateSoftwareOutputSurfaceAndResourceProvider();
-        tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create(
-            base::ThreadTaskRunnerHandle::Get().get(), &task_graph_runner_,
-            resource_provider_.get());
+        raster_buffer_provider =
+            BitmapRasterBufferProvider::Create(resource_provider_.get());
         break;
     }
 
-    DCHECK(tile_task_worker_pool_);
+    DCHECK(raster_buffer_provider);
+
+    tile_task_manager_ = TileTaskManagerImpl::Create(
+        std::move(raster_buffer_provider), &task_graph_runner_);
   }
 
   void TearDown() override {
-    tile_task_worker_pool_->Shutdown();
-    tile_task_worker_pool_->CheckForCompletedTasks();
+    tile_task_manager_->Shutdown();
+    tile_task_manager_->CheckForCompletedTasks();
   }
 
   void AllTileTasksFinished() {
-    tile_task_worker_pool_->CheckForCompletedTasks();
+    tile_task_manager_->CheckForCompletedTasks();
     base::MessageLoop::current()->QuitWhenIdle();
   }
 
   void RunMessageLoopUntilAllTasksHaveCompleted() {
     task_graph_runner_.RunUntilIdle();
-    tile_task_worker_pool_->CheckForCompletedTasks();
+    tile_task_manager_->CheckForCompletedTasks();
   }
 
   void ScheduleTasks() {
@@ -199,7 +199,7 @@
                                 0 /* dependencies */);
     }
 
-    tile_task_worker_pool_->ScheduleTasks(&graph_);
+    tile_task_manager_->ScheduleTasks(&graph_);
   }
 
   void AppendTask(unsigned id, const gfx::Size& size) {
@@ -212,7 +212,7 @@
     TileTask::Vector empty;
     tasks_.push_back(new TestRasterTaskImpl(
         const_resource,
-        base::Bind(&TileTaskWorkerPoolTest::OnTaskCompleted,
+        base::Bind(&RasterBufferProviderTest::OnTaskCompleted,
                    base::Unretained(this), base::Passed(&resource), id),
         &empty));
   }
@@ -231,7 +231,7 @@
     TileTask::Vector empty;
     tasks_.push_back(new BlockingTestRasterTaskImpl(
         const_resource,
-        base::Bind(&TileTaskWorkerPoolTest::OnTaskCompleted,
+        base::Bind(&RasterBufferProviderTest::OnTaskCompleted,
                    base::Unretained(this), base::Passed(&resource), id),
         lock, &empty));
   }
@@ -287,7 +287,7 @@
   FakeOutputSurfaceClient output_surface_client_;
   std::unique_ptr<FakeOutputSurface> output_surface_;
   std::unique_ptr<ResourceProvider> resource_provider_;
-  std::unique_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
+  std::unique_ptr<TileTaskManager> tile_task_manager_;
   TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
   TestSharedBitmapManager shared_bitmap_manager_;
   SynchronousTaskGraphRunner task_graph_runner_;
@@ -300,7 +300,7 @@
   TaskGraph graph_;
 };
 
-TEST_P(TileTaskWorkerPoolTest, Basic) {
+TEST_P(RasterBufferProviderTest, Basic) {
   AppendTask(0u);
   AppendTask(1u);
   ScheduleTasks();
@@ -312,8 +312,8 @@
   EXPECT_FALSE(completed_tasks()[1].canceled);
 }
 
-TEST_P(TileTaskWorkerPoolTest, FailedMapResource) {
-  if (GetParam() == TILE_TASK_WORKER_POOL_TYPE_BITMAP)
+TEST_P(RasterBufferProviderTest, FailedMapResource) {
+  if (GetParam() == RASTER_BUFFER_PROVIDER_TYPE_BITMAP)
     return;
 
   TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d();
@@ -329,7 +329,7 @@
 
 // This test checks that replacing a pending raster task with another does
 // not prevent the DidFinishRunningTileTasks notification from being sent.
-TEST_P(TileTaskWorkerPoolTest, FalseThrottling) {
+TEST_P(RasterBufferProviderTest, FalseThrottling) {
   base::Lock lock;
 
   // Schedule a task that is prevented from completing with a lock.
@@ -351,7 +351,7 @@
   RunMessageLoopUntilAllTasksHaveCompleted();
 }
 
-TEST_P(TileTaskWorkerPoolTest, LostContext) {
+TEST_P(RasterBufferProviderTest, LostContext) {
   LoseContext(output_surface_->context_provider());
   LoseContext(output_surface_->worker_context_provider());
 
@@ -366,12 +366,12 @@
   EXPECT_FALSE(completed_tasks()[1].canceled);
 }
 
-INSTANTIATE_TEST_CASE_P(TileTaskWorkerPoolTests,
-                        TileTaskWorkerPoolTest,
-                        ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
-                                          TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
-                                          TILE_TASK_WORKER_POOL_TYPE_GPU,
-                                          TILE_TASK_WORKER_POOL_TYPE_BITMAP));
+INSTANTIATE_TEST_CASE_P(RasterBufferProviderTests,
+                        RasterBufferProviderTest,
+                        ::testing::Values(RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY,
+                                          RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY,
+                                          RASTER_BUFFER_PROVIDER_TYPE_GPU,
+                                          RASTER_BUFFER_PROVIDER_TYPE_BITMAP));
 
 }  // namespace
 }  // namespace cc
diff --git a/cc/raster/tile_task_worker_pool.h b/cc/raster/tile_task_worker_pool.h
deleted file mode 100644
index 9542d02..0000000
--- a/cc/raster/tile_task_worker_pool.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RASTER_TILE_TASK_WORKER_POOL_H_
-#define CC_RASTER_TILE_TASK_WORKER_POOL_H_
-
-#include <stddef.h>
-
-#include "cc/playback/raster_source.h"
-#include "cc/raster/raster_buffer.h"
-#include "cc/raster/task_graph_runner.h"
-#include "cc/raster/tile_task.h"
-#include "cc/resources/resource_format.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace base {
-class SequencedTaskRunner;
-}
-
-namespace cc {
-class RenderingStatsInstrumentation;
-
-// This class provides the wrapper over TaskGraphRunner for scheduling and
-// collecting tasks. The client can call CheckForCompletedTasks() at any time to
-// process all completed tasks at the moment that have finished running or
-// cancelled.
-class CC_EXPORT TileTaskWorkerPool {
- public:
-  TileTaskWorkerPool();
-  virtual ~TileTaskWorkerPool();
-
-  // Utility function that can be used to call ::ScheduleOnOriginThread() for
-  // each task in |graph|.
-  static void ScheduleTasksOnOriginThread(RasterBufferProvider* provider,
-                                          TaskGraph* graph);
-
-  // Utility function that will create a temporary bitmap and copy pixels to
-  // |memory| when necessary. The |canvas_bitmap_rect| is the rect of the bitmap
-  // being played back in the pixel space of the source, ie a rect in the source
-  // that will cover the resulting |memory|. The |canvas_playback_rect| can be a
-  // smaller contained rect inside the |canvas_bitmap_rect| if the |memory| is
-  // already partially complete, and only the subrect needs to be played back.
-  static void PlaybackToMemory(
-      void* memory,
-      ResourceFormat format,
-      const gfx::Size& size,
-      size_t stride,
-      const RasterSource* raster_source,
-      const gfx::Rect& canvas_bitmap_rect,
-      const gfx::Rect& canvas_playback_rect,
-      float scale,
-      const RasterSource::PlaybackSettings& playback_settings);
-
-  // Tells the worker pool to shutdown after canceling all previously scheduled
-  // tasks. Reply callbacks are still guaranteed to run when
-  // CheckForCompletedTasks() is called.
-  virtual void Shutdown() = 0;
-
-  // Schedule running of tile tasks in |graph| and all dependencies.
-  // Previously scheduled tasks that are not in |graph| will be canceled unless
-  // already running. Once scheduled, reply callbacks are guaranteed to run for
-  // all tasks even if they later get canceled by another call to
-  // ScheduleTasks().
-  virtual void ScheduleTasks(TaskGraph* graph) = 0;
-
-  // Check for completed tasks and dispatch reply callbacks.
-  virtual void CheckForCompletedTasks() = 0;
-
-  // Returns the format to use for the tiles.
-  virtual ResourceFormat GetResourceFormat(bool must_support_alpha) const = 0;
-
-  // Determine if the resource requires swizzling.
-  virtual bool GetResourceRequiresSwizzle(bool must_support_alpha) const = 0;
-
-  // Downcasting routine for RasterBufferProvider interface.
-  virtual RasterBufferProvider* AsRasterBufferProvider() = 0;
-
- protected:
-  // Check if resource format matches output format.
-  static bool ResourceFormatRequiresSwizzle(ResourceFormat format);
-};
-
-}  // namespace cc
-
-#endif  // CC_RASTER_TILE_TASK_WORKER_POOL_H_
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc
new file mode 100644
index 0000000..93e8d7e
--- /dev/null
+++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -0,0 +1,120 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/raster/zero_copy_raster_buffer_provider.h"
+
+#include <stdint.h>
+
+#include <algorithm>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "cc/debug/traced_value.h"
+#include "cc/resources/platform_color.h"
+#include "cc/resources/resource.h"
+#include "ui/gfx/buffer_format_util.h"
+#include "ui/gfx/gpu_memory_buffer.h"
+
+namespace cc {
+namespace {
+
+class RasterBufferImpl : public RasterBuffer {
+ public:
+  RasterBufferImpl(ResourceProvider* resource_provider,
+                   const Resource* resource)
+      : lock_(resource_provider, resource->id()), resource_(resource) {}
+
+  // Overridden from RasterBuffer:
+  void Playback(
+      const RasterSource* raster_source,
+      const gfx::Rect& raster_full_rect,
+      const gfx::Rect& raster_dirty_rect,
+      uint64_t new_content_id,
+      float scale,
+      const RasterSource::PlaybackSettings& playback_settings) override {
+    gfx::GpuMemoryBuffer* buffer = lock_.GetGpuMemoryBuffer();
+    if (!buffer)
+      return;
+
+    DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat()));
+    bool rv = buffer->Map();
+    DCHECK(rv);
+    DCHECK(buffer->memory(0));
+    // RasterBufferProvider::PlaybackToMemory only supports unsigned strides.
+    DCHECK_GE(buffer->stride(0), 0);
+
+    // TODO(danakj): Implement partial raster with raster_dirty_rect.
+    RasterBufferProvider::PlaybackToMemory(
+        buffer->memory(0), resource_->format(), resource_->size(),
+        buffer->stride(0), raster_source, raster_full_rect, raster_full_rect,
+        scale, playback_settings);
+    buffer->Unmap();
+  }
+
+ private:
+  ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock_;
+  const Resource* resource_;
+
+  DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
+};
+
+}  // namespace
+
+// static
+std::unique_ptr<RasterBufferProvider> ZeroCopyRasterBufferProvider::Create(
+    ResourceProvider* resource_provider,
+    ResourceFormat preferred_tile_format) {
+  return base::WrapUnique<RasterBufferProvider>(
+      new ZeroCopyRasterBufferProvider(resource_provider,
+                                       preferred_tile_format));
+}
+
+ZeroCopyRasterBufferProvider::ZeroCopyRasterBufferProvider(
+    ResourceProvider* resource_provider,
+    ResourceFormat preferred_tile_format)
+    : resource_provider_(resource_provider),
+      preferred_tile_format_(preferred_tile_format) {}
+
+ZeroCopyRasterBufferProvider::~ZeroCopyRasterBufferProvider() {}
+
+std::unique_ptr<RasterBuffer>
+ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
+    const Resource* resource,
+    uint64_t resource_content_id,
+    uint64_t previous_content_id) {
+  return base::WrapUnique<RasterBuffer>(
+      new RasterBufferImpl(resource_provider_, resource));
+}
+
+void ZeroCopyRasterBufferProvider::ReleaseBufferForRaster(
+    std::unique_ptr<RasterBuffer> buffer) {
+  // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
+}
+
+void ZeroCopyRasterBufferProvider::OrderingBarrier() {
+  // No need to sync resources as this provider does not use GL context.
+}
+
+ResourceFormat ZeroCopyRasterBufferProvider::GetResourceFormat(
+    bool must_support_alpha) const {
+  if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) &&
+      (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
+       !must_support_alpha)) {
+    return preferred_tile_format_;
+  }
+
+  return resource_provider_->best_texture_format();
+}
+
+bool ZeroCopyRasterBufferProvider::GetResourceRequiresSwizzle(
+    bool must_support_alpha) const {
+  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
+}
+
+void ZeroCopyRasterBufferProvider::Shutdown() {}
+
+}  // namespace cc
diff --git a/cc/raster/zero_copy_raster_buffer_provider.h b/cc/raster/zero_copy_raster_buffer_provider.h
new file mode 100644
index 0000000..f813a59b
--- /dev/null
+++ b/cc/raster/zero_copy_raster_buffer_provider.h
@@ -0,0 +1,59 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_RASTER_ZERO_COPY_RASTER_BUFFER_PROVIDER_H_
+#define CC_RASTER_ZERO_COPY_RASTER_BUFFER_PROVIDER_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
+#include "cc/raster/raster_buffer_provider.h"
+
+namespace base {
+namespace trace_event {
+class ConvertableToTraceFormat;
+}
+}
+
+namespace cc {
+class ResourceProvider;
+
+class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
+ public:
+  ~ZeroCopyRasterBufferProvider() override;
+
+  static std::unique_ptr<RasterBufferProvider> Create(
+      ResourceProvider* resource_provider,
+      ResourceFormat preferred_tile_format);
+
+  // Overridden from RasterBufferProvider:
+  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
+      const Resource* resource,
+      uint64_t resource_content_id,
+      uint64_t previous_content_id) override;
+  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
+  void OrderingBarrier() override;
+  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
+  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
+  void Shutdown() override;
+
+ protected:
+  ZeroCopyRasterBufferProvider(ResourceProvider* resource_provider,
+                               ResourceFormat preferred_tile_format);
+
+ private:
+  std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
+      const;
+
+  ResourceProvider* resource_provider_;
+  ResourceFormat preferred_tile_format_;
+
+  DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferProvider);
+};
+
+}  // namespace cc
+
+#endif  // CC_RASTER_ZERO_COPY_RASTER_BUFFER_PROVIDER_H_
diff --git a/cc/raster/zero_copy_tile_task_worker_pool.cc b/cc/raster/zero_copy_tile_task_worker_pool.cc
deleted file mode 100644
index e423450b..0000000
--- a/cc/raster/zero_copy_tile_task_worker_pool.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/raster/zero_copy_tile_task_worker_pool.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "cc/debug/traced_value.h"
-#include "cc/resources/platform_color.h"
-#include "cc/resources/resource.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace cc {
-namespace {
-
-class RasterBufferImpl : public RasterBuffer {
- public:
-  RasterBufferImpl(ResourceProvider* resource_provider,
-                   const Resource* resource)
-      : lock_(resource_provider, resource->id()), resource_(resource) {}
-
-  // Overridden from RasterBuffer:
-  void Playback(
-      const RasterSource* raster_source,
-      const gfx::Rect& raster_full_rect,
-      const gfx::Rect& raster_dirty_rect,
-      uint64_t new_content_id,
-      float scale,
-      const RasterSource::PlaybackSettings& playback_settings) override {
-    gfx::GpuMemoryBuffer* buffer = lock_.GetGpuMemoryBuffer();
-    if (!buffer)
-      return;
-
-    DCHECK_EQ(1u, gfx::NumberOfPlanesForBufferFormat(buffer->GetFormat()));
-    bool rv = buffer->Map();
-    DCHECK(rv);
-    DCHECK(buffer->memory(0));
-    // TileTaskWorkerPool::PlaybackToMemory only supports unsigned strides.
-    DCHECK_GE(buffer->stride(0), 0);
-
-    // TODO(danakj): Implement partial raster with raster_dirty_rect.
-    TileTaskWorkerPool::PlaybackToMemory(
-        buffer->memory(0), resource_->format(), resource_->size(),
-        buffer->stride(0), raster_source, raster_full_rect, raster_full_rect,
-        scale, playback_settings);
-    buffer->Unmap();
-  }
-
- private:
-  ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock_;
-  const Resource* resource_;
-
-  DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
-};
-
-}  // namespace
-
-// static
-std::unique_ptr<TileTaskWorkerPool> ZeroCopyTileTaskWorkerPool::Create(
-    base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
-    ResourceProvider* resource_provider,
-    ResourceFormat preferred_tile_format) {
-  return base::WrapUnique<TileTaskWorkerPool>(
-      new ZeroCopyTileTaskWorkerPool(task_runner, task_graph_runner,
-                                     resource_provider, preferred_tile_format));
-}
-
-ZeroCopyTileTaskWorkerPool::ZeroCopyTileTaskWorkerPool(
-    base::SequencedTaskRunner* task_runner,
-    TaskGraphRunner* task_graph_runner,
-    ResourceProvider* resource_provider,
-    ResourceFormat preferred_tile_format)
-    : task_runner_(task_runner),
-      task_graph_runner_(task_graph_runner),
-      namespace_token_(task_graph_runner->GetNamespaceToken()),
-      resource_provider_(resource_provider),
-      preferred_tile_format_(preferred_tile_format) {}
-
-ZeroCopyTileTaskWorkerPool::~ZeroCopyTileTaskWorkerPool() {
-}
-
-void ZeroCopyTileTaskWorkerPool::Shutdown() {
-  TRACE_EVENT0("cc", "ZeroCopyTileTaskWorkerPool::Shutdown");
-
-  TaskGraph empty;
-  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
-  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
-}
-
-void ZeroCopyTileTaskWorkerPool::ScheduleTasks(TaskGraph* graph) {
-  TRACE_EVENT0("cc", "ZeroCopyTileTaskWorkerPool::ScheduleTasks");
-
-  ScheduleTasksOnOriginThread(this, graph);
-  task_graph_runner_->ScheduleTasks(namespace_token_, graph);
-}
-
-void ZeroCopyTileTaskWorkerPool::CheckForCompletedTasks() {
-  TRACE_EVENT0("cc", "ZeroCopyTileTaskWorkerPool::CheckForCompletedTasks");
-
-  task_graph_runner_->CollectCompletedTasks(namespace_token_,
-                                            &completed_tasks_);
-  for (Task::Vector::const_iterator it = completed_tasks_.begin();
-       it != completed_tasks_.end(); ++it) {
-    TileTask* task = static_cast<TileTask*>(it->get());
-
-    task->WillComplete();
-    task->CompleteOnOriginThread(this);
-    task->DidComplete();
-  }
-  completed_tasks_.clear();
-}
-
-ResourceFormat ZeroCopyTileTaskWorkerPool::GetResourceFormat(
-    bool must_support_alpha) const {
-  if (resource_provider_->IsResourceFormatSupported(preferred_tile_format_) &&
-      (DoesResourceFormatSupportAlpha(preferred_tile_format_) ||
-       !must_support_alpha)) {
-    return preferred_tile_format_;
-  }
-
-  return resource_provider_->best_texture_format();
-}
-
-bool ZeroCopyTileTaskWorkerPool::GetResourceRequiresSwizzle(
-    bool must_support_alpha) const {
-  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
-}
-
-RasterBufferProvider* ZeroCopyTileTaskWorkerPool::AsRasterBufferProvider() {
-  return this;
-}
-
-std::unique_ptr<RasterBuffer>
-ZeroCopyTileTaskWorkerPool::AcquireBufferForRaster(
-    const Resource* resource,
-    uint64_t resource_content_id,
-    uint64_t previous_content_id) {
-  return base::WrapUnique<RasterBuffer>(
-      new RasterBufferImpl(resource_provider_, resource));
-}
-
-void ZeroCopyTileTaskWorkerPool::ReleaseBufferForRaster(
-    std::unique_ptr<RasterBuffer> buffer) {
-  // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
-}
-
-}  // namespace cc
diff --git a/cc/raster/zero_copy_tile_task_worker_pool.h b/cc/raster/zero_copy_tile_task_worker_pool.h
deleted file mode 100644
index 7a78233..0000000
--- a/cc/raster/zero_copy_tile_task_worker_pool.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_RASTER_ZERO_COPY_TILE_TASK_WORKER_POOL_H_
-#define CC_RASTER_ZERO_COPY_TILE_TASK_WORKER_POOL_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/values.h"
-#include "cc/raster/tile_task_worker_pool.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-}
-}
-
-namespace cc {
-class ResourceProvider;
-
-class CC_EXPORT ZeroCopyTileTaskWorkerPool : public TileTaskWorkerPool,
-                                             public RasterBufferProvider {
- public:
-  ~ZeroCopyTileTaskWorkerPool() override;
-
-  static std::unique_ptr<TileTaskWorkerPool> Create(
-      base::SequencedTaskRunner* task_runner,
-      TaskGraphRunner* task_graph_runner,
-      ResourceProvider* resource_provider,
-      ResourceFormat preferred_tile_format);
-
-  // Overridden from TileTaskWorkerPool:
-  void Shutdown() override;
-  void ScheduleTasks(TaskGraph* graph) override;
-  void CheckForCompletedTasks() override;
-  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
-  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
-  RasterBufferProvider* AsRasterBufferProvider() override;
-
-  // Overridden from RasterBufferProvider:
-  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
-      const Resource* resource,
-      uint64_t resource_content_id,
-      uint64_t previous_content_id) override;
-  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
-
- protected:
-  ZeroCopyTileTaskWorkerPool(base::SequencedTaskRunner* task_runner,
-                             TaskGraphRunner* task_graph_runner,
-                             ResourceProvider* resource_provider,
-                             ResourceFormat preferred_tile_format);
-
- private:
-  std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
-      const;
-
-  scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  TaskGraphRunner* task_graph_runner_;
-  const NamespaceToken namespace_token_;
-  ResourceProvider* resource_provider_;
-
-  ResourceFormat preferred_tile_format_;
-
-  Task::Vector completed_tasks_;
-
-  DISALLOW_COPY_AND_ASSIGN(ZeroCopyTileTaskWorkerPool);
-};
-
-}  // namespace cc
-
-#endif  // CC_RASTER_ZERO_COPY_TILE_TASK_WORKER_POOL_H_
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc
index 7dbfaae..01f48140 100644
--- a/cc/scheduler/begin_frame_source.cc
+++ b/cc/scheduler/begin_frame_source.cc
@@ -48,14 +48,6 @@
   }
 }
 
-void BeginFrameObserverBase::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->BeginDictionary("last_begin_frame_args_");
-  last_begin_frame_args_.AsValueInto(dict);
-  dict->EndDictionary();
-  dict->SetInteger("dropped_begin_frame_args_", dropped_begin_frame_args_);
-}
-
 // BeginFrameSourceBase ------------------------------------------------------
 BeginFrameSourceBase::BeginFrameSourceBase()
     : paused_(false), inside_as_value_into_(false) {}
@@ -103,29 +95,6 @@
     obs->OnBeginFrameSourcePausedChanged(paused_);
 }
 
-// Tracing support
-void BeginFrameSourceBase::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  // As the observer might try to trace the source, prevent an infinte loop
-  // from occuring.
-  if (inside_as_value_into_) {
-    dict->SetString("observer", "<loop detected>");
-    return;
-  }
-
-  {
-    base::AutoReset<bool> prevent_loops(
-        const_cast<bool*>(&inside_as_value_into_), true);
-    dict->BeginArray("observers");
-    for (const BeginFrameObserver* obs : observers_) {
-      dict->BeginDictionary();
-      obs->AsValueInto(dict);
-      dict->EndDictionary();
-    }
-    dict->EndArray();
-  }
-}
-
 // BackToBackBeginFrameSource --------------------------------------------
 BackToBackBeginFrameSource::BackToBackBeginFrameSource(
     base::SingleThreadTaskRunner* task_runner)
@@ -190,13 +159,6 @@
     obs->OnBeginFrame(args);
 }
 
-// Tracing support
-void BackToBackBeginFrameSource::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->SetString("type", "BackToBackBeginFrameSource");
-  BeginFrameSourceBase::AsValueInto(dict);
-}
-
 // SyntheticBeginFrameSource ---------------------------------------------
 SyntheticBeginFrameSource::SyntheticBeginFrameSource(
     base::SingleThreadTaskRunner* task_runner,
@@ -262,15 +224,4 @@
   }
 }
 
-// Tracing support
-void SyntheticBeginFrameSource::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->SetString("type", "SyntheticBeginFrameSource");
-  BeginFrameSourceBase::AsValueInto(dict);
-
-  dict->BeginDictionary("time_source");
-  time_source_->AsValueInto(dict);
-  dict->EndDictionary();
-}
-
 }  // namespace cc
diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h
index 4d8d30e..5779966 100644
--- a/cc/scheduler/begin_frame_source.h
+++ b/cc/scheduler/begin_frame_source.h
@@ -61,9 +61,6 @@
   virtual const BeginFrameArgs& LastUsedBeginFrameArgs() const = 0;
 
   virtual void OnBeginFrameSourcePausedChanged(bool paused) = 0;
-
-  // Tracing support
-  virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0;
 };
 
 // Simple base class which implements a BeginFrameObserver which checks the
@@ -87,9 +84,6 @@
   void OnBeginFrame(const BeginFrameArgs& args) override;
   const BeginFrameArgs& LastUsedBeginFrameArgs() const override;
 
-  // Outputs last_begin_frame_args_
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
  protected:
   // Subclasses should override this method!
   // Return true if the given argument is (or will be) used.
@@ -126,10 +120,6 @@
   // should shut down its timers, disable vsync, etc.
   virtual void AddObserver(BeginFrameObserver* obs) = 0;
   virtual void RemoveObserver(BeginFrameObserver* obs) = 0;
-
-  // Tracing support - Recommend (but not required) to call this implementation
-  // in any override.
-  virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0;
 };
 
 // Simple base class which implements a BeginFrameSource.
@@ -137,8 +127,6 @@
 //  - Implement the pure virtual (Set)NeedsBeginFrames methods from
 //    BeginFrameSource.
 //  - Use the CallOnBeginFrame method to call to the observer(s).
-//  - Recommended (but not required) to call BeginFrameSourceBase::AsValueInto
-//    in their own AsValueInto implementation.
 class CC_EXPORT BeginFrameSourceBase : public BeginFrameSource {
  public:
   ~BeginFrameSourceBase() override;
@@ -149,10 +137,6 @@
   void AddObserver(BeginFrameObserver* obs) override;
   void RemoveObserver(BeginFrameObserver* obs) override;
 
-  // Tracing support - Recommend (but not required) to call this implementation
-  // in any override.
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
  protected:
   BeginFrameSourceBase();
 
@@ -190,9 +174,6 @@
   void DidFinishFrame(BeginFrameObserver* obs,
                       size_t remaining_frames) override;
 
-  // Tracing
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
  protected:
   virtual base::TimeTicks Now();  // Now overridable for testing
 
@@ -227,9 +208,6 @@
   void AddObserver(BeginFrameObserver* obs) override;
   void OnNeedsBeginFramesChanged(bool needs_begin_frames) override;
 
-  // Tracing
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
   // DelayBasedTimeSourceClient
   void OnTimerTick() override;
 
diff --git a/cc/scheduler/begin_frame_source_unittest.cc b/cc/scheduler/begin_frame_source_unittest.cc
index 684b3233..e2390ef 100644
--- a/cc/scheduler/begin_frame_source_unittest.cc
+++ b/cc/scheduler/begin_frame_source_unittest.cc
@@ -173,38 +173,6 @@
   source.RemoveObserver(&obs2);
 }
 
-class LoopingBeginFrameObserver : public BeginFrameObserverBase {
- public:
-  BeginFrameSource* source_;
-
-  void AsValueInto(base::trace_event::TracedValue* dict) const override {
-    dict->SetString("type", "LoopingBeginFrameObserver");
-    dict->BeginDictionary("source");
-    source_->AsValueInto(dict);
-    dict->EndDictionary();
-  }
-
- protected:
-  // BeginFrameObserverBase
-  bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override {
-    return true;
-  }
-
-  void OnBeginFrameSourcePausedChanged(bool paused) override {}
-};
-
-TEST(BeginFrameSourceBaseTest, DetectAsValueIntoLoop) {
-  LoopingBeginFrameObserver obs;
-  FakeBeginFrameSource source;
-
-  obs.source_ = &source;
-  source.AddObserver(&obs);
-
-  std::unique_ptr<base::trace_event::TracedValue> state(
-      new base::trace_event::TracedValue());
-  source.AsValueInto(state.get());
-}
-
 // BackToBackBeginFrameSource testing -----------------------------------------
 class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource {
  public:
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index a0bb050..6696c29a 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -732,28 +732,12 @@
 Scheduler::AsValue() const {
   std::unique_ptr<base::trace_event::TracedValue> state(
       new base::trace_event::TracedValue());
-  AsValueInto(state.get());
-  return std::move(state);
-}
-
-void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
   base::TimeTicks now = Now();
 
   state->BeginDictionary("state_machine");
-  state_machine_.AsValueInto(state);
+  state_machine_.AsValueInto(state.get());
   state->EndDictionary();
 
-  // Only trace frame sources when explicitly enabled - http://crbug.com/420607
-  bool frame_tracing_enabled = false;
-  TRACE_EVENT_CATEGORY_GROUP_ENABLED(
-      TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
-      &frame_tracing_enabled);
-  if (frame_tracing_enabled && begin_frame_source_) {
-    state->BeginDictionary("begin_frame_source_");
-    begin_frame_source_->AsValueInto(state);
-    state->EndDictionary();
-  }
-
   state->BeginDictionary("scheduler_state");
   state->SetBoolean("throttle_frame_production_",
                     settings_.throttle_frame_production);
@@ -771,7 +755,7 @@
                    SchedulerStateMachine::ActionToString(inside_action_));
 
   state->BeginDictionary("begin_impl_frame_args");
-  begin_impl_frame_tracker_.AsValueInto(now, state);
+  begin_impl_frame_tracker_.AsValueInto(now, state.get());
   state->EndDictionary();
 
   state->SetString("begin_impl_frame_deadline_mode_",
@@ -780,8 +764,10 @@
   state->EndDictionary();
 
   state->BeginDictionary("compositor_timing_history");
-  compositor_timing_history_->AsValueInto(state);
+  compositor_timing_history_->AsValueInto(state.get());
   state->EndDictionary();
+
+  return std::move(state);
 }
 
 void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() {
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index 0a3ace7..017307e 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -135,7 +135,6 @@
   void SetDeferCommits(bool defer_commits);
 
   std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-  void AsValueInto(base::trace_event::TracedValue* value) const override;
 
   void SetVideoNeedsBeginFrames(bool video_needs_begin_frames);
 
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc
index 16498a3..f40b7dcb 100644
--- a/cc/surfaces/display.cc
+++ b/cc/surfaces/display.cc
@@ -36,7 +36,6 @@
                       size_t remaining_frames) override{};
   void AddObserver(cc::BeginFrameObserver* obs) override{};
   void RemoveObserver(cc::BeginFrameObserver* obs) override{};
-  void AsValueInto(base::trace_event::TracedValue* dict) const override{};
 };
 
 }  // namespace
diff --git a/cc/surfaces/surface_manager_unittest.cc b/cc/surfaces/surface_manager_unittest.cc
index e262d841..05edb02 100644
--- a/cc/surfaces/surface_manager_unittest.cc
+++ b/cc/surfaces/surface_manager_unittest.cc
@@ -62,7 +62,6 @@
                       size_t remaining_frames) override {}
   void AddObserver(BeginFrameObserver* obs) override {}
   void RemoveObserver(BeginFrameObserver* obs) override {}
-  void AsValueInto(base::trace_event::TracedValue* dict) const override {}
 };
 
 class SurfaceManagerTest : public testing::Test {
diff --git a/cc/test/fake_raster_buffer_provider.cc b/cc/test/fake_raster_buffer_provider.cc
new file mode 100644
index 0000000..9657b6be
--- /dev/null
+++ b/cc/test/fake_raster_buffer_provider.cc
@@ -0,0 +1,38 @@
+// 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 "cc/test/fake_raster_buffer_provider.h"
+
+namespace cc {
+
+FakeRasterBufferProviderImpl::FakeRasterBufferProviderImpl() {}
+
+FakeRasterBufferProviderImpl::~FakeRasterBufferProviderImpl() {}
+
+std::unique_ptr<RasterBuffer>
+FakeRasterBufferProviderImpl::AcquireBufferForRaster(
+    const Resource* resource,
+    uint64_t resource_content_id,
+    uint64_t previous_content_id) {
+  return nullptr;
+}
+
+void FakeRasterBufferProviderImpl::ReleaseBufferForRaster(
+    std::unique_ptr<RasterBuffer> buffer) {}
+
+void FakeRasterBufferProviderImpl::OrderingBarrier() {}
+
+ResourceFormat FakeRasterBufferProviderImpl::GetResourceFormat(
+    bool must_support_alpha) const {
+  return ResourceFormat::RGBA_8888;
+}
+
+bool FakeRasterBufferProviderImpl::GetResourceRequiresSwizzle(
+    bool must_support_alpha) const {
+  return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
+}
+
+void FakeRasterBufferProviderImpl::Shutdown() {}
+
+}  // namespace cc
diff --git a/cc/test/fake_raster_buffer_provider.h b/cc/test/fake_raster_buffer_provider.h
new file mode 100644
index 0000000..00ab04a6
--- /dev/null
+++ b/cc/test/fake_raster_buffer_provider.h
@@ -0,0 +1,32 @@
+// 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 CC_TEST_FAKE_RASTER_BUFFER_PROVIDER_H_
+#define CC_TEST_FAKE_RASTER_BUFFER_PROVIDER_H_
+
+#include "cc/raster/raster_buffer_provider.h"
+
+namespace cc {
+
+// Fake RasterBufferProvider that just no-ops all calls.
+class FakeRasterBufferProviderImpl : public RasterBufferProvider {
+ public:
+  FakeRasterBufferProviderImpl();
+  ~FakeRasterBufferProviderImpl() override;
+
+  // RasterBufferProvider methods.
+  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
+      const Resource* resource,
+      uint64_t resource_content_id,
+      uint64_t previous_content_id) override;
+  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override;
+  void OrderingBarrier() override;
+  ResourceFormat GetResourceFormat(bool must_support_alpha) const override;
+  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override;
+  void Shutdown() override;
+};
+
+}  // namespace cc
+
+#endif  // CC_TEST_FAKE_RASTER_BUFFER_PROVIDER_H_
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index 94ca37b..768e518 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -13,60 +13,13 @@
 #include "base/lazy_instance.h"
 #include "base/thread_task_runner_handle.h"
 #include "cc/raster/raster_buffer.h"
-#include "cc/raster/tile_task_worker_pool.h"
+#include "cc/test/fake_tile_task_manager.h"
 
 namespace cc {
 
 namespace {
 
-class FakeTileTaskWorkerPoolImpl : public TileTaskWorkerPool,
-                                   public RasterBufferProvider {
- public:
-  // Overridden from TileTaskWorkerPool:
-  void Shutdown() override {}
-  void ScheduleTasks(TaskGraph* graph) override {
-    for (const auto& node : graph->nodes) {
-      TileTask* task = static_cast<TileTask*>(node.task);
-
-      task->WillSchedule();
-      task->ScheduleOnOriginThread(this);
-      task->DidSchedule();
-
-      completed_tasks_.push_back(task);
-    }
-  }
-  void CheckForCompletedTasks() override {
-    for (TileTask::Vector::iterator it = completed_tasks_.begin();
-         it != completed_tasks_.end(); ++it) {
-      TileTask* task = it->get();
-
-      task->WillComplete();
-      task->CompleteOnOriginThread(this);
-      task->DidComplete();
-    }
-    completed_tasks_.clear();
-  }
-  ResourceFormat GetResourceFormat(bool must_support_alpha) const override {
-    return RGBA_8888;
-  }
-  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override {
-    return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
-  }
-  RasterBufferProvider* AsRasterBufferProvider() override { return this; }
-
-  // Overridden from RasterBufferProvider:
-  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
-      const Resource* resource,
-      uint64_t resource_content_id,
-      uint64_t previous_content_id) override {
-    return nullptr;
-  }
-  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override {}
-
- private:
-  TileTask::Vector completed_tasks_;
-};
-base::LazyInstance<FakeTileTaskWorkerPoolImpl> g_fake_tile_task_worker_pool =
+base::LazyInstance<FakeTileTaskManagerImpl> g_fake_tile_task_manager =
     LAZY_INSTANCE_INITIALIZER;
 
 }  // namespace
@@ -76,9 +29,9 @@
                   base::ThreadTaskRunnerHandle::Get(),
                   std::numeric_limits<size_t>::max(),
                   false /* use_partial_raster */) {
-  SetResources(nullptr, g_fake_tile_task_worker_pool.Pointer(),
-               &image_decode_controller_, std::numeric_limits<size_t>::max(),
-               false /* use_gpu_rasterization */);
+  SetResources(
+      nullptr, &image_decode_controller_, g_fake_tile_task_manager.Pointer(),
+      std::numeric_limits<size_t>::max(), false /* use_gpu_rasterization */);
 }
 
 FakeTileManager::FakeTileManager(TileManagerClient* client,
@@ -87,8 +40,9 @@
                   base::ThreadTaskRunnerHandle::Get(),
                   std::numeric_limits<size_t>::max(),
                   false /* use_partial_raster */) {
-  SetResources(resource_pool, g_fake_tile_task_worker_pool.Pointer(),
-               &image_decode_controller_, std::numeric_limits<size_t>::max(),
+  SetResources(resource_pool, &image_decode_controller_,
+               g_fake_tile_task_manager.Pointer(),
+               std::numeric_limits<size_t>::max(),
                false /* use_gpu_rasterization */);
 }
 
diff --git a/cc/test/fake_tile_task_manager.cc b/cc/test/fake_tile_task_manager.cc
new file mode 100644
index 0000000..9b28d55
--- /dev/null
+++ b/cc/test/fake_tile_task_manager.cc
@@ -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.
+
+#include "cc/test/fake_tile_task_manager.h"
+
+#include "base/memory/ptr_util.h"
+
+namespace cc {
+
+FakeTileTaskManagerImpl::FakeTileTaskManagerImpl()
+    : raster_buffer_provider_(base::WrapUnique<RasterBufferProvider>(
+          new FakeRasterBufferProviderImpl)) {}
+
+FakeTileTaskManagerImpl::FakeTileTaskManagerImpl(
+    std::unique_ptr<RasterBufferProvider> raster_buffer_provider)
+    : raster_buffer_provider_(std::move(raster_buffer_provider)) {}
+
+FakeTileTaskManagerImpl::~FakeTileTaskManagerImpl() {}
+
+void FakeTileTaskManagerImpl::ScheduleTasks(TaskGraph* graph) {
+  for (const auto& node : graph->nodes) {
+    TileTask* task = static_cast<TileTask*>(node.task);
+
+    task->WillSchedule();
+    task->ScheduleOnOriginThread(raster_buffer_provider_.get());
+    task->DidSchedule();
+
+    completed_tasks_.push_back(task);
+  }
+}
+
+void FakeTileTaskManagerImpl::CheckForCompletedTasks() {
+  for (Task::Vector::iterator it = completed_tasks_.begin();
+       it != completed_tasks_.end(); ++it) {
+    TileTask* task = static_cast<TileTask*>(it->get());
+
+    task->WillComplete();
+    task->CompleteOnOriginThread(raster_buffer_provider_.get());
+    task->DidComplete();
+  }
+  completed_tasks_.clear();
+}
+
+void FakeTileTaskManagerImpl::Shutdown() {}
+
+RasterBufferProvider* FakeTileTaskManagerImpl::GetRasterBufferProvider() const {
+  return raster_buffer_provider_.get();
+}
+
+}  // namespace cc
diff --git a/cc/test/fake_tile_task_manager.h b/cc/test/fake_tile_task_manager.h
new file mode 100644
index 0000000..7fb6af6
--- /dev/null
+++ b/cc/test/fake_tile_task_manager.h
@@ -0,0 +1,35 @@
+// 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 CC_TEST_FAKE_TILE_TASK_MANAGER_H_
+#define CC_TEST_FAKE_TILE_TASK_MANAGER_H_
+
+#include "cc/test/fake_raster_buffer_provider.h"
+#include "cc/tiles/tile_task_manager.h"
+
+namespace cc {
+
+// Fake TileTaskManager.
+class FakeTileTaskManagerImpl : public TileTaskManager {
+ public:
+  FakeTileTaskManagerImpl();
+  // Ctor for custom raster buffer provider.
+  FakeTileTaskManagerImpl(
+      std::unique_ptr<RasterBufferProvider> raster_buffer_provider);
+  ~FakeTileTaskManagerImpl() override;
+
+  // Overridden from TileTaskManager:
+  void ScheduleTasks(TaskGraph* graph) override;
+  void CheckForCompletedTasks() override;
+  void Shutdown() override;
+  RasterBufferProvider* GetRasterBufferProvider() const override;
+
+ protected:
+  std::unique_ptr<RasterBufferProvider> raster_buffer_provider_;
+  Task::Vector completed_tasks_;
+};
+
+}  // namespace cc
+
+#endif  // CC_TEST_FAKE_TILE_TASK_MANAGER_H_
diff --git a/cc/test/layer_test_common.cc b/cc/test/layer_test_common.cc
index af7ffeb8..4ba0927 100644
--- a/cc/test/layer_test_common.cc
+++ b/cc/test/layer_test_common.cc
@@ -152,7 +152,7 @@
   LayerImplList layer_list;
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_layer(), viewport_size, &layer_list);
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 }
 
 void LayerTestCommon::LayerImplTest::AppendQuadsWithOcclusion(
diff --git a/cc/test/layer_tree_host_common_test.cc b/cc/test/layer_tree_host_common_test.cc
index 6ac0c57..4f2be2b4f 100644
--- a/cc/test/layer_tree_host_common_test.cc
+++ b/cc/test/layer_tree_host_common_test.cc
@@ -74,7 +74,7 @@
     Layer* page_scale_layer,
     bool can_use_lcd_text,
     bool layers_always_allowed_lcd_text) {
-  LayerTreeHostCommon::PreCalculateMetaInformation(root_layer);
+  PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
 
   EXPECT_TRUE(page_scale_layer || (page_scale_factor == 1.f));
   gfx::Transform identity_matrix;
@@ -96,7 +96,7 @@
 void LayerTreeHostCommonTestBase::
     ExecuteCalculateDrawPropertiesWithPropertyTrees(Layer* root_layer) {
   DCHECK(root_layer->layer_tree_host());
-  LayerTreeHostCommon::PreCalculateMetaInformation(root_layer);
+  PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
 
   gfx::Transform identity_transform;
 
@@ -138,7 +138,7 @@
 void LayerTreeHostCommonTestBase::
     ExecuteCalculateDrawPropertiesWithPropertyTrees(LayerImpl* root_layer) {
   DCHECK(root_layer->layer_tree_impl());
-  LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer);
+  PropertyTreeBuilder::PreCalculateMetaInformationForTesting(root_layer);
 
   gfx::Transform identity_transform;
 
@@ -198,7 +198,7 @@
   inputs.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text;
   inputs.can_adjust_raster_scales = true;
 
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 }
 
 void LayerTreeHostCommonTestBase::
@@ -215,7 +215,7 @@
   inputs.can_adjust_raster_scales = true;
   inputs.can_render_to_separate_surface = false;
 
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 }
 
 bool LayerTreeHostCommonTestBase::UpdateLayerListContains(int id) const {
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc
index 7da328f..b4f48e4d 100644
--- a/cc/test/layer_tree_pixel_resource_test.cc
+++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -5,12 +5,12 @@
 #include "cc/test/layer_tree_pixel_resource_test.h"
 
 #include "cc/layers/layer.h"
-#include "cc/raster/bitmap_tile_task_worker_pool.h"
+#include "cc/raster/bitmap_raster_buffer_provider.h"
+#include "cc/raster/gpu_raster_buffer_provider.h"
 #include "cc/raster/gpu_rasterizer.h"
-#include "cc/raster/gpu_tile_task_worker_pool.h"
-#include "cc/raster/one_copy_tile_task_worker_pool.h"
-#include "cc/raster/tile_task_worker_pool.h"
-#include "cc/raster/zero_copy_tile_task_worker_pool.h"
+#include "cc/raster/one_copy_raster_buffer_provider.h"
+#include "cc/raster/raster_buffer_provider.h"
+#include "cc/raster/zero_copy_raster_buffer_provider.h"
 #include "cc/resources/resource_pool.h"
 #include "cc/test/fake_output_surface.h"
 #include "gpu/GLES2/gl2extchromium.h"
@@ -44,7 +44,7 @@
 LayerTreeHostPixelResourceTest::LayerTreeHostPixelResourceTest(
     PixelResourceTestCase test_case)
     : draw_texture_target_(GL_INVALID_VALUE),
-      resource_pool_option_(BITMAP_TILE_TASK_WORKER_POOL),
+      raster_buffer_provider_type_(RASTER_BUFFER_PROVIDER_TYPE_BITMAP),
       initialized_(false),
       test_case_(test_case) {
   InitializeFromTestCase(test_case);
@@ -52,7 +52,7 @@
 
 LayerTreeHostPixelResourceTest::LayerTreeHostPixelResourceTest()
     : draw_texture_target_(GL_INVALID_VALUE),
-      resource_pool_option_(BITMAP_TILE_TASK_WORKER_POOL),
+      raster_buffer_provider_type_(RASTER_BUFFER_PROVIDER_TYPE_BITMAP),
       initialized_(false),
       test_case_(SOFTWARE) {}
 
@@ -64,50 +64,50 @@
     case SOFTWARE:
       test_type_ = PIXEL_TEST_SOFTWARE;
       draw_texture_target_ = GL_INVALID_VALUE;
-      resource_pool_option_ = BITMAP_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_BITMAP;
       return;
     case GL_GPU_RASTER_2D_DRAW:
       test_type_ = PIXEL_TEST_GL;
       draw_texture_target_ = GL_TEXTURE_2D;
-      resource_pool_option_ = GPU_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_GPU;
       return;
     case GL_ONE_COPY_2D_STAGING_2D_DRAW:
       test_type_ = PIXEL_TEST_GL;
       draw_texture_target_ = GL_TEXTURE_2D;
-      resource_pool_option_ = ONE_COPY_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY;
       return;
     case GL_ONE_COPY_RECT_STAGING_2D_DRAW:
       test_type_ = PIXEL_TEST_GL;
       draw_texture_target_ = GL_TEXTURE_2D;
-      resource_pool_option_ = ONE_COPY_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY;
       return;
     case GL_ONE_COPY_EXTERNAL_STAGING_2D_DRAW:
       test_type_ = PIXEL_TEST_GL;
       draw_texture_target_ = GL_TEXTURE_2D;
-      resource_pool_option_ = ONE_COPY_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY;
       return;
     case GL_ZERO_COPY_2D_DRAW:
       test_type_ = PIXEL_TEST_GL;
       draw_texture_target_ = GL_TEXTURE_2D;
-      resource_pool_option_ = ZERO_COPY_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY;
       return;
     case GL_ZERO_COPY_RECT_DRAW:
       test_type_ = PIXEL_TEST_GL;
       draw_texture_target_ = GL_TEXTURE_RECTANGLE_ARB;
-      resource_pool_option_ = ZERO_COPY_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY;
       return;
     case GL_ZERO_COPY_EXTERNAL_DRAW:
       test_type_ = PIXEL_TEST_GL;
       draw_texture_target_ = GL_TEXTURE_EXTERNAL_OES;
-      resource_pool_option_ = ZERO_COPY_TILE_TASK_WORKER_POOL;
+      raster_buffer_provider_type_ = RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY;
       return;
   }
   NOTREACHED();
 }
 
-void LayerTreeHostPixelResourceTest::CreateResourceAndTileTaskWorkerPool(
+void LayerTreeHostPixelResourceTest::CreateResourceAndRasterBufferProvider(
     LayerTreeHostImpl* host_impl,
-    std::unique_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
+    std::unique_ptr<RasterBufferProvider>* raster_buffer_provider,
     std::unique_ptr<ResourcePool>* resource_pool) {
   base::SingleThreadTaskRunner* task_runner =
       task_runner_provider()->HasImplThread()
@@ -122,42 +122,39 @@
   int max_bytes_per_copy_operation = 1024 * 1024;
   int max_staging_buffer_usage_in_bytes = 32 * 1024 * 1024;
 
-  switch (resource_pool_option_) {
-    case BITMAP_TILE_TASK_WORKER_POOL:
+  // Create resource pool.
+  *resource_pool = ResourcePool::Create(resource_provider, task_runner);
+
+  switch (raster_buffer_provider_type_) {
+    case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
       EXPECT_FALSE(context_provider);
       EXPECT_EQ(PIXEL_TEST_SOFTWARE, test_type_);
-      *resource_pool = ResourcePool::Create(resource_provider, task_runner);
 
-      *tile_task_worker_pool = BitmapTileTaskWorkerPool::Create(
-          task_runner, task_graph_runner(), resource_provider);
+      *raster_buffer_provider =
+          BitmapRasterBufferProvider::Create(resource_provider);
       break;
-    case GPU_TILE_TASK_WORKER_POOL:
+    case RASTER_BUFFER_PROVIDER_TYPE_GPU:
       EXPECT_TRUE(context_provider);
       EXPECT_EQ(PIXEL_TEST_GL, test_type_);
-      *resource_pool = ResourcePool::Create(resource_provider, task_runner);
 
-      *tile_task_worker_pool = GpuTileTaskWorkerPool::Create(
-          task_runner, task_graph_runner(), context_provider, resource_provider,
-          false, 0);
+      *raster_buffer_provider = GpuRasterBufferProvider::Create(
+          context_provider, resource_provider, false, 0);
       break;
-    case ZERO_COPY_TILE_TASK_WORKER_POOL:
+    case RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY:
       EXPECT_TRUE(context_provider);
       EXPECT_EQ(PIXEL_TEST_GL, test_type_);
       EXPECT_TRUE(host_impl->GetRendererCapabilities().using_image);
-      *resource_pool = ResourcePool::Create(resource_provider, task_runner);
 
-      *tile_task_worker_pool = ZeroCopyTileTaskWorkerPool::Create(
-          task_runner, task_graph_runner(), resource_provider,
-          PlatformColor::BestTextureFormat());
+      *raster_buffer_provider = ZeroCopyRasterBufferProvider::Create(
+          resource_provider, PlatformColor::BestTextureFormat());
       break;
-    case ONE_COPY_TILE_TASK_WORKER_POOL:
+    case RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY:
       EXPECT_TRUE(context_provider);
       EXPECT_EQ(PIXEL_TEST_GL, test_type_);
       EXPECT_TRUE(host_impl->GetRendererCapabilities().using_image);
-      *resource_pool = ResourcePool::Create(resource_provider, task_runner);
 
-      *tile_task_worker_pool = OneCopyTileTaskWorkerPool::Create(
-          task_runner, task_graph_runner(), context_provider, resource_provider,
+      *raster_buffer_provider = OneCopyRasterBufferProvider::Create(
+          task_runner, context_provider, resource_provider,
           max_bytes_per_copy_operation, false,
           max_staging_buffer_usage_in_bytes,
           PlatformColor::BestTextureFormat());
diff --git a/cc/test/layer_tree_pixel_resource_test.h b/cc/test/layer_tree_pixel_resource_test.h
index effa9e0d..54339a2 100644
--- a/cc/test/layer_tree_pixel_resource_test.h
+++ b/cc/test/layer_tree_pixel_resource_test.h
@@ -11,7 +11,7 @@
 namespace cc {
 
 class LayerTreeHostImpl;
-class TileTaskWorkerPool;
+class RasterBufferProvider;
 class ResourcePool;
 
 // Enumerate the various combinations of renderer, resource pool, staging
@@ -34,24 +34,24 @@
   explicit LayerTreeHostPixelResourceTest(PixelResourceTestCase test_case);
   LayerTreeHostPixelResourceTest();
 
-  void CreateResourceAndTileTaskWorkerPool(
+  void CreateResourceAndRasterBufferProvider(
       LayerTreeHostImpl* host_impl,
-      std::unique_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
+      std::unique_ptr<RasterBufferProvider>* raster_buffer_provider,
       std::unique_ptr<ResourcePool>* resource_pool) override;
 
   void RunPixelResourceTest(scoped_refptr<Layer> content_root,
                             base::FilePath file_name);
 
-  enum TileTaskWorkerPoolOption {
-    BITMAP_TILE_TASK_WORKER_POOL,
-    GPU_TILE_TASK_WORKER_POOL,
-    ZERO_COPY_TILE_TASK_WORKER_POOL,
-    ONE_COPY_TILE_TASK_WORKER_POOL
+  enum RasterBufferProviderType {
+    RASTER_BUFFER_PROVIDER_TYPE_ZERO_COPY,
+    RASTER_BUFFER_PROVIDER_TYPE_ONE_COPY,
+    RASTER_BUFFER_PROVIDER_TYPE_GPU,
+    RASTER_BUFFER_PROVIDER_TYPE_BITMAP
   };
 
  protected:
   unsigned draw_texture_target_;
-  TileTaskWorkerPoolOption resource_pool_option_;
+  RasterBufferProviderType raster_buffer_provider_type_;
   bool initialized_;
 
   void InitializeFromTestCase(PixelResourceTestCase test_case);
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 19762ae..7275ec3a 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -190,11 +190,11 @@
         block_notify_ready_to_activate_for_testing_(false),
         notify_ready_to_activate_was_blocked_(false) {}
 
-  void CreateResourceAndTileTaskWorkerPool(
-      std::unique_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
+  void CreateResourceAndRasterBufferProvider(
+      std::unique_ptr<RasterBufferProvider>* raster_buffer_provider,
       std::unique_ptr<ResourcePool>* resource_pool) override {
-    test_hooks_->CreateResourceAndTileTaskWorkerPool(
-        this, tile_task_worker_pool, resource_pool);
+    test_hooks_->CreateResourceAndRasterBufferProvider(
+        this, raster_buffer_provider, resource_pool);
   }
 
   void WillBeginImplFrame(const BeginFrameArgs& args) override {
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 515faf6..8c56f88f 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -16,7 +16,7 @@
 #include "cc/output/output_surface_client.h"
 #include "cc/output/software_renderer.h"
 #include "cc/output/texture_mailbox_deleter.h"
-#include "cc/raster/tile_task_worker_pool.h"
+#include "cc/raster/raster_buffer_provider.h"
 #include "cc/resources/resource_provider.h"
 #include "cc/scheduler/begin_frame_source.h"
 #include "cc/test/fake_output_surface_client.h"
diff --git a/cc/test/scheduler_test_common.cc b/cc/test/scheduler_test_common.cc
index d89655bc..36201961 100644
--- a/cc/test/scheduler_test_common.cc
+++ b/cc/test/scheduler_test_common.cc
@@ -42,12 +42,6 @@
 
 FakeBeginFrameSource::~FakeBeginFrameSource() {}
 
-void FakeBeginFrameSource::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->SetString("type", "FakeBeginFrameSource");
-  BeginFrameSourceBase::AsValueInto(dict);
-}
-
 TestBackToBackBeginFrameSource::TestBackToBackBeginFrameSource(
     base::SimpleTestTickClock* now_src,
     base::SingleThreadTaskRunner* task_runner)
diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h
index dffd71b..f3c6f9c 100644
--- a/cc/test/scheduler_test_common.h
+++ b/cc/test/scheduler_test_common.h
@@ -109,9 +109,6 @@
 
   bool has_observers() const { return !observers_.empty(); }
 
-  // BeginFrameSource
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
   using BeginFrameSourceBase::SetBeginFrameSourcePaused;
 
  private:
diff --git a/cc/test/test_hooks.cc b/cc/test/test_hooks.cc
index a6b83002..5850154 100644
--- a/cc/test/test_hooks.cc
+++ b/cc/test/test_hooks.cc
@@ -17,12 +17,12 @@
   return draw_result;
 }
 
-void TestHooks::CreateResourceAndTileTaskWorkerPool(
+void TestHooks::CreateResourceAndRasterBufferProvider(
     LayerTreeHostImpl* host_impl,
-    std::unique_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
+    std::unique_ptr<RasterBufferProvider>* raster_buffer_provider,
     std::unique_ptr<ResourcePool>* resource_pool) {
-  host_impl->LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool(
-      tile_task_worker_pool, resource_pool);
+  host_impl->LayerTreeHostImpl::CreateResourceAndRasterBufferProvider(
+      raster_buffer_provider, resource_pool);
 }
 
 }  // namespace cc
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h
index 075bdd1..299729a 100644
--- a/cc/test/test_hooks.h
+++ b/cc/test/test_hooks.h
@@ -24,9 +24,9 @@
 
   void ReadSettings(const LayerTreeSettings& settings);
 
-  virtual void CreateResourceAndTileTaskWorkerPool(
+  virtual void CreateResourceAndRasterBufferProvider(
       LayerTreeHostImpl* host_impl,
-      std::unique_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
+      std::unique_ptr<RasterBufferProvider>* raster_buffer_provider,
       std::unique_ptr<ResourcePool>* resource_pool);
   virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
                                           const BeginFrameArgs& args) {}
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index c30f3a3c..3ce24d9 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -210,7 +210,7 @@
 
     dependencies++;
 
-    // Add decode task if it doesn't already exists in graph.
+    // Add decode task if it doesn't already exist in graph.
     TaskGraph::Node::Vector::iterator decode_it =
         std::find_if(graph->nodes.begin(), graph->nodes.end(),
                      [decode_task](const TaskGraph::Node& node) {
@@ -308,7 +308,7 @@
     : client_(client),
       task_runner_(std::move(task_runner)),
       resource_pool_(nullptr),
-      tile_task_worker_pool_(nullptr),
+      tile_task_manager_(nullptr),
       scheduled_raster_task_limit_(scheduled_raster_task_limit),
       use_partial_raster_(use_partial_raster),
       use_gpu_rasterization_(false),
@@ -332,25 +332,25 @@
 }
 
 void TileManager::FinishTasksAndCleanUp() {
-  if (!tile_task_worker_pool_)
+  if (!tile_task_manager_)
     return;
 
   global_state_ = GlobalStateThatImpactsTilePriority();
 
   // This cancels tasks if possible, finishes pending tasks, and release any
   // uninitialized resources.
-  tile_task_worker_pool_->Shutdown();
+  tile_task_manager_->Shutdown();
 
   // Now that all tasks have been finished, we can clear any
   // |orphan_tasks_|.
   orphan_tasks_.clear();
 
-  tile_task_worker_pool_->CheckForCompletedTasks();
+  tile_task_manager_->CheckForCompletedTasks();
 
   FreeResourcesForReleasedTiles();
   CleanUpReleasedTiles();
 
-  tile_task_worker_pool_ = nullptr;
+  tile_task_manager_ = nullptr;
   resource_pool_ = nullptr;
   more_tiles_need_prepare_check_notifier_.Cancel();
   signals_check_notifier_.Cancel();
@@ -358,18 +358,18 @@
 }
 
 void TileManager::SetResources(ResourcePool* resource_pool,
-                               TileTaskWorkerPool* tile_task_worker_pool,
                                ImageDecodeController* image_decode_controller,
+                               TileTaskManager* tile_task_manager,
                                size_t scheduled_raster_task_limit,
                                bool use_gpu_rasterization) {
-  DCHECK(!tile_task_worker_pool_);
-  DCHECK(tile_task_worker_pool);
+  DCHECK(!tile_task_manager_);
+  DCHECK(tile_task_manager);
 
   use_gpu_rasterization_ = use_gpu_rasterization;
   scheduled_raster_task_limit_ = scheduled_raster_task_limit;
   resource_pool_ = resource_pool;
-  tile_task_worker_pool_ = tile_task_worker_pool;
   image_decode_controller_ = image_decode_controller;
+  tile_task_manager_ = tile_task_manager;
 }
 
 void TileManager::Release(Tile* tile) {
@@ -419,7 +419,7 @@
   TRACE_EVENT0("cc", "TileManager::DidFinishRunningAllTileTasks");
   TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
   DCHECK(resource_pool_);
-  DCHECK(tile_task_worker_pool_);
+  DCHECK(tile_task_manager_);
 
   has_scheduled_tile_tasks_ = false;
 
@@ -446,7 +446,7 @@
   TRACE_EVENT1("cc", "TileManager::PrepareTiles", "prepare_tiles_id",
                prepare_tiles_count_);
 
-  if (!tile_task_worker_pool_) {
+  if (!tile_task_manager_) {
     TRACE_EVENT_INSTANT0("cc", "PrepareTiles aborted",
                          TRACE_EVENT_SCOPE_THREAD);
     return false;
@@ -458,7 +458,7 @@
   // We need to call CheckForCompletedTasks() once in-between each call
   // to ScheduleTasks() to prevent canceled tasks from being scheduled.
   if (!did_check_for_completed_tasks_since_last_schedule_tasks_) {
-    tile_task_worker_pool_->CheckForCompletedTasks();
+    tile_task_manager_->CheckForCompletedTasks();
     did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
   }
 
@@ -490,12 +490,12 @@
 void TileManager::Flush() {
   TRACE_EVENT0("cc", "TileManager::Flush");
 
-  if (!tile_task_worker_pool_) {
+  if (!tile_task_manager_) {
     TRACE_EVENT_INSTANT0("cc", "Flush aborted", TRACE_EVENT_SCOPE_THREAD);
     return;
   }
 
-  tile_task_worker_pool_->CheckForCompletedTasks();
+  tile_task_manager_->CheckForCompletedTasks();
 
   did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
 
@@ -592,7 +592,7 @@
   TRACE_EVENT_BEGIN0("cc", "TileManager::AssignGpuMemoryToTiles");
 
   DCHECK(resource_pool_);
-  DCHECK(tile_task_worker_pool_);
+  DCHECK(tile_task_manager_);
 
   // Maintain the list of released resources that can potentially be re-used
   // or deleted. If this operation becomes expensive too, only do this after
@@ -830,7 +830,7 @@
   // Schedule running of |raster_queue_|. This replaces any previously
   // scheduled tasks and effectively cancels all tasks not present
   // in |raster_queue_|.
-  tile_task_worker_pool_->ScheduleTasks(&graph_);
+  tile_task_manager_->ScheduleTasks(&graph_);
 
   // It's now safe to clean up orphan tasks as raster worker pool is not
   // allowed to keep around unreferenced raster tasks after ScheduleTasks() has
@@ -961,7 +961,7 @@
                                       int flags) {
   // We need to have a tile task worker pool to do anything meaningful with
   // tiles.
-  DCHECK(tile_task_worker_pool_);
+  DCHECK(tile_task_manager_);
   ScopedTilePtr tile(
       new Tile(this, info, layer_id, source_frame_number, flags));
   DCHECK(tiles_.find(tile->id()) == tiles_.end());
@@ -970,9 +970,9 @@
   return tile;
 }
 
-void TileManager::SetTileTaskWorkerPoolForTesting(
-    TileTaskWorkerPool* tile_task_worker_pool) {
-  tile_task_worker_pool_ = tile_task_worker_pool;
+void TileManager::SetTileTaskManagerForTesting(
+    TileTaskManager* tile_task_manager) {
+  tile_task_manager_ = tile_task_manager;
 }
 
 bool TileManager::AreRequiredTilesReadyToDraw(
@@ -1015,7 +1015,7 @@
 
 void TileManager::CheckAndIssueSignals() {
   TRACE_EVENT0("cc", "TileManager::CheckAndIssueSignals");
-  tile_task_worker_pool_->CheckForCompletedTasks();
+  tile_task_manager_->CheckForCompletedTasks();
   did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
 
   // Ready to activate.
@@ -1055,7 +1055,7 @@
 }
 
 void TileManager::CheckIfMoreTilesNeedToBePrepared() {
-  tile_task_worker_pool_->CheckForCompletedTasks();
+  tile_task_manager_->CheckForCompletedTasks();
   did_check_for_completed_tasks_since_last_schedule_tasks_ = true;
 
   // When OOM, keep re-assigning memory until we reach a steady state
@@ -1142,11 +1142,13 @@
 }
 
 ResourceFormat TileManager::DetermineResourceFormat(const Tile* tile) const {
-  return tile_task_worker_pool_->GetResourceFormat(!tile->is_opaque());
+  return tile_task_manager_->GetRasterBufferProvider()->GetResourceFormat(
+      !tile->is_opaque());
 }
 
 bool TileManager::DetermineResourceRequiresSwizzle(const Tile* tile) const {
-  return tile_task_worker_pool_->GetResourceRequiresSwizzle(!tile->is_opaque());
+  return tile_task_manager_->GetRasterBufferProvider()
+      ->GetResourceRequiresSwizzle(!tile->is_opaque());
 }
 
 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h
index dfcf478..b98c4ec 100644
--- a/cc/tiles/tile_manager.h
+++ b/cc/tiles/tile_manager.h
@@ -18,7 +18,7 @@
 #include "base/values.h"
 #include "cc/base/unique_notifier.h"
 #include "cc/playback/raster_source.h"
-#include "cc/raster/tile_task_worker_pool.h"
+#include "cc/raster/raster_buffer_provider.h"
 #include "cc/resources/memory_history.h"
 #include "cc/resources/resource_pool.h"
 #include "cc/tiles/eviction_tile_priority_queue.h"
@@ -26,6 +26,7 @@
 #include "cc/tiles/raster_tile_priority_queue.h"
 #include "cc/tiles/tile.h"
 #include "cc/tiles/tile_draw_info.h"
+#include "cc/tiles/tile_task_manager.h"
 
 namespace base {
 namespace trace_event {
@@ -117,8 +118,8 @@
   // FinishTasksAndCleanUp must be called in between consecutive calls to
   // SetResources.
   void SetResources(ResourcePool* resource_pool,
-                    TileTaskWorkerPool* tile_task_worker_pool,
                     ImageDecodeController* image_decode_controller,
+                    TileTaskManager* tile_task_manager,
                     size_t scheduled_raster_task_limit,
                     bool use_gpu_rasterization);
 
@@ -147,7 +148,8 @@
       TileDrawInfo& draw_info = tiles[i]->draw_info();
       draw_info.resource_ = resource_pool_->AcquireResource(
           tiles[i]->desired_texture_size(),
-          tile_task_worker_pool_->GetResourceFormat(false));
+          tile_task_manager_->GetRasterBufferProvider()->GetResourceFormat(
+              false));
     }
   }
 
@@ -163,8 +165,7 @@
     global_state_ = state;
   }
 
-  void SetTileTaskWorkerPoolForTesting(
-      TileTaskWorkerPool* tile_task_worker_pool);
+  void SetTileTaskManagerForTesting(TileTaskManager* tile_task_manager);
 
   void FreeResourcesAndCleanUpReleasedTilesForTesting() {
     FreeResourcesForReleasedTiles();
@@ -287,7 +288,7 @@
   TileManagerClient* client_;
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
   ResourcePool* resource_pool_;
-  TileTaskWorkerPool* tile_task_worker_pool_;
+  TileTaskManager* tile_task_manager_;
   GlobalStateThatImpactsTilePriority global_state_;
   size_t scheduled_raster_task_limit_;
   const bool use_partial_raster_;
diff --git a/cc/tiles/tile_manager_perftest.cc b/cc/tiles/tile_manager_perftest.cc
index e573c5a..134ec374 100644
--- a/cc/tiles/tile_manager_perftest.cc
+++ b/cc/tiles/tile_manager_perftest.cc
@@ -20,6 +20,7 @@
 #include "cc/test/fake_raster_source.h"
 #include "cc/test/fake_tile_manager.h"
 #include "cc/test/fake_tile_manager_client.h"
+#include "cc/test/fake_tile_task_manager.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_task_graph_runner.h"
 #include "cc/test/test_tile_priorities.h"
@@ -37,54 +38,7 @@
 static const int kWarmupRuns = 5;
 static const int kTimeCheckInterval = 10;
 
-class FakeTileTaskWorkerPoolImpl : public TileTaskWorkerPool,
-                                   public RasterBufferProvider {
- public:
-  // Overridden from TileTaskWorkerPool:
-  void Shutdown() override {}
-  void ScheduleTasks(TaskGraph* graph) override {
-    for (auto& node : graph->nodes) {
-      TileTask* task = static_cast<TileTask*>(node.task);
-
-      task->WillSchedule();
-      task->ScheduleOnOriginThread(this);
-      task->DidSchedule();
-
-      completed_tasks_.push_back(task);
-    }
-  }
-  void CheckForCompletedTasks() override {
-    for (TileTask::Vector::iterator it = completed_tasks_.begin();
-         it != completed_tasks_.end(); ++it) {
-      TileTask* task = it->get();
-
-      task->WillComplete();
-      task->CompleteOnOriginThread(this);
-      task->DidComplete();
-    }
-    completed_tasks_.clear();
-  }
-  ResourceFormat GetResourceFormat(bool must_support_alpha) const override {
-    return RGBA_8888;
-  }
-  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override {
-    return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha));
-  }
-  RasterBufferProvider* AsRasterBufferProvider() override { return this; }
-
-  // Overridden from RasterBufferProvider:
-  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
-      const Resource* resource,
-      uint64_t new_content_id,
-      uint64_t previous_content_id) override {
-    return nullptr;
-  }
-  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override {}
-
- private:
-  TileTask::Vector completed_tasks_;
-};
-base::LazyInstance<FakeTileTaskWorkerPoolImpl> g_fake_tile_task_worker_pool =
+base::LazyInstance<FakeTileTaskManagerImpl> g_fake_tile_task_manager =
     LAZY_INSTANCE_INITIALIZER;
 
 class TileManagerPerfTest : public testing::Test {
@@ -127,8 +81,8 @@
   virtual void InitializeRenderer() {
     host_impl_.SetVisible(true);
     host_impl_.InitializeRenderer(output_surface_.get());
-    tile_manager()->SetTileTaskWorkerPoolForTesting(
-        g_fake_tile_task_worker_pool.Pointer());
+    tile_manager()->SetTileTaskManagerForTesting(
+        g_fake_tile_task_manager.Pointer());
   }
 
   void SetupDefaultTrees(const gfx::Size& layer_bounds) {
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc
index a691b44..18cdcb83 100644
--- a/cc/tiles/tile_manager_unittest.cc
+++ b/cc/tiles/tile_manager_unittest.cc
@@ -23,6 +23,7 @@
 #include "cc/test/fake_raster_source.h"
 #include "cc/test/fake_recording_source.h"
 #include "cc/test/fake_tile_manager.h"
+#include "cc/test/fake_tile_task_manager.h"
 #include "cc/test/test_gpu_memory_buffer_manager.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_task_graph_runner.h"
@@ -1907,51 +1908,21 @@
   run_loop.Run();
 }
 
-// Fake TileTaskRunner that just no-ops all calls.
-// Fake TileTaskWorkerPool that just no-ops all calls.
-class FakeTileTaskWorkerPool : public TileTaskWorkerPool,
-                               public RasterBufferProvider {
+// Fake TileTaskManager that just cancels all scheduled tasks immediately.
+class CancellingTileTaskManager : public FakeTileTaskManagerImpl {
  public:
-  FakeTileTaskWorkerPool() {}
-  ~FakeTileTaskWorkerPool() override {}
-
-  // TileTaskWorkerPool methods.
-  void Shutdown() override {}
-  void CheckForCompletedTasks() override {}
-  ResourceFormat GetResourceFormat(bool must_support_alpha) const override {
-    return ResourceFormat::RGBA_8888;
-  }
-  bool GetResourceRequiresSwizzle(bool must_support_alpha) const override {
-    return false;
-  }
-  RasterBufferProvider* AsRasterBufferProvider() override { return this; }
-
-  void ScheduleTasks(TaskGraph* graph) override {}
-
-  // RasterBufferProvider methods.
-  std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
-      const Resource* resource,
-      uint64_t resource_content_id,
-      uint64_t previous_content_id) override {
-    NOTREACHED();
-    return nullptr;
-  }
-  void ReleaseBufferForRaster(std::unique_ptr<RasterBuffer> buffer) override {}
-};
-
-// Fake TileTaskWorkerPool that just cancels all scheduled tasks immediately.
-class CancellingTileTaskWorkerPool : public FakeTileTaskWorkerPool {
- public:
-  CancellingTileTaskWorkerPool() {}
-  ~CancellingTileTaskWorkerPool() override {}
+  CancellingTileTaskManager() {}
+  ~CancellingTileTaskManager() override {}
 
   void ScheduleTasks(TaskGraph* graph) override {
     // Just call CompleteOnOriginThread on each item in the queue. As none of
     // these items have run yet, they will be treated as cancelled tasks.
     for (const auto& node : graph->nodes) {
-      static_cast<TileTask*>(node.task)->CompleteOnOriginThread(this);
+      static_cast<TileTask*>(node.task)->CompleteOnOriginThread(
+          raster_buffer_provider_.get());
     }
   }
+  void CheckForCompletedTasks() override {}
 };
 
 class PartialRasterTileManagerTest : public TileManagerTest {
@@ -1966,9 +1937,9 @@
 TEST_F(PartialRasterTileManagerTest, CancelledTasksHaveNoContentId) {
   // Create a CancellingTaskRunner and set it on the tile manager so that all
   // scheduled work is immediately cancelled.
-  CancellingTileTaskWorkerPool cancelling_worker_pool;
-  host_impl_->tile_manager()->SetTileTaskWorkerPoolForTesting(
-      &cancelling_worker_pool);
+  CancellingTileTaskManager cancelling_task_manager;
+  host_impl_->tile_manager()->SetTileTaskManagerForTesting(
+      &cancelling_task_manager);
 
   // Pick arbitrary IDs - they don't really matter as long as they're constant.
   const int kLayerId = 7;
@@ -2001,9 +1972,8 @@
   EXPECT_FALSE(queue->IsEmpty());
   queue->Top().tile()->SetInvalidated(gfx::Rect(), kInvalidatedId);
 
-  // PrepareTiles to schedule tasks. Due to the CancellingTileTaskWorkerPool,
-  // these
-  // tasks will immediately be canceled.
+  // PrepareTiles to schedule tasks. Due to the CancellingTileTaskManager,
+  // these tasks will immediately be canceled.
   host_impl_->tile_manager()->PrepareTiles(host_impl_->global_tile_state());
 
   // Make sure that the tile we invalidated above was not returned to the pool
@@ -2012,31 +1982,20 @@
   EXPECT_FALSE(host_impl_->resource_pool()->TryAcquireResourceWithContentId(
       kInvalidatedId));
 
-  // Free our host_impl_ before the cancelling_worker_pool we passed it, as it
-  // will
-  // use that class in clean up.
+  // Free our host_impl_ before the cancelling_task_manager we passed it, as it
+  // will use that class in clean up.
   host_impl_ = nullptr;
 }
 
-// Fake TileTaskWorkerPool that verifies the resource content ID of raster
+// FakeRasterBufferProviderImpl that verifies the resource content ID of raster
 // tasks.
-class VerifyResourceContentIdTileTaskWorkerPool
-    : public FakeTileTaskWorkerPool {
+class VerifyResourceContentIdRasterBufferProvider
+    : public FakeRasterBufferProviderImpl {
  public:
-  explicit VerifyResourceContentIdTileTaskWorkerPool(
+  explicit VerifyResourceContentIdRasterBufferProvider(
       uint64_t expected_resource_id)
       : expected_resource_id_(expected_resource_id) {}
-  ~VerifyResourceContentIdTileTaskWorkerPool() override {}
-
-  void ScheduleTasks(TaskGraph* graph) override {
-    for (const auto& node : graph->nodes) {
-      TileTask* task = static_cast<TileTask*>(node.task);
-      // Triggers a call to AcquireBufferForRaster.
-      task->ScheduleOnOriginThread(this);
-      // Calls TileManager as though task was cancelled.
-      task->CompleteOnOriginThread(this);
-    }
-  }
+  ~VerifyResourceContentIdRasterBufferProvider() override {}
 
   // RasterBufferProvider methods.
   std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
@@ -2051,6 +2010,26 @@
   uint64_t expected_resource_id_;
 };
 
+class VerifyResourceContentIdTileTaskManager : public FakeTileTaskManagerImpl {
+ public:
+  explicit VerifyResourceContentIdTileTaskManager(uint64_t expected_resource_id)
+      : FakeTileTaskManagerImpl(base::WrapUnique<RasterBufferProvider>(
+            new VerifyResourceContentIdRasterBufferProvider(
+                expected_resource_id))) {}
+  ~VerifyResourceContentIdTileTaskManager() override {}
+
+  void ScheduleTasks(TaskGraph* graph) override {
+    for (const auto& node : graph->nodes) {
+      TileTask* task = static_cast<TileTask*>(node.task);
+      // Triggers a call to AcquireBufferForRaster.
+      task->ScheduleOnOriginThread(raster_buffer_provider_.get());
+      // Calls TileManager as though task was cancelled.
+      task->CompleteOnOriginThread(raster_buffer_provider_.get());
+    }
+  }
+  void CheckForCompletedTasks() override {}
+};
+
 // Runs a test to ensure that partial raster is either enabled or disabled,
 // depending on |partial_raster_enabled|'s value. Takes ownership of host_impl
 // so that cleanup order can be controlled.
@@ -2062,12 +2041,11 @@
   const uint64_t kExpectedId = partial_raster_enabled ? kInvalidatedId : 0u;
   const gfx::Size kTileSize(128, 128);
 
-  // Create a VerifyResourceContentIdTileTaskWorkerPool to ensure that the
-  // raster
-  // task we see is created with |kExpectedId|.
-  VerifyResourceContentIdTileTaskWorkerPool verifying_worker_pool(kExpectedId);
-  host_impl->tile_manager()->SetTileTaskWorkerPoolForTesting(
-      &verifying_worker_pool);
+  // Create a VerifyResourceContentIdTileTaskManager to ensure that the
+  // raster task we see is created with |kExpectedId|.
+  VerifyResourceContentIdTileTaskManager verifying_task_manager(kExpectedId);
+  host_impl->tile_manager()->SetTileTaskManagerForTesting(
+      &verifying_task_manager);
 
   // Ensure there's a resource with our |kInvalidatedId| in the resource pool.
   host_impl->resource_pool()->ReleaseResource(
@@ -2102,13 +2080,12 @@
   queue->Top().tile()->SetInvalidated(gfx::Rect(), kInvalidatedId);
 
   // PrepareTiles to schedule tasks. Due to the
-  // VerifyPreviousContentTileTaskWorkerPool, these tasks will verified and
+  // VerifyPreviousContentRasterBufferProvider, these tasks will verified and
   // cancelled.
   host_impl->tile_manager()->PrepareTiles(host_impl->global_tile_state());
 
-  // Free our host_impl before the cancelling_worker_pool we passed it, as it
-  // will
-  // use that class in clean up.
+  // Free our host_impl before the verifying_task_manager we passed it, as it
+  // will use that class in clean up.
   host_impl = nullptr;
 }
 
diff --git a/cc/tiles/tile_task_manager.cc b/cc/tiles/tile_task_manager.cc
new file mode 100644
index 0000000..9f78d38
--- /dev/null
+++ b/cc/tiles/tile_task_manager.cc
@@ -0,0 +1,86 @@
+// 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 "cc/tiles/tile_task_manager.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/trace_event/trace_event.h"
+
+namespace cc {
+
+TileTaskManager::TileTaskManager() {}
+
+TileTaskManager::~TileTaskManager() {}
+
+// static
+std::unique_ptr<TileTaskManagerImpl> TileTaskManagerImpl::Create(
+    std::unique_ptr<RasterBufferProvider> raster_buffer_provider,
+    TaskGraphRunner* task_graph_runner) {
+  return base::WrapUnique<TileTaskManagerImpl>(new TileTaskManagerImpl(
+      std::move(raster_buffer_provider), task_graph_runner));
+}
+
+TileTaskManagerImpl::TileTaskManagerImpl(
+    std::unique_ptr<RasterBufferProvider> raster_buffer_provider,
+    TaskGraphRunner* task_graph_runner)
+    : raster_buffer_provider_(std::move(raster_buffer_provider)),
+      task_graph_runner_(task_graph_runner),
+      namespace_token_(task_graph_runner->GetNamespaceToken()) {}
+
+TileTaskManagerImpl::~TileTaskManagerImpl() {
+  DCHECK_EQ(0u, completed_tasks_.size());
+}
+
+void TileTaskManagerImpl::ScheduleTasks(TaskGraph* graph) {
+  TRACE_EVENT0("cc", "TileTaskManagerImpl::ScheduleTasks");
+
+  for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin();
+       it != graph->nodes.end(); ++it) {
+    TaskGraph::Node& node = *it;
+    TileTask* task = static_cast<TileTask*>(node.task);
+
+    if (!task->HasBeenScheduled()) {
+      task->WillSchedule();
+      task->ScheduleOnOriginThread(raster_buffer_provider_.get());
+      task->DidSchedule();
+    }
+  }
+
+  raster_buffer_provider_->OrderingBarrier();
+
+  task_graph_runner_->ScheduleTasks(namespace_token_, graph);
+}
+
+void TileTaskManagerImpl::CheckForCompletedTasks() {
+  TRACE_EVENT0("cc", "TileTaskManagerImpl::CheckForCompletedTasks");
+
+  task_graph_runner_->CollectCompletedTasks(namespace_token_,
+                                            &completed_tasks_);
+  for (Task::Vector::const_iterator it = completed_tasks_.begin();
+       it != completed_tasks_.end(); ++it) {
+    TileTask* task = static_cast<TileTask*>(it->get());
+
+    task->WillComplete();
+    task->CompleteOnOriginThread(raster_buffer_provider_.get());
+    task->DidComplete();
+  }
+  completed_tasks_.clear();
+}
+
+void TileTaskManagerImpl::Shutdown() {
+  TRACE_EVENT0("cc", "TileTaskManagerImpl::Shutdown");
+
+  // Cancel non-scheduled tasks and wait for running tasks to finish.
+  TaskGraph empty;
+  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
+  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
+
+  raster_buffer_provider_->Shutdown();
+}
+
+RasterBufferProvider* TileTaskManagerImpl::GetRasterBufferProvider() const {
+  return raster_buffer_provider_.get();
+}
+
+}  // namespace cc
diff --git a/cc/tiles/tile_task_manager.h b/cc/tiles/tile_task_manager.h
new file mode 100644
index 0000000..e670b41
--- /dev/null
+++ b/cc/tiles/tile_task_manager.h
@@ -0,0 +1,72 @@
+// 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 CC_TILES_TILE_TASK_MANAGER_H_
+#define CC_TILES_TILE_TASK_MANAGER_H_
+
+#include <stddef.h>
+
+#include "cc/raster/raster_buffer_provider.h"
+#include "cc/raster/task_graph_runner.h"
+#include "cc/raster/tile_task.h"
+
+namespace cc {
+// This interface provides the wrapper over TaskGraphRunner for scheduling and
+// collecting tasks. The client can call CheckForCompletedTasks() at any time to
+// process all completed tasks at the moment that have finished running or
+// cancelled.
+class CC_EXPORT TileTaskManager {
+ public:
+  TileTaskManager();
+  virtual ~TileTaskManager();
+
+  // Schedule running of tile tasks in |graph| and all dependencies.
+  // Previously scheduled tasks that are not in |graph| will be canceled unless
+  // already running. Once scheduled, reply callbacks are guaranteed to run for
+  // all tasks even if they later get canceled by another call to
+  // ScheduleTasks().
+  virtual void ScheduleTasks(TaskGraph* graph) = 0;
+
+  // Check for completed tasks and dispatch reply callbacks.
+  virtual void CheckForCompletedTasks() = 0;
+
+  // Shutdown after canceling all previously scheduled tasks. Reply callbacks
+  // are still guaranteed to run when CheckForCompletedTasks() is called.
+  virtual void Shutdown() = 0;
+
+  // Get RasterBufferProvider.
+  virtual RasterBufferProvider* GetRasterBufferProvider() const = 0;
+};
+
+class CC_EXPORT TileTaskManagerImpl : public TileTaskManager {
+ public:
+  ~TileTaskManagerImpl() override;
+
+  static std::unique_ptr<TileTaskManagerImpl> Create(
+      std::unique_ptr<RasterBufferProvider> raster_buffer_provider,
+      TaskGraphRunner* task_graph_runner);
+
+  // Overridden from TileTaskManager:
+  void ScheduleTasks(TaskGraph* graph) override;
+  void CheckForCompletedTasks() override;
+  void Shutdown() override;
+  RasterBufferProvider* GetRasterBufferProvider() const override;
+
+ protected:
+  TileTaskManagerImpl(
+      std::unique_ptr<RasterBufferProvider> raster_buffer_provider,
+      TaskGraphRunner* task_graph_runner);
+
+  std::unique_ptr<RasterBufferProvider> raster_buffer_provider_;
+  TaskGraphRunner* task_graph_runner_;
+  const NamespaceToken namespace_token_;
+  Task::Vector completed_tasks_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TileTaskManagerImpl);
+};
+
+}  // namespace cc
+
+#endif  // CC_TILES_TILE_TASK_MANAGER_H_
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc
index e8747e2..d9f58158 100644
--- a/cc/trees/damage_tracker_unittest.cc
+++ b/cc/trees/damage_tracker_unittest.cc
@@ -36,7 +36,7 @@
   FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root);
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root, root->bounds(), render_surface_layer_list);
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
   ASSERT_TRUE(root->render_surface());
 }
 
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 686711e6..8357268 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -71,11 +71,6 @@
   ValidateIsNotRootForIsolatedGroup(layer);
 }
 
-static void ValidateRenderSurfacesRecursive(Layer* layer) {
-  ValidateRenderSurfaceForLayer(layer);
-  for (size_t i = 0; i < layer->children().size(); ++i)
-    ValidateRenderSurfacesRecursive(layer->child_at(i));
-}
 #endif
 
 template <typename LayerType>
@@ -373,15 +368,6 @@
     layer->SetHasRenderSurface(false);
 }
 
-void UpdateRenderSurfacesForLayersRecursive(EffectTree* effect_tree,
-                                            Layer* layer) {
-  UpdateRenderSurfaceForLayer(effect_tree, true, layer);
-
-  for (size_t i = 0; i < layer->children().size(); ++i) {
-    UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i));
-  }
-}
-
 }  // namespace
 
 template <typename LayerType>
@@ -658,11 +644,12 @@
 }
 
 void UpdateRenderSurfaces(Layer* root_layer, PropertyTrees* property_trees) {
-  UpdateRenderSurfacesForLayersRecursive(&property_trees->effect_tree,
-                                         root_layer);
+  for (auto* layer : *root_layer->layer_tree_host()) {
+    UpdateRenderSurfaceForLayer(&property_trees->effect_tree, true, layer);
 #if DCHECK_IS_ON()
-  ValidateRenderSurfacesRecursive(root_layer);
+    ValidateRenderSurfaceForLayer(layer);
 #endif
+  }
 }
 
 void UpdatePropertyTrees(PropertyTrees* property_trees,
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 6c64cf2b..fee2d6c 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -217,7 +217,6 @@
       needs_meta_info_recomputation_(true),
       client_(params->client),
       source_frame_number_(0),
-      meta_information_sequence_number_(1),
       rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
       output_surface_lost_(true),
       settings_(*params->settings),
@@ -656,16 +655,8 @@
 }
 
 void LayerTreeHost::SetNeedsDisplayOnAllLayers() {
-  std::stack<Layer*> layer_stack;
-  layer_stack.push(root_layer());
-  while (!layer_stack.empty()) {
-    Layer* current_layer = layer_stack.top();
-    layer_stack.pop();
-    current_layer->SetNeedsDisplay();
-    for (unsigned int i = 0; i < current_layer->children().size(); i++) {
-      layer_stack.push(current_layer->child_at(i));
-    }
-  }
+  for (auto* layer : *this)
+    layer->SetNeedsDisplay();
 }
 
 void LayerTreeHost::SetOutputIsSecure(bool output_is_secure) {
@@ -910,6 +901,14 @@
   return LayerListIterator<Layer>(nullptr);
 }
 
+const LayerListIterator<Layer> LayerTreeHost::begin() const {
+  return LayerListIterator<Layer>(root_layer_.get());
+}
+
+const LayerListIterator<Layer> LayerTreeHost::end() const {
+  return LayerListIterator<Layer>(nullptr);
+}
+
 LayerListReverseIterator<Layer> LayerTreeHost::rbegin() {
   return LayerListReverseIterator<Layer>(root_layer_.get());
 }
@@ -922,22 +921,6 @@
   did_complete_scale_animation_ = true;
 }
 
-static Layer* FindFirstScrollableLayer(Layer* layer) {
-  if (!layer)
-    return NULL;
-
-  if (layer->scrollable())
-    return layer;
-
-  for (size_t i = 0; i < layer->children().size(); ++i) {
-    Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
-    if (found)
-      return found;
-  }
-
-  return NULL;
-}
-
 void LayerTreeHost::RecordGpuRasterizationHistogram() {
   // Gpu rasterization is only supported for Renderer compositors.
   // Checking for IsSingleThreaded() to exclude Browser compositors.
@@ -965,7 +948,7 @@
 }
 
 void LayerTreeHost::BuildPropertyTreesForTesting() {
-  LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer_.get());
+  PropertyTreeBuilder::PreCalculateMetaInformation(root_layer_.get());
   gfx::Transform identity_transform;
   PropertyTreeBuilder::BuildPropertyTrees(
       root_layer_.get(), page_scale_layer_.get(),
@@ -985,7 +968,8 @@
 
   UpdateHudLayer();
 
-  Layer* root_scroll = FindFirstScrollableLayer(root_layer);
+  Layer* root_scroll =
+      PropertyTreeBuilder::FindFirstScrollableLayer(root_layer);
   Layer* page_scale_layer = page_scale_layer_.get();
   if (!page_scale_layer && root_scroll)
     page_scale_layer = root_scroll->parent();
@@ -1002,7 +986,7 @@
     TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees");
     TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"),
                  "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees");
-    LayerTreeHostCommon::PreCalculateMetaInformation(root_layer);
+    PropertyTreeBuilder::PreCalculateMetaInformation(root_layer);
     bool can_render_to_separate_surface = true;
     PropertyTreeBuilder::BuildPropertyTrees(
         root_layer, page_scale_layer, inner_viewport_scroll_layer_.get(),
@@ -1503,8 +1487,6 @@
   proto->set_needs_full_tree_sync(needs_full_tree_sync_);
   proto->set_needs_meta_info_recomputation(needs_meta_info_recomputation_);
   proto->set_source_frame_number(source_frame_number_);
-  proto->set_meta_information_sequence_number(
-      meta_information_sequence_number_);
 
   LayerProtoConverter::SerializeLayerHierarchy(root_layer_,
                                                proto->mutable_root_layer());
@@ -1576,7 +1558,6 @@
   needs_full_tree_sync_ = proto.needs_full_tree_sync();
   needs_meta_info_recomputation_ = proto.needs_meta_info_recomputation();
   source_frame_number_ = proto.source_frame_number();
-  meta_information_sequence_number_ = proto.meta_information_sequence_number();
 
   // Layer hierarchy.
   scoped_refptr<Layer> new_root_layer =
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 41741d1..63208b4 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -149,6 +149,8 @@
 
   LayerListIterator<Layer> begin();
   LayerListIterator<Layer> end();
+  const LayerListIterator<Layer> begin() const;
+  const LayerListIterator<Layer> end() const;
   LayerListReverseIterator<Layer> rbegin();
   LayerListReverseIterator<Layer> rend();
 
@@ -171,18 +173,10 @@
 
   int source_frame_number() const { return source_frame_number_; }
 
-  int meta_information_sequence_number() {
-    return meta_information_sequence_number_;
-  }
-
   bool gpu_rasterization_histogram_recorded() const {
     return gpu_rasterization_histogram_recorded_;
   }
 
-  void IncrementMetaInformationSequenceNumber() {
-    meta_information_sequence_number_++;
-  }
-
   void SetNeedsDisplayOnAllLayers();
 
   void SetOutputIsSecure(bool output_is_secure);
@@ -510,7 +504,6 @@
   std::unique_ptr<TaskRunnerProvider> task_runner_provider_;
 
   int source_frame_number_;
-  int meta_information_sequence_number_;
   std::unique_ptr<RenderingStatsInstrumentation>
       rendering_stats_instrumentation_;
 
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index aef8d33..55c2f45 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -188,19 +188,6 @@
   top_controls_delta = proto.top_controls_delta();
 }
 
-static inline bool IsRootLayer(const Layer* layer) {
-  return !layer->parent();
-}
-
-static bool HasInvertibleOrAnimatedTransform(Layer* layer) {
-  return layer->transform_is_invertible() ||
-         layer->HasPotentiallyRunningTransformAnimation();
-}
-
-static bool HasInvertibleOrAnimatedTransformForTesting(LayerImpl* layer) {
-  return layer->transform().IsInvertible() ||
-         layer->HasPotentiallyRunningTransformAnimation();
-}
 
 static inline void SetMaskLayersAreDrawnRenderSurfaceLayerListMembers(
     LayerImpl* layer) {
@@ -240,145 +227,6 @@
   }
 }
 
-struct PreCalculateMetaInformationRecursiveData {
-  size_t num_unclipped_descendants;
-  int num_layer_or_descendants_with_copy_request;
-  int num_layer_or_descendants_with_touch_handler;
-  int num_descendants_that_draw_content;
-
-  PreCalculateMetaInformationRecursiveData()
-      : num_unclipped_descendants(0),
-        num_layer_or_descendants_with_copy_request(0),
-        num_layer_or_descendants_with_touch_handler(0),
-        num_descendants_that_draw_content(0) {}
-
-  void Merge(const PreCalculateMetaInformationRecursiveData& data) {
-    num_layer_or_descendants_with_copy_request +=
-        data.num_layer_or_descendants_with_copy_request;
-    num_layer_or_descendants_with_touch_handler +=
-        data.num_layer_or_descendants_with_touch_handler;
-    num_unclipped_descendants += data.num_unclipped_descendants;
-    num_descendants_that_draw_content += data.num_descendants_that_draw_content;
-  }
-};
-
-static bool IsMetaInformationRecomputationNeeded(Layer* layer) {
-  return layer->layer_tree_host()->needs_meta_info_recomputation();
-}
-
-static void UpdateMetaInformationSequenceNumber(Layer* root_layer) {
-  root_layer->layer_tree_host()->IncrementMetaInformationSequenceNumber();
-}
-
-// Recursively walks the layer tree(if needed) to compute any information
-// that is needed before doing the main recursion.
-static void PreCalculateMetaInformationInternal(
-    Layer* layer,
-    PreCalculateMetaInformationRecursiveData* recursive_data) {
-  if (!IsMetaInformationRecomputationNeeded(layer)) {
-    DCHECK(IsRootLayer(layer));
-    return;
-  }
-
-  if (layer->clip_parent())
-    recursive_data->num_unclipped_descendants++;
-
-  if (!HasInvertibleOrAnimatedTransform(layer)) {
-    // Layers with singular transforms should not be drawn, the whole subtree
-    // can be skipped.
-    return;
-  }
-
-  for (size_t i = 0; i < layer->children().size(); ++i) {
-    Layer* child_layer = layer->child_at(i);
-
-    PreCalculateMetaInformationRecursiveData data_for_child;
-    PreCalculateMetaInformationInternal(child_layer, &data_for_child);
-    recursive_data->Merge(data_for_child);
-  }
-
-  if (layer->clip_children()) {
-    size_t num_clip_children = layer->clip_children()->size();
-    DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
-    recursive_data->num_unclipped_descendants -= num_clip_children;
-  }
-
-  if (layer->HasCopyRequest())
-    recursive_data->num_layer_or_descendants_with_copy_request++;
-
-  if (!layer->touch_event_handler_region().IsEmpty())
-    recursive_data->num_layer_or_descendants_with_touch_handler++;
-
-  layer->set_num_unclipped_descendants(
-      recursive_data->num_unclipped_descendants);
-
-  if (IsRootLayer(layer))
-    layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false);
-}
-
-static void PreCalculateMetaInformationInternalForTesting(
-    LayerImpl* layer,
-    PreCalculateMetaInformationRecursiveData* recursive_data) {
-  if (layer->test_properties()->clip_parent)
-    recursive_data->num_unclipped_descendants++;
-
-  if (!HasInvertibleOrAnimatedTransformForTesting(layer)) {
-    // Layers with singular transforms should not be drawn, the whole subtree
-    // can be skipped.
-    return;
-  }
-
-  for (size_t i = 0; i < layer->children().size(); ++i) {
-    LayerImpl* child_layer = layer->child_at(i);
-
-    PreCalculateMetaInformationRecursiveData data_for_child;
-    PreCalculateMetaInformationInternalForTesting(child_layer, &data_for_child);
-    recursive_data->Merge(data_for_child);
-  }
-
-  if (layer->test_properties()->clip_children) {
-    size_t num_clip_children = layer->test_properties()->clip_children->size();
-    DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
-    recursive_data->num_unclipped_descendants -= num_clip_children;
-  }
-
-  if (layer->HasCopyRequest())
-    recursive_data->num_layer_or_descendants_with_copy_request++;
-
-  if (!layer->touch_event_handler_region().IsEmpty())
-    recursive_data->num_layer_or_descendants_with_touch_handler++;
-
-  layer->draw_properties().num_unclipped_descendants =
-      recursive_data->num_unclipped_descendants;
-  layer->set_layer_or_descendant_has_touch_handler(
-      (recursive_data->num_layer_or_descendants_with_touch_handler != 0));
-  // TODO(enne): this should be synced from the main thread, so is only
-  // for tests constructing layers on the compositor thread.
-  layer->test_properties()->num_descendants_that_draw_content =
-      recursive_data->num_descendants_that_draw_content;
-
-  if (layer->DrawsContent())
-    recursive_data->num_descendants_that_draw_content++;
-}
-
-void LayerTreeHostCommon::PreCalculateMetaInformation(Layer* root_layer) {
-  PreCalculateMetaInformationRecursiveData recursive_data;
-  PreCalculateMetaInformationInternal(root_layer, &recursive_data);
-}
-
-void LayerTreeHostCommon::PreCalculateMetaInformationForTesting(
-    LayerImpl* root_layer) {
-  PreCalculateMetaInformationRecursiveData recursive_data;
-  PreCalculateMetaInformationInternalForTesting(root_layer, &recursive_data);
-}
-
-void LayerTreeHostCommon::PreCalculateMetaInformationForTesting(
-    Layer* root_layer) {
-  UpdateMetaInformationSequenceNumber(root_layer);
-  PreCalculateMetaInformationRecursiveData recursive_data;
-  PreCalculateMetaInformationInternal(root_layer, &recursive_data);
-}
-
 static bool CdpPerfTracingEnabled() {
   bool tracing_enabled;
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("cdp.perf", &tracing_enabled);
@@ -842,11 +690,10 @@
   }
 }
 
-void LayerTreeHostCommon::CalculateDrawProperties(
+void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
     CalcDrawPropsImplInputsForTesting* inputs) {
-  PreCalculateMetaInformationRecursiveData recursive_data;
-  PreCalculateMetaInformationInternalForTesting(inputs->root_layer,
-                                                &recursive_data);
+  PropertyTreeBuilder::PreCalculateMetaInformationForTesting(
+      inputs->root_layer);
   CalculateDrawPropertiesInternal(inputs, BUILD_PROPERTY_TREES_IF_NEEDED);
 }
 
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index 10c0a1a..1a32f3f 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -117,12 +117,9 @@
   static int CalculateLayerJitter(LayerImpl* scrolling_layer);
   static void CalculateDrawPropertiesForTesting(
       CalcDrawPropsMainInputsForTesting* inputs);
-  static void PreCalculateMetaInformation(Layer* root_layer);
-  static void PreCalculateMetaInformationForTesting(LayerImpl* root_layer);
-  static void PreCalculateMetaInformationForTesting(Layer* root_layer);
 
   static void CalculateDrawProperties(CalcDrawPropsImplInputs* inputs);
-  static void CalculateDrawProperties(
+  static void CalculateDrawPropertiesForTesting(
       CalcDrawPropsImplInputsForTesting* inputs);
 
   template <typename Function>
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 99dca32..ea9defbe 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -1112,7 +1112,7 @@
       root, root->bounds(), translate, &render_surface_layer_list_impl);
   inputs.device_scale_factor = device_scale_factor;
   inputs.property_trees->needs_rebuild = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   // Between grand_child and render_surface, we translate by (10, 10) and scale
   // by a factor of 2.
@@ -1146,7 +1146,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), translate, &render_surface_layer_list_impl);
     inputs.property_trees->needs_rebuild = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     EXPECT_EQ(translate, root->draw_properties().target_space_transform);
     EXPECT_EQ(translate, child->draw_properties().target_space_transform);
     EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
@@ -1159,7 +1159,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), scale, &render_surface_layer_list_impl);
     inputs.property_trees->needs_rebuild = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     EXPECT_EQ(scale, root->draw_properties().target_space_transform);
     EXPECT_EQ(scale, child->draw_properties().target_space_transform);
     EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
@@ -1172,7 +1172,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), rotate, &render_surface_layer_list_impl);
     inputs.property_trees->needs_rebuild = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     EXPECT_EQ(rotate, root->draw_properties().target_space_transform);
     EXPECT_EQ(rotate, child->draw_properties().target_space_transform);
     EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
@@ -1187,7 +1187,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), composite, &render_surface_layer_list_impl);
     inputs.property_trees->needs_rebuild = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     EXPECT_EQ(composite, root->draw_properties().target_space_transform);
     EXPECT_EQ(composite, child->draw_properties().target_space_transform);
     EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
@@ -1202,7 +1202,7 @@
         root, root->bounds(), translate, &render_surface_layer_list_impl);
     inputs.device_scale_factor = device_scale_factor;
     inputs.property_trees->needs_rebuild = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     gfx::Transform device_scaled_translate = translate;
     device_scaled_translate.Scale(device_scale_factor, device_scale_factor);
     EXPECT_EQ(device_scaled_translate,
@@ -1222,7 +1222,7 @@
     inputs.page_scale_factor = page_scale_factor;
     inputs.page_scale_layer = root;
     inputs.property_trees->needs_rebuild = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     gfx::Transform page_scaled_translate = translate;
     page_scaled_translate.Scale(page_scale_factor, page_scale_factor);
     EXPECT_EQ(page_scaled_translate,
@@ -1240,7 +1240,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), composite, &render_surface_layer_list_impl);
     inputs.property_trees->needs_rebuild = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     gfx::Transform compositeSquared = composite;
     compositeSquared.ConcatTransform(composite);
     EXPECT_TRANSFORMATION_MATRIX_EQ(
@@ -1300,7 +1300,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       parent, parent->bounds(), &render_surface_layer_list);
   inputs.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   // Since the layer is transparent, render_surface1->render_surface() should
   // not have gotten added anywhere.  Also, the drawable content rect should not
@@ -1341,7 +1341,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         parent, parent->bounds(), &render_surface_layer_list);
     inputs.can_adjust_raster_scales = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
     EXPECT_EQ(2U, render_surface_layer_list.size());
   }
   // The layer is fully transparent, but has a background filter, so it
@@ -1364,7 +1364,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         parent, parent->bounds(), &render_surface_layer_list);
     inputs.can_adjust_raster_scales = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
   }
 
   node = effect_tree.Node(render_surface1->effect_tree_index());
@@ -1402,7 +1402,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root, root->bounds(), &render_surface_layer_list);
   inputs.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   ASSERT_TRUE(parent->render_surface());
   EXPECT_EQ(2U, parent->render_surface()->layer_list().size());
@@ -3438,7 +3438,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root, gfx::Size(), &render_surface_layer_list_impl);
 
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
   ASSERT_TRUE(root->render_surface());
   EXPECT_FALSE(root->is_clipped());
 
@@ -5201,7 +5201,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_layer, root_layer->bounds(), &render_surface_layer_list);
   inputs.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   // We should have one render surface and two layers. The child
   // layer should be included even though it is transparent.
@@ -5216,7 +5216,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs2(
       root_layer, root_layer->bounds(), &render_surface_layer_list2);
   inputs2.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs2);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs2);
 
   LayerImpl* child_ptr = root_layer->layer_tree_impl()->LayerById(2);
   EffectTree& tree =
@@ -5233,7 +5233,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs3(
       root_layer, root_layer->bounds(), &render_surface_layer_list3);
   inputs3.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs3);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs3);
 
   child_ptr = root_layer->layer_tree_impl()->LayerById(2);
   tree = root_layer->layer_tree_impl()->property_trees()->effect_tree;
@@ -5531,7 +5531,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_layer, root_layer->bounds(), &render_surface_layer_list);
   inputs.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   // We should have one render surface and two layers. The grand child has
   // hidden itself.
@@ -5581,7 +5581,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_layer, root_layer->bounds(), &render_surface_layer_list);
   inputs.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   // We should have one render surface and one layers. The child has
   // hidden itself and the grand child.
@@ -5694,7 +5694,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_layer, root_layer->bounds(), &render_surface_layer_list);
   inputs.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   EXPECT_GT(root_layer->num_copy_requests_in_target_subtree(), 0);
   EXPECT_GT(copy_grand_parent_layer->num_copy_requests_in_target_subtree(), 0);
@@ -5807,7 +5807,7 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root_layer, root_layer->bounds(), &render_surface_layer_list);
   inputs.can_adjust_raster_scales = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   // We should have two render surface, as the others are clipped out.
   ASSERT_EQ(2u, render_surface_layer_list.size());
@@ -6329,7 +6329,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root_layer, root_layer->bounds(), &render_surface_layer_list);
     inputs.can_render_to_separate_surface = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
     EXPECT_EQ(2u, render_surface_layer_list.size());
 
@@ -6360,7 +6360,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root_layer, root_layer->bounds(), &render_surface_layer_list);
     inputs.can_render_to_separate_surface = false;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
     EXPECT_EQ(1u, render_surface_layer_list.size());
 
@@ -6650,7 +6650,7 @@
       root, root->bounds(), identity_transform,
       &render_surface_layer_list_impl);
   inputs.device_scale_factor = device_scale_factor;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   EXPECT_EQ(scroll_child->effect_tree_index(),
             scroll_child_target->effect_tree_index());
@@ -7085,7 +7085,7 @@
     root->layer_tree_impl()
         ->property_trees()
         ->transform_tree.set_source_to_parent_updates_allowed(false);
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
     EXPECT_TRANSFORMATION_MATRIX_EQ(
         container_layer->draw_properties().screen_space_transform,
@@ -7110,7 +7110,7 @@
     LayerImplList render_surface_layer_list;
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), &render_surface_layer_list);
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
     EXPECT_TRANSFORMATION_MATRIX_EQ(
         container_layer->draw_properties().screen_space_transform,
@@ -7138,7 +7138,7 @@
     LayerImplList render_surface_layer_list;
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), &render_surface_layer_list);
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
     EXPECT_TRANSFORMATION_MATRIX_EQ(
         container_layer->draw_properties().screen_space_transform,
@@ -7932,7 +7932,7 @@
   inputs.page_scale_factor = page_scale_factor;
   inputs.can_adjust_raster_scales = true;
   inputs.page_scale_layer = root_layer;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   EXPECT_FLOAT_EQ(3.f, root_layer->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(9.f, child1_layer->GetIdealContentsScale());
@@ -7965,7 +7965,7 @@
   inputs.device_scale_factor = device_scale_factor;
   inputs.can_adjust_raster_scales = true;
   root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   EXPECT_FLOAT_EQ(12.f, root_layer->GetIdealContentsScale());
   EXPECT_FLOAT_EQ(36.f, child1_layer->GetIdealContentsScale());
@@ -8019,7 +8019,7 @@
   inputs.device_scale_factor = 2.f;
   inputs.page_scale_factor = 1.f;
   inputs.page_scale_layer = NULL;
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   // Layers in the root render surface have their visible content rect clipped
   // by the viewport.
@@ -8081,11 +8081,11 @@
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root, device_viewport_size, &layer_impl_list);
 
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
   EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect());
 
   root->SetBoundsDelta(gfx::Vector2dF(0.0, 50.0));
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   gfx::Rect affected_by_delta(0, 0, root_size.width(),
                               root_size.height() + 50);
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 8583ec4..27d28a3 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -63,13 +63,13 @@
 #include "cc/quads/shared_quad_state.h"
 #include "cc/quads/solid_color_draw_quad.h"
 #include "cc/quads/texture_draw_quad.h"
-#include "cc/raster/bitmap_tile_task_worker_pool.h"
+#include "cc/raster/bitmap_raster_buffer_provider.h"
+#include "cc/raster/gpu_raster_buffer_provider.h"
 #include "cc/raster/gpu_rasterizer.h"
-#include "cc/raster/gpu_tile_task_worker_pool.h"
-#include "cc/raster/one_copy_tile_task_worker_pool.h"
+#include "cc/raster/one_copy_raster_buffer_provider.h"
+#include "cc/raster/raster_buffer_provider.h"
 #include "cc/raster/synchronous_task_graph_runner.h"
-#include "cc/raster/tile_task_worker_pool.h"
-#include "cc/raster/zero_copy_tile_task_worker_pool.h"
+#include "cc/raster/zero_copy_raster_buffer_provider.h"
 #include "cc/resources/memory_history.h"
 #include "cc/resources/resource_pool.h"
 #include "cc/resources/ui_resource_bitmap.h"
@@ -79,6 +79,7 @@
 #include "cc/tiles/picture_layer_tiling.h"
 #include "cc/tiles/raster_tile_priority_queue.h"
 #include "cc/tiles/software_image_decode_controller.h"
+#include "cc/tiles/tile_task_manager.h"
 #include "cc/trees/damage_tracker.h"
 #include "cc/trees/draw_property_utils.h"
 #include "cc/trees/latency_info_swap_promise_monitor.h"
@@ -2134,7 +2135,9 @@
 }
 
 void LayerTreeHostImpl::CreateTileManagerResources() {
-  CreateResourceAndTileTaskWorkerPool(&tile_task_worker_pool_, &resource_pool_);
+  std::unique_ptr<RasterBufferProvider> raster_buffer_provider;
+  CreateResourceAndRasterBufferProvider(&raster_buffer_provider,
+                                        &resource_pool_);
 
   if (use_gpu_rasterization_) {
     image_decode_controller_ = base::WrapUnique(new GpuImageDecodeController(
@@ -2146,24 +2149,6 @@
             settings_.renderer_settings.preferred_tile_format));
   }
 
-  // TODO(vmpstr): Initialize tile task limit at ctor time.
-  tile_manager_->SetResources(
-      resource_pool_.get(), tile_task_worker_pool_.get(),
-      image_decode_controller_.get(),
-      is_synchronous_single_threaded_ ? std::numeric_limits<size_t>::max()
-                                      : settings_.scheduled_raster_task_limit,
-      use_gpu_rasterization_);
-  UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
-}
-
-void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool(
-    std::unique_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
-    std::unique_ptr<ResourcePool>* resource_pool) {
-  DCHECK(GetTaskRunner());
-  // TODO(vmpstr): Make this a DCHECK (or remove) when crbug.com/419086 is
-  // resolved.
-  CHECK(resource_provider_);
-
   // Pass the single-threaded synchronous task graph runner to the worker pool
   // if we're in synchronous single-threaded mode.
   TaskGraphRunner* task_graph_runner = task_graph_runner_;
@@ -2174,13 +2159,34 @@
     task_graph_runner = single_thread_synchronous_task_graph_runner_.get();
   }
 
+  tile_task_manager_ = TileTaskManagerImpl::Create(
+      std::move(raster_buffer_provider), task_graph_runner);
+
+  // TODO(vmpstr): Initialize tile task limit at ctor time.
+  tile_manager_->SetResources(
+      resource_pool_.get(), image_decode_controller_.get(),
+      tile_task_manager_.get(),
+      is_synchronous_single_threaded_ ? std::numeric_limits<size_t>::max()
+                                      : settings_.scheduled_raster_task_limit,
+      use_gpu_rasterization_);
+  UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
+}
+
+void LayerTreeHostImpl::CreateResourceAndRasterBufferProvider(
+    std::unique_ptr<RasterBufferProvider>* raster_buffer_provider,
+    std::unique_ptr<ResourcePool>* resource_pool) {
+  DCHECK(GetTaskRunner());
+  // TODO(vmpstr): Make this a DCHECK (or remove) when crbug.com/419086 is
+  // resolved.
+  CHECK(resource_provider_);
+
   ContextProvider* context_provider = output_surface_->context_provider();
   if (!context_provider) {
     *resource_pool =
         ResourcePool::Create(resource_provider_.get(), GetTaskRunner());
 
-    *tile_task_worker_pool = BitmapTileTaskWorkerPool::Create(
-        GetTaskRunner(), task_graph_runner, resource_provider_.get());
+    *raster_buffer_provider =
+        BitmapRasterBufferProvider::Create(resource_provider_.get());
     return;
   }
 
@@ -2192,10 +2198,9 @@
 
     int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0;
 
-    *tile_task_worker_pool = GpuTileTaskWorkerPool::Create(
-        GetTaskRunner(), task_graph_runner, context_provider,
-        resource_provider_.get(), settings_.use_distance_field_text,
-        msaa_sample_count);
+    *raster_buffer_provider = GpuRasterBufferProvider::Create(
+        context_provider, resource_provider_.get(),
+        settings_.use_distance_field_text, msaa_sample_count);
     return;
   }
 
@@ -2214,8 +2219,8 @@
     *resource_pool = ResourcePool::CreateForGpuMemoryBufferResources(
         resource_provider_.get(), GetTaskRunner());
 
-    *tile_task_worker_pool = ZeroCopyTileTaskWorkerPool::Create(
-        GetTaskRunner(), task_graph_runner, resource_provider_.get(),
+    *raster_buffer_provider = ZeroCopyRasterBufferProvider::Create(
+        resource_provider_.get(),
         settings_.renderer_settings.preferred_tile_format);
     return;
   }
@@ -2226,10 +2231,10 @@
   const int max_copy_texture_chromium_size =
       context_provider->ContextCapabilities().max_copy_texture_chromium_size;
 
-  *tile_task_worker_pool = OneCopyTileTaskWorkerPool::Create(
-      GetTaskRunner(), task_graph_runner, context_provider,
-      resource_provider_.get(), max_copy_texture_chromium_size,
-      settings_.use_partial_raster, settings_.max_staging_buffer_usage_in_bytes,
+  *raster_buffer_provider = OneCopyRasterBufferProvider::Create(
+      GetTaskRunner(), context_provider, resource_provider_.get(),
+      max_copy_texture_chromium_size, settings_.use_partial_raster,
+      settings_.max_staging_buffer_usage_in_bytes,
       settings_.renderer_settings.preferred_tile_format);
 }
 
@@ -2243,7 +2248,7 @@
   ClearUIResources();
   tile_manager_->FinishTasksAndCleanUp();
   resource_pool_ = nullptr;
-  tile_task_worker_pool_ = nullptr;
+  tile_task_manager_ = nullptr;
   single_thread_synchronous_task_graph_runner_ = nullptr;
   image_decode_controller_ = nullptr;
 }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index ae4f257..935f4f0 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -64,7 +64,8 @@
 class PageScaleAnimation;
 class PictureLayerImpl;
 class RasterTilePriorityQueue;
-class TileTaskWorkerPool;
+class TileTaskManager;
+class RasterBufferProvider;
 class RenderPassDrawQuad;
 class RenderingStatsInstrumentation;
 class ResourcePool;
@@ -575,8 +576,8 @@
   bool SupportsImplScrolling() const;
   bool CommitToActiveTree() const;
 
-  virtual void CreateResourceAndTileTaskWorkerPool(
-      std::unique_ptr<TileTaskWorkerPool>* tile_task_worker_pool,
+  virtual void CreateResourceAndRasterBufferProvider(
+      std::unique_ptr<RasterBufferProvider>* raster_buffer_provider,
       std::unique_ptr<ResourcePool>* resource_pool);
 
   bool prepare_tiles_needed() const { return tile_priorities_dirty_; }
@@ -731,7 +732,7 @@
   bool use_msaa_;
   GpuRasterizationStatus gpu_rasterization_status_;
   bool tree_resources_for_gpu_rasterization_dirty_;
-  std::unique_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
+  std::unique_ptr<TileTaskManager> tile_task_manager_;
   std::unique_ptr<ResourcePool> resource_pool_;
   std::unique_ptr<Renderer> renderer_;
   std::unique_ptr<ImageDecodeController> image_decode_controller_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 06f81fe..d96a01c 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -1434,7 +1434,7 @@
   LayerImplList list;
   LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
       root, gfx::Size(50, 50), &list);
-  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+  LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
   EXPECT_FALSE(did_request_next_frame_);
   EXPECT_FALSE(did_request_redraw_);
diff --git a/cc/trees/layer_tree_host_unittest_serialization.cc b/cc/trees/layer_tree_host_unittest_serialization.cc
index 2e4dc0da0..00852bc 100644
--- a/cc/trees/layer_tree_host_unittest_serialization.cc
+++ b/cc/trees/layer_tree_host_unittest_serialization.cc
@@ -67,8 +67,6 @@
               layer_tree_host_dst_->needs_meta_info_recomputation_);
     EXPECT_EQ(layer_tree_host_src_->source_frame_number_,
               layer_tree_host_dst_->source_frame_number_);
-    EXPECT_EQ(layer_tree_host_src_->meta_information_sequence_number_,
-              layer_tree_host_dst_->meta_information_sequence_number_);
     EXPECT_EQ(layer_tree_host_src_->root_layer()->id(),
               layer_tree_host_dst_->root_layer()->id());
     EXPECT_EQ(layer_tree_host_dst_.get(),
@@ -184,7 +182,6 @@
     layer_tree_host_src_->needs_meta_info_recomputation_ =
         !layer_tree_host_src_->needs_meta_info_recomputation_;
     layer_tree_host_src_->source_frame_number_ *= 3;
-    layer_tree_host_src_->meta_information_sequence_number_ *= 3;
 
     // Just fake setup a layer for both source and dest.
     scoped_refptr<Layer> root_layer_src = Layer::Create();
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 858506a..74603d5 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -953,7 +953,7 @@
 }
 
 void LayerTreeImpl::BuildPropertyTreesForTesting() {
-  LayerTreeHostCommon::PreCalculateMetaInformationForTesting(root_layer_);
+  PropertyTreeBuilder::PreCalculateMetaInformationForTesting(root_layer_);
   property_trees_.transform_tree.set_source_to_parent_updates_allowed(true);
   PropertyTreeBuilder::BuildPropertyTrees(
       root_layer_, PageScaleLayer(), InnerViewportScrollLayer(),
diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc
index 8b54ce2..9c577fb1e 100644
--- a/cc/trees/occlusion_tracker_unittest.cc
+++ b/cc/trees/occlusion_tracker_unittest.cc
@@ -232,7 +232,7 @@
     LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
         root, root->bounds(), &render_surface_layer_list_impl_);
     inputs.can_adjust_raster_scales = true;
-    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+    LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs);
 
     layer_iterator_ = layer_iterator_begin_ =
         LayerIterator::Begin(&render_surface_layer_list_impl_);
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index a265b4e..1c4c772 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -80,6 +80,137 @@
   return layer->test_properties()->position_constraint;
 }
 
+struct PreCalculateMetaInformationRecursiveData {
+  size_t num_unclipped_descendants;
+  int num_layer_or_descendants_with_copy_request;
+  int num_layer_or_descendants_with_touch_handler;
+  int num_descendants_that_draw_content;
+
+  PreCalculateMetaInformationRecursiveData()
+      : num_unclipped_descendants(0),
+        num_layer_or_descendants_with_copy_request(0),
+        num_layer_or_descendants_with_touch_handler(0),
+        num_descendants_that_draw_content(0) {}
+
+  void Merge(const PreCalculateMetaInformationRecursiveData& data) {
+    num_layer_or_descendants_with_copy_request +=
+        data.num_layer_or_descendants_with_copy_request;
+    num_layer_or_descendants_with_touch_handler +=
+        data.num_layer_or_descendants_with_touch_handler;
+    num_unclipped_descendants += data.num_unclipped_descendants;
+    num_descendants_that_draw_content += data.num_descendants_that_draw_content;
+  }
+};
+
+static inline bool IsRootLayer(const Layer* layer) {
+  return !layer->parent();
+}
+
+static bool HasInvertibleOrAnimatedTransform(Layer* layer) {
+  return layer->transform_is_invertible() ||
+         layer->HasPotentiallyRunningTransformAnimation();
+}
+
+static bool HasInvertibleOrAnimatedTransformForTesting(LayerImpl* layer) {
+  return layer->transform().IsInvertible() ||
+         layer->HasPotentiallyRunningTransformAnimation();
+}
+
+static bool IsMetaInformationRecomputationNeeded(Layer* layer) {
+  return layer->layer_tree_host()->needs_meta_info_recomputation();
+}
+
+// Recursively walks the layer tree(if needed) to compute any information
+// that is needed before doing the main recursion.
+static void PreCalculateMetaInformationInternal(
+    Layer* layer,
+    PreCalculateMetaInformationRecursiveData* recursive_data) {
+  if (!IsMetaInformationRecomputationNeeded(layer)) {
+    DCHECK(IsRootLayer(layer));
+    return;
+  }
+
+  if (layer->clip_parent())
+    recursive_data->num_unclipped_descendants++;
+
+  if (!HasInvertibleOrAnimatedTransform(layer)) {
+    // Layers with singular transforms should not be drawn, the whole subtree
+    // can be skipped.
+    return;
+  }
+
+  for (size_t i = 0; i < layer->children().size(); ++i) {
+    Layer* child_layer = layer->child_at(i);
+
+    PreCalculateMetaInformationRecursiveData data_for_child;
+    PreCalculateMetaInformationInternal(child_layer, &data_for_child);
+    recursive_data->Merge(data_for_child);
+  }
+
+  if (layer->clip_children()) {
+    size_t num_clip_children = layer->clip_children()->size();
+    DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
+    recursive_data->num_unclipped_descendants -= num_clip_children;
+  }
+
+  if (layer->HasCopyRequest())
+    recursive_data->num_layer_or_descendants_with_copy_request++;
+
+  if (!layer->touch_event_handler_region().IsEmpty())
+    recursive_data->num_layer_or_descendants_with_touch_handler++;
+
+  layer->set_num_unclipped_descendants(
+      recursive_data->num_unclipped_descendants);
+
+  if (IsRootLayer(layer))
+    layer->layer_tree_host()->SetNeedsMetaInfoRecomputation(false);
+}
+
+static void PreCalculateMetaInformationInternalForTesting(
+    LayerImpl* layer,
+    PreCalculateMetaInformationRecursiveData* recursive_data) {
+  if (layer->test_properties()->clip_parent)
+    recursive_data->num_unclipped_descendants++;
+
+  if (!HasInvertibleOrAnimatedTransformForTesting(layer)) {
+    // Layers with singular transforms should not be drawn, the whole subtree
+    // can be skipped.
+    return;
+  }
+
+  for (size_t i = 0; i < layer->children().size(); ++i) {
+    LayerImpl* child_layer = layer->child_at(i);
+
+    PreCalculateMetaInformationRecursiveData data_for_child;
+    PreCalculateMetaInformationInternalForTesting(child_layer, &data_for_child);
+    recursive_data->Merge(data_for_child);
+  }
+
+  if (layer->test_properties()->clip_children) {
+    size_t num_clip_children = layer->test_properties()->clip_children->size();
+    DCHECK_GE(recursive_data->num_unclipped_descendants, num_clip_children);
+    recursive_data->num_unclipped_descendants -= num_clip_children;
+  }
+
+  if (layer->HasCopyRequest())
+    recursive_data->num_layer_or_descendants_with_copy_request++;
+
+  if (!layer->touch_event_handler_region().IsEmpty())
+    recursive_data->num_layer_or_descendants_with_touch_handler++;
+
+  layer->draw_properties().num_unclipped_descendants =
+      recursive_data->num_unclipped_descendants;
+  layer->set_layer_or_descendant_has_touch_handler(
+      (recursive_data->num_layer_or_descendants_with_touch_handler != 0));
+  // TODO(enne): this should be synced from the main thread, so is only
+  // for tests constructing layers on the compositor thread.
+  layer->test_properties()->num_descendants_that_draw_content =
+      recursive_data->num_descendants_that_draw_content;
+
+  if (layer->DrawsContent())
+    recursive_data->num_descendants_that_draw_content++;
+}
+
 static Layer* ScrollParent(Layer* layer) {
   return layer->scroll_parent();
 }
@@ -951,6 +1082,34 @@
 
 }  // namespace
 
+void CC_EXPORT
+PropertyTreeBuilder::PreCalculateMetaInformation(Layer* root_layer) {
+  PreCalculateMetaInformationRecursiveData recursive_data;
+  PreCalculateMetaInformationInternal(root_layer, &recursive_data);
+}
+
+void CC_EXPORT PropertyTreeBuilder::PreCalculateMetaInformationForTesting(
+    LayerImpl* root_layer) {
+  PreCalculateMetaInformationRecursiveData recursive_data;
+  PreCalculateMetaInformationInternalForTesting(root_layer, &recursive_data);
+}
+
+Layer* PropertyTreeBuilder::FindFirstScrollableLayer(Layer* layer) {
+  if (!layer)
+    return nullptr;
+
+  if (layer->scrollable())
+    return layer;
+
+  for (size_t i = 0; i < layer->children().size(); ++i) {
+    Layer* found = FindFirstScrollableLayer(layer->children()[i].get());
+    if (found)
+      return found;
+  }
+
+  return nullptr;
+}
+
 template <typename LayerType>
 void BuildPropertyTreesTopLevelInternal(
     LayerType* root_layer,
diff --git a/cc/trees/property_tree_builder.h b/cc/trees/property_tree_builder.h
index 49a9175..be6829e 100644
--- a/cc/trees/property_tree_builder.h
+++ b/cc/trees/property_tree_builder.h
@@ -16,6 +16,12 @@
 
 class PropertyTreeBuilder {
  public:
+  static Layer* FindFirstScrollableLayer(Layer* root_layer);
+
+  static void CC_EXPORT PreCalculateMetaInformation(Layer* root_layer);
+  static void CC_EXPORT
+  PreCalculateMetaInformationForTesting(LayerImpl* root_layer);
+
   static void CC_EXPORT
   BuildPropertyTrees(Layer* root_layer,
                      const Layer* page_scale_layer,
diff --git a/chrome/VERSION b/chrome/VERSION
index 9e03b5a..b6a4f75b 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=52
 MINOR=0
-BUILD=2720
+BUILD=2721
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index afc2815..52c207c 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -230,6 +230,7 @@
     "//chrome/browser/android/activity_type_ids.h",
     "//chrome/browser/android/feedback/connectivity_checker.cc",
     "//chrome/browser/android/ntp/most_visited_sites.cc",
+    "//chrome/browser/android/policy/policy_auditor.cc",
     "//chrome/browser/android/shortcut_info.h",
     "//chrome/browser/android/tab_android.h",
     "//chrome/browser/browsing_data/browsing_data_counter_utils.h",
diff --git a/chrome/android/java/res/layout/fre_data_reduction_proxy.xml b/chrome/android/java/res/layout/fre_data_reduction_proxy.xml
index 5aaaef5..fb04088 100644
--- a/chrome/android/java/res/layout/fre_data_reduction_proxy.xml
+++ b/chrome/android/java/res/layout/fre_data_reduction_proxy.xml
@@ -6,6 +6,7 @@
 -->
 <org.chromium.chrome.browser.firstrun.FirstRunView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:chrome="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
@@ -80,26 +81,18 @@
         </LinearLayout>
     </ScrollView>
 
-    <LinearLayout
-        android:id="@+id/button_bar"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/fre_button_bar_height"
-        android:layout_gravity="bottom"
-        android:orientation="vertical">
-
-        <View style="@style/ButtonBarTopDivider" />
-
-        <Button
-            android:id="@+id/next_button"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/fre_button_bar_height"
-            android:layout_gravity="bottom"
-            android:background="?attr/listChoiceBackgroundIndicator"
-            android:padding="16dp"
-            android:text="@string/next"
-            android:textAllCaps="true"
-            android:textColor="@color/light_active_color"
-            android:textSize="@dimen/fre_button_text_size"
-            style="@style/ButtonCompatBorderless" />
-    </LinearLayout>
+    <!-- fre_button_bar_height = 52dp = layout_height + layout_marginBottom -->
+    <org.chromium.ui.widget.ButtonCompat
+        android:id="@+id/next_button"
+        android:layout_width="wrap_content"
+        android:layout_height="36dp"
+        android:layout_marginBottom="16dp"
+        android:layout_gravity="bottom|center_horizontal"
+        android:paddingStart="@dimen/fre_button_padding"
+        android:paddingEnd="@dimen/fre_button_padding"
+        android:text="@string/next"
+        android:textAllCaps="true"
+        android:textColor="@android:color/white"
+        android:textSize="@dimen/fre_button_text_size"
+        chrome:buttonColor="@color/light_active_color"/>
 </org.chromium.chrome.browser.firstrun.FirstRunView>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/fre_tosanduma.xml b/chrome/android/java/res/layout/fre_tosanduma.xml
index 76d558b..0b59d586 100644
--- a/chrome/android/java/res/layout/fre_tosanduma.xml
+++ b/chrome/android/java/res/layout/fre_tosanduma.xml
@@ -6,6 +6,7 @@
 -->
 <org.chromium.chrome.browser.firstrun.FirstRunView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:chrome="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
@@ -77,26 +78,18 @@
         </LinearLayout>
     </ScrollView>
 
-    <LinearLayout
-        android:id="@+id/button_bar"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/fre_button_bar_height"
-        android:layout_gravity="bottom"
-        android:orientation="vertical">
-
-        <View style="@style/ButtonBarTopDivider" />
-
-        <Button
-            android:id="@+id/terms_accept"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/fre_button_bar_height"
-            android:layout_gravity="bottom"
-            android:background="?attr/listChoiceBackgroundIndicator"
-            android:padding="16dp"
-            android:text="@string/fre_accept_continue"
-            android:textAllCaps="true"
-            android:textColor="@color/light_active_color"
-            android:textSize="@dimen/fre_button_text_size"
-            style="@style/ButtonCompatBorderless" />
-    </LinearLayout>
+    <!-- fre_button_bar_height = 52dp = layout_height + layout_marginBottom -->
+    <org.chromium.ui.widget.ButtonCompat
+        android:id="@+id/terms_accept"
+        android:layout_width="wrap_content"
+        android:layout_height="36dp"
+        android:layout_marginBottom="16dp"
+        android:layout_gravity="bottom|center_horizontal"
+        android:paddingStart="@dimen/fre_button_padding"
+        android:paddingEnd="@dimen/fre_button_padding"
+        android:text="@string/fre_accept_continue"
+        android:textAllCaps="true"
+        android:textColor="@android:color/white"
+        android:textSize="@dimen/fre_button_text_size"
+        chrome:buttonColor="@color/light_active_color"/>
 </org.chromium.chrome.browser.firstrun.FirstRunView>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/payment_request.xml b/chrome/android/java/res/layout/payment_request.xml
index 973fe5bd..84814ccd 100644
--- a/chrome/android/java/res/layout/payment_request.xml
+++ b/chrome/android/java/res/layout/payment_request.xml
@@ -46,7 +46,7 @@
                 android:id="@+id/hostname"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
-                android:ellipsize="end"
+                android:ellipsize="start"
                 android:maxLines="1"
                 android:singleLine="true"
                 android:textColor="@color/descriptive_text_color"
@@ -151,6 +151,14 @@
                 android:padding="16dp"
                 android:visibility="gone" />
 
+            <TextView
+                android:id="@+id/selectShippingAddressPrompt"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:text="@string/payments_select_shipping_address_prompt"
+                android:padding="16dp"
+                android:visibility="gone" />
+
             <RadioGroup
                 android:id="@+id/shippingAddresses"
                 android:layout_height="wrap_content"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 0da9eea..6bde79e 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -153,7 +153,7 @@
     <!-- First Run Experience dimensions -->
     <dimen name="fre_content_margin">24dp</dimen>
     <dimen name="fre_vertical_spacing">32dp</dimen>
-    <dimen name="fre_button_bar_height">56dp</dimen>
+    <dimen name="fre_button_bar_height">52dp</dimen>
     <dimen name="fre_button_padding">12dp</dimen>
     <dimen name="fre_margin">24dp</dimen>
     <dimen name="fre_title_text_size">24sp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
index 6c8c6fb..70ea42e4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.os.AsyncTask;
+import android.os.SystemClock;
 import android.text.TextUtils;
 
 import org.chromium.base.FieldTrialList;
@@ -14,10 +15,12 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.VisibleForTesting;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.bookmarkswidget.BookmarkWidgetProvider;
 import org.chromium.chrome.browser.crash.CrashFileManager;
 import org.chromium.chrome.browser.crash.MinidumpUploadService;
 import org.chromium.chrome.browser.media.MediaCaptureNotificationService;
+import org.chromium.chrome.browser.metrics.UmaUtils;
 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
 import org.chromium.chrome.browser.physicalweb.PhysicalWeb;
 import org.chromium.chrome.browser.precache.PrecacheLauncher;
@@ -26,6 +29,8 @@
 import org.chromium.chrome.browser.share.ShareHelper;
 import org.chromium.content.browser.ChildProcessLauncher;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * Handler for application level tasks to be completed on deferred startup.
  */
@@ -65,6 +70,10 @@
                 try {
                     TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
                     if (!crashDumpUploadingCommandLineDisabled) {
+                        RecordHistogram.recordMediumTimesHistogram(
+                                "UMA.Debug.EnableCrashUpload.Uptime",
+                                SystemClock.uptimeMillis() - UmaUtils.getMainEntryPointTime(),
+                                TimeUnit.MILLISECONDS);
                         PrivacyPreferencesManager.getInstance(application)
                                 .enablePotentialCrashUploading();
                         MinidumpUploadService.tryUploadAllCrashDumps(application);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
index 8f765fc..b70b652 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -368,8 +368,8 @@
 
         // Check if we should notify OverviewModeObservers.
         if (isOverviewLayout(layoutBeingShown)) {
-            boolean showToolbar =
-                    !mEnableAnimations || getTabModelSelector().getCurrentModel().getCount() <= 0;
+            boolean showToolbar = animate && (!mEnableAnimations
+                    || getTabModelSelector().getCurrentModel().getCount() <= 0);
             for (OverviewModeObserver observer : mOverviewModeObservers) {
                 observer.onOverviewModeStartedShowing(showToolbar);
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/cookies/CanonicalCookie.java b/chrome/android/java/src/org/chromium/chrome/browser/cookies/CanonicalCookie.java
index eead2a8..c8d67b5d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/cookies/CanonicalCookie.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/cookies/CanonicalCookie.java
@@ -7,9 +7,13 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Java representation of net/cookies/canonical_cookie.h.
+ *
+ * Also has static methods serialize Cookies.
  */
 class CanonicalCookie {
     private final String mUrl;
@@ -22,13 +26,13 @@
     private final long mLastAccess;
     private final boolean mSecure;
     private final boolean mHttpOnly;
-    private final boolean mSameSite;
+    private final int mSameSite;
     private final int mPriority;
 
     /** Constructs a CanonicalCookie */
     CanonicalCookie(String url, String name, String value, String domain, String path,
             long creation, long expiration, long lastAccess, boolean secure, boolean httpOnly,
-            boolean sameSite, int priority) {
+            int sameSite, int priority) {
         mUrl = url;
         mName = name;
         mValue = value;
@@ -53,8 +57,8 @@
         return mHttpOnly;
     }
 
-    /** @return True if the cookie is Same-Site. */
-    boolean isSameSite() {
+    /** @return SameSite enum */
+    int getSameSite() {
         return mSameSite;
     }
 
@@ -103,13 +107,63 @@
         return mValue;
     }
 
-    /**
-     * Serializes for saving to disk. Does not close the stream.
-     * It is up to the caller to do so.
-     *
-     * @param out Stream to write the cookie to.
-     */
-    void saveToStream(DataOutputStream out) throws IOException {
+    // Note incognito state cannot persist across app installs since the encryption key is stored
+    // in the activity state bundle. So the version here is more of a guard than a real version
+    // used for format migrations.
+    private static final int SERIALIZATION_VERSION = 20160426;
+
+    static void saveListToStream(DataOutputStream out, CanonicalCookie[] cookies)
+            throws IOException {
+        if (out == null) {
+            throw new IllegalArgumentException("out arg is null");
+        }
+        if (cookies == null) {
+            throw new IllegalArgumentException("cookies arg is null");
+        }
+        for (CanonicalCookie cookie : cookies) {
+            if (cookie == null) {
+                throw new IllegalArgumentException("cookies arg contains null value");
+            }
+        }
+
+        int length = cookies.length;
+        out.writeInt(SERIALIZATION_VERSION);
+        out.writeInt(length);
+        for (int i = 0; i < length; ++i) {
+            cookies[i].saveToStream(out);
+        }
+    }
+
+    // Not private for tests.
+    static class UnexpectedFormatException extends Exception {
+        public UnexpectedFormatException(String message) {
+            super(message);
+        }
+    }
+
+    static List<CanonicalCookie> readListFromStream(DataInputStream in)
+            throws IOException, UnexpectedFormatException {
+        if (in == null) {
+            throw new IllegalArgumentException("in arg is null");
+        }
+
+        final int version = in.readInt();
+        if (version != SERIALIZATION_VERSION) {
+            throw new UnexpectedFormatException("Unexpected version");
+        }
+        final int length = in.readInt();
+        if (length < 0) {
+            throw new UnexpectedFormatException("Negative length: " + length);
+        }
+
+        ArrayList<CanonicalCookie> cookies = new ArrayList<>(length);
+        for (int i = 0; i < length; ++i) {
+            cookies.add(createFromStream(in));
+        }
+        return cookies;
+    }
+
+    private void saveToStream(DataOutputStream out) throws IOException {
         out.writeUTF(mUrl);
         out.writeUTF(mName);
         out.writeUTF(mValue);
@@ -120,20 +174,13 @@
         out.writeLong(mLastAccess);
         out.writeBoolean(mSecure);
         out.writeBoolean(mHttpOnly);
-        out.writeBoolean(mSameSite);
+        out.writeInt(mSameSite);
         out.writeInt(mPriority);
     }
 
-    /**
-     * Constructs a cookie by deserializing a single entry from the
-     * input stream.
-     *
-     * @param in Stream to read a cookie entry from.
-     */
-    static CanonicalCookie createFromStream(DataInputStream in)
-            throws IOException {
+    private static CanonicalCookie createFromStream(DataInputStream in) throws IOException {
         return new CanonicalCookie(in.readUTF(), in.readUTF(), in.readUTF(), in.readUTF(),
                 in.readUTF(), in.readLong(), in.readLong(), in.readLong(), in.readBoolean(),
-                in.readBoolean(), in.readBoolean(), in.readInt());
+                in.readBoolean(), in.readInt(), in.readInt());
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java
index c5c42bf..0cfafdb9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java
@@ -18,7 +18,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
-import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -40,13 +39,6 @@
     /** Used for logging. */
     private static final String TAG = "CookiesFetcher";
 
-    /**
-     * Used to confirm that the current cipher key matches the previously used cipher key when
-     * restoring data.  If this value cannot be read from the file, the file is likely garbage.
-     * TODO(acleung): May be use real cryptographic integrity checks on the whole file, instead.
-     */
-    private static final String MAGIC_STRING = "c0Ok135";
-
     /** Native-side pointer. */
     private final long mNativeCookiesFetcher;
 
@@ -119,7 +111,7 @@
             @Override
             protected List<CanonicalCookie> doInBackground(Void... voids) {
                 // Read cookies from disk on a background thread to avoid strict mode violations.
-                ArrayList<CanonicalCookie> cookies = new ArrayList<CanonicalCookie>();
+                List<CanonicalCookie> cookies = new ArrayList<CanonicalCookie>();
                 DataInputStream in = null;
                 try {
                     Cipher cipher = CipherFactory.getInstance().getCipher(Cipher.DECRYPT_MODE);
@@ -132,27 +124,14 @@
 
                     FileInputStream streamIn = new FileInputStream(fileIn);
                     in = new DataInputStream(new CipherInputStream(streamIn, cipher));
-                    String check = in.readUTF();
-                    if (!MAGIC_STRING.equals(check)) {
-                        // Stale cookie file. Chrome might have crashed before it
-                        // can delete the old file.
-                        return cookies;
-                    }
-                    try {
-                        while (true) {
-                            CanonicalCookie cookie = CanonicalCookie.createFromStream(in);
-                            cookies.add(cookie);
-                        }
-                    } catch (EOFException ignored) {
-                      // We are done.
-                    }
+                    cookies = CanonicalCookie.readListFromStream(in);
 
                     // The Cookie File should not be restored again. It'll be overwritten
                     // on the next onPause.
                     scheduleDeleteCookiesFile(context);
 
                 } catch (IOException e) {
-                    Log.w(TAG, "IOException during Cookie Restore");
+                    Log.w(TAG, "IOException during Cookie Restore", e);
                 } catch (Throwable t) {
                     Log.w(TAG, "Error restoring cookies.", t);
                 } finally {
@@ -174,7 +153,7 @@
                     nativeRestoreCookies(cookie.getUrl(), cookie.getName(), cookie.getValue(),
                             cookie.getDomain(), cookie.getPath(), cookie.getCreationDate(),
                             cookie.getExpirationDate(), cookie.getLastAccessDate(),
-                            cookie.isSecure(), cookie.isHttpOnly(), cookie.isSameSite(),
+                            cookie.isSecure(), cookie.isHttpOnly(), cookie.getSameSite(),
                             cookie.getPriority());
                 }
             }
@@ -219,7 +198,7 @@
     @CalledByNative
     private CanonicalCookie createCookie(String url, String name, String value, String domain,
             String path, long creation, long expiration, long lastAccess, boolean secure,
-            boolean httpOnly, boolean sameSite, int priority) {
+            boolean httpOnly, int sameSite, int priority) {
         return new CanonicalCookie(url, name, value, domain, path, creation, expiration, lastAccess,
                 secure, httpOnly, sameSite, priority);
     }
@@ -251,11 +230,7 @@
             CipherOutputStream cipherOut =
                     new CipherOutputStream(byteOut, cipher);
             out = new DataOutputStream(cipherOut);
-
-            out.writeUTF(MAGIC_STRING);
-            for (CanonicalCookie cookie : cookies) {
-                cookie.saveToStream(out);
-            }
+            CanonicalCookie.saveListToStream(out, cookies);
             out.close();
             ImportantFileWriterAndroid.writeFileAtomically(
                     fetchFileName(mContext), byteOut.toByteArray());
@@ -296,5 +271,5 @@
     private native void nativePersistCookies(long nativeCookiesFetcher);
     private static native void nativeRestoreCookies(String url, String name, String value,
             String domain, String path, long creation, long expiration, long lastAccess,
-            boolean secure, boolean httpOnly, boolean sameSite, int priority);
+            boolean secure, boolean httpOnly, int sameSite, int priority);
 }
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 e9bf7e0..5e03c96 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
@@ -710,6 +710,7 @@
         if (DomDistillerUrlUtils.isDistilledPage(url)) {
             url = DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(url);
         }
+        if (TextUtils.isEmpty(url)) url = getUrlToLoad();
         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.putExtra(ChromeLauncherActivity.EXTRA_IS_ALLOWED_TO_RETURN_TO_PARENT, false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DataReductionProxyFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DataReductionProxyFirstRunFragment.java
index 09fe40d..66a1a5ce 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DataReductionProxyFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DataReductionProxyFirstRunFragment.java
@@ -10,11 +10,11 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.Button;
 
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings;
 import org.chromium.chrome.browser.preferences.datareduction.DataReductionPromoScreen;
+import org.chromium.ui.widget.ButtonCompat;
 
 /**
  * The First Run Experience fragment that allows the user to opt in to Data Saver.
@@ -33,7 +33,7 @@
 
         final SwitchCompat enableDataSaverSwitch = (SwitchCompat) view
                 .findViewById(R.id.enable_data_saver_switch);
-        Button nextButton = (Button) view.findViewById(R.id.next_button);
+        ButtonCompat nextButton = (ButtonCompat) view.findViewById(R.id.next_button);
 
         enableDataSaverSwitch.setOnClickListener(new OnClickListener() {
             @Override
@@ -48,6 +48,7 @@
             }
         });
 
+        nextButton.setRaised(false);
         nextButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
index 31b8e65..3f9a590 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
@@ -11,7 +11,6 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.TextView;
 
@@ -22,6 +21,7 @@
 import org.chromium.ui.text.NoUnderlineClickableSpan;
 import org.chromium.ui.text.SpanApplier;
 import org.chromium.ui.text.SpanApplier.SpanInfo;
+import org.chromium.ui.widget.ButtonCompat;
 
 /**
  * The First Run Experience fragment that allows the user to accept Terms of Service ("ToS") and
@@ -29,7 +29,7 @@
  * User Metrics Analysis) as defined in the Chrome Privacy Notice.
  */
 public class ToSAndUMAFirstRunFragment extends FirstRunPage {
-    private Button mAcceptButton;
+    private ButtonCompat mAcceptButton;
     private CheckBox mSendReportCheckBox;
     private TextView mTosAndPrivacy;
 
@@ -43,10 +43,11 @@
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
 
-        mAcceptButton = (Button) view.findViewById(R.id.terms_accept);
+        mAcceptButton = (ButtonCompat) view.findViewById(R.id.terms_accept);
         mSendReportCheckBox = (CheckBox) view.findViewById(R.id.send_report_checkbox);
         mTosAndPrivacy = (TextView) view.findViewById(R.id.tos_and_privacy);
 
+        mAcceptButton.setRaised(false);
         mAcceptButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
index d7fda1d5..6991058 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -23,7 +23,6 @@
 import org.chromium.base.BaseSwitches;
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContentUriUtils;
-import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.PathUtils;
 import org.chromium.base.ResourceExtractor;
@@ -185,8 +184,6 @@
         ThreadUtils.assertOnUiThread();
         if (mPreInflationStartupComplete) return;
 
-        ContextUtils.initApplicationContext(mApplication);
-
         // Ensure critical files are available, so they aren't blocked on the file-system
         // behind long-running accesses in next phase.
         // Don't do any large file access here!
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java
index 3c153aff..6ec79eb7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaUtils.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.metrics;
 
+import android.os.SystemClock;
+
 import org.chromium.base.annotations.CalledByNative;
 
 /**
@@ -24,7 +26,7 @@
         // isn't initialized until we start the native content browser component, and we
         // then need the start time in the C++ side before we return to Java. As such we
         // save it in a static that the C++ can fetch once it has initialized the JNI.
-        sApplicationStartWallClockMs = System.currentTimeMillis();
+        sApplicationStartWallClockMs = SystemClock.uptimeMillis();
     }
 
     /**
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 1c6c0fe..f5b4dd1 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
@@ -831,11 +831,7 @@
 
     @Override
     public void onUrlPreFocusChanged(boolean gainFocus) {
-        if (mToolbarDataProvider == null || mToolbarDataProvider.getTab() == null) return;
-
-        if (!mQueryInTheOmnibox && !TextUtils.isEmpty(mUrlBar.getText())) {
-            mUrlBar.setUrl(getOnlineUrlFromTab(), null);
-        }
+      // TODO(mariakhomenko): remove from the interface entirely as it's unused
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java
index 19ee688c..baed3e8c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java
@@ -48,6 +48,7 @@
     private final int mTitleLinkEnd;
     private final String mOrigin;
     private ArrayAdapter<Credential> mAdapter;
+    private boolean mIsDestroyed;
 
     /**
      * Holds the reference to the credentials which were chosen by the user.
@@ -194,6 +195,7 @@
 
     @CalledByNative
     private void imageFetchComplete(int index, Bitmap avatarBitmap) {
+        if (mIsDestroyed) return;
         assert index >= 0 && index < mCredentials.length;
         assert mCredentials[index] != null;
         avatarBitmap = AccountManagementFragment.makeRoundUserPicture(avatarBitmap);
@@ -210,6 +212,8 @@
 
     private void destroy() {
         assert mNativeAccountChooserDialog != 0;
+        assert !mIsDestroyed;
+        mIsDestroyed = true;
         nativeDestroy(mNativeAccountChooserDialog);
         mNativeAccountChooserDialog = 0;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
index 27347ea9..76e000e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -20,6 +20,7 @@
 import org.chromium.chrome.browser.payments.ui.PaymentRequestUI;
 import org.chromium.chrome.browser.payments.ui.SectionInformation;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.util.UrlUtilities;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.mojo.system.MojoException;
@@ -93,7 +94,8 @@
         if (mContext == null) return;
 
         mMerchantName = webContents.getTitle();
-        mOrigin = webContents.getVisibleUrl();
+        // The feature is available only in secure context, so it's OK to not show HTTPS.
+        mOrigin = UrlUtilities.formatUrlForSecurityDisplay(webContents.getVisibleUrl(), false);
 
         final FaviconHelper faviconHelper = new FaviconHelper();
         float scale = mContext.getResources().getDisplayMetrics().density;
@@ -187,9 +189,10 @@
 
         if (addresses.isEmpty()) {
             mShippingAddresses = new SectionInformation();
-        } else {
+        } else if (mShippingOptions.getSelectedItem() != null) {
             mShippingAddresses = new SectionInformation(0, addresses);
-            onShippingAddressChanged(addresses.get(0));
+        } else {
+            mShippingAddresses = new SectionInformation(SectionInformation.NO_SELECTION, addresses);
         }
 
         mPendingApps = new ArrayList<>(mApps);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
index 1903d9b..c2ee877 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -16,6 +16,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.WindowManager;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.RadioButton;
@@ -231,6 +232,8 @@
         dialogWindow.setGravity(Gravity.BOTTOM);
         dialogWindow.setLayout(
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        dialogWindow.setDimAmount(0.5f);
+        dialogWindow.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         mDialog.show();
 
         mClient.getDefaultPaymentInformation(new Callback<PaymentInformation>() {
@@ -240,18 +243,27 @@
 
                 if (mRequestShipping) {
                     mShippingAddressesSection = result.getShippingAddresses();
-                    String selectedAddressLabel = result.getSelectedShippingAddressLabel();
-                    if (selectedAddressLabel != null) {
-                        mShippingSummaryAddress.setText(selectedAddressLabel);
-                    }
-
                     mShippingOptionsSection = result.getShippingOptions();
+
+                    String selectedAddressLabel = result.getSelectedShippingAddressLabel();
                     String selectedShippingOptionLabel = result.getSelectedShippingOptionLabel();
-                    if (selectedShippingOptionLabel != null) {
-                        mShippingSummaryOption.setText(selectedShippingOptionLabel);
+                    if (selectedAddressLabel == null && selectedShippingOptionLabel == null) {
+                        mShippingSummaryAddress.setText(mContext.getString(
+                                R.string.payments_select_shipping_prompt));
                     } else {
-                        mShippingSummaryOption.setText(mContext.getString(
-                                R.string.payments_select_shipping_option_prompt));
+                        if (selectedAddressLabel == null) {
+                            mShippingSummaryAddress.setText(mContext.getString(
+                                    R.string.payments_select_shipping_address_prompt));
+                        } else {
+                            mShippingSummaryAddress.setText(selectedAddressLabel);
+                        }
+
+                        if (selectedShippingOptionLabel == null) {
+                            mShippingSummaryOption.setText(mContext.getString(
+                                    R.string.payments_select_shipping_option_prompt));
+                        } else {
+                            mShippingSummaryOption.setText(selectedShippingOptionLabel);
+                        }
                     }
                 }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java b/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java
index 17646b2..ab35ea7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java
@@ -23,13 +23,15 @@
         AUTOFILL_SELECTED
     }
 
+
     /**
      * Make it non-obvious to accidentally instantiate this outside of ChromeApplication.
      */
     protected PolicyAuditor() {}
 
-    public void notifyAuditEvent(final Context context, final AuditEvent event, final String url,
-            final String message) {}
+    public void notifyAuditEvent(Context context, AuditEvent event, String url, String message) {}
 
-    public void notifyCertificateFailure(final WebContents webContents, final Context context) {}
-}
+    public void notifyCertificateFailure(int certificateFailure, Context context) {}
+
+    public static native int nativeGetCertificateFailure(WebContents webContents);
+}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
index 8b5c902..bca8e50 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
@@ -248,11 +248,11 @@
         }
 
         mSigninChooseView.updateAccounts(mAccountNames, accountToSelect, mProfileData);
-        if (!mAccountNames.isEmpty()) {
-            setUpSigninButton(true);
-        } else {
+        if (mAccountNames.isEmpty()) {
             setUpSigninButton(false);
+            return false;
         }
+        setUpSigninButton(true);
 
         mProfileData.update();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java
index 65cb6e9d..5c128492 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java
@@ -29,10 +29,9 @@
  */
 public class SigninAndSyncView extends FrameLayout
         implements AndroidSyncSettingsObserver, SignInStateObserver {
-    private static final String TAG = "SigninAndSyncView";
     private final Listener mListener;
-    private final int mAccessPoint;
-    @AccessPoint private final SigninManager mSigninManager;
+    @AccessPoint private final int mAccessPoint;
+    private final SigninManager mSigninManager;
 
     private final TextView mTitle;
     private final TextView mDescription;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 21171d3..489b44a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -554,7 +554,9 @@
         public void onSSLStateUpdated(Tab tab) {
             PolicyAuditor auditor =
                     ((ChromeApplication) getApplicationContext()).getPolicyAuditor();
-            auditor.notifyCertificateFailure(getWebContents(), getApplicationContext());
+            auditor.notifyCertificateFailure(
+                    PolicyAuditor.nativeGetCertificateFailure(getWebContents()),
+                    getApplicationContext());
             updateFullscreenEnabledState();
         }
 
@@ -1438,7 +1440,7 @@
         if (intent == null) intent = new Intent();
         intent.setPackage(activity.getPackageName());
         intent.setAction(Intent.ACTION_VIEW);
-        intent.setData(Uri.parse(getUrl()));
+        if (TextUtils.isEmpty(intent.getDataString())) intent.setData(Uri.parse(getUrl()));
         intent.putExtra(IntentHandler.EXTRA_TAB_ID, mId);
         if (isIncognito()) {
             intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
index c8c5eef..f5463a040 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -6,6 +6,7 @@
 
 import android.content.Context;
 import android.graphics.Color;
+import android.os.SystemClock;
 import android.support.annotation.IntDef;
 import android.view.View;
 
@@ -213,7 +214,7 @@
             //   s^b = 60000
             //   b = ln(60000) / ln(1.05) ~= 225
             RecordHistogram.recordCustomTimesHistogram("Startup.FirstCommitNavigationTime",
-                    System.currentTimeMillis() - UmaUtils.getMainEntryPointTime(),
+                    SystemClock.uptimeMillis() - UmaUtils.getMainEntryPointTime(),
                     1, 60000 /* 1 minute */, TimeUnit.MILLISECONDS, 225);
             UmaUtils.setRunningApplicationStart(false);
         }
@@ -303,7 +304,9 @@
 
         PolicyAuditor auditor =
                 ((ChromeApplication) mTab.getApplicationContext()).getPolicyAuditor();
-        auditor.notifyCertificateFailure(mTab.getWebContents(), mTab.getApplicationContext());
+        auditor.notifyCertificateFailure(
+                PolicyAuditor.nativeGetCertificateFailure(mTab.getWebContents()),
+                mTab.getApplicationContext());
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
index 906039d..c5f81d5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -1346,6 +1346,11 @@
         enterAnimation.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
+                // The Android framework calls onAnimationEnd() on listeners before
+                // Animator#isRunning() returns false (see crbug.com/606419). In order for
+                // ToolbarPhone#isTabSwitcherAnimationRunning() to return the correct value,
+                // set mTabSwitcherModeAnimation = null here.
+                mTabSwitcherModeAnimation = null;
                 // This is to deal with the view going invisible when resuming the activity and
                 // running this animation.  The view is still there and clickable but does not
                 // render and only a layout triggers a refresh.  See crbug.com/306890.
@@ -1367,6 +1372,11 @@
         exitAnimation.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
+                // The Android framework calls onAnimationEnd() on listeners before
+                // Animator#isRunning() returns false (see crbug.com/606419). In order for
+                // ToolbarPhone#isTabSwitcherAnimationRunning() to return the correct value,
+                // set mTabSwitcherModeAnimation = null here.
+                mTabSwitcherModeAnimation = null;
                 updateViewsForTabSwitcherMode(mIsInTabSwitcherMode);
             }
         });
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 0e08bc2..3432c06 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1716,7 +1716,7 @@
         Continue
       </message>
       <message name="IDS_SIGNIN_ACCOUNT_CHOICE_DESCRIPTION" desc="Text for account chooser page">
-        Sign in to get your bookmarks, history, passwords, and other settings on all your devices.
+        Sign in with your Google Account to get your bookmarks, history, passwords, and other settings on all your devices.
       </message>
       <message name="IDS_SIGNIN_ACCEPT" desc="Text for button to accept being signed in">
         OK, got it
@@ -2345,9 +2345,15 @@
       <message name="IDS_PAYMENTS_SHIPPING_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be shipped.">
         Shipping option
       </message>
+      <message name="IDS_PAYMENTS_SELECT_SHIPPING_PROMPT" desc="The label for the button that presents the user with the list of possible shipping addresses and options.">
+        Select shipping
+      </message>
       <message name="IDS_PAYMENTS_SELECT_SHIPPING_OPTION_PROMPT" desc="The label for the button that presents the user with the list of possible shipping options.">
         Select shipping option
       </message>
+      <message name="IDS_PAYMENTS_SELECT_SHIPPING_ADDRESS_PROMPT" desc="The label for the button that presents the user with the list of possible shipping addresses.">
+        Select shipping address
+      </message>
       <message name="IDS_PAYMENTS_ORDER_SUMMARY_LABEL" desc="The title of the section that shows the summary of the order, including names and prices of individual line items, i.e. the bill.">
         Order summary
       </message>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 2b230931..c955dbb 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1198,6 +1198,7 @@
   "junit/src/org/chromium/chrome/browser/SSLClientCertificateRequestTest.java",
   "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java",
   "junit/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionControllerTest.java",
+  "junit/src/org/chromium/chrome/browser/cookies/CanonicalCookieTest.java",
   "junit/src/org/chromium/chrome/browser/crash/LogcatExtractionCallableTest.java",
   "junit/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtilsTest.java",
   "junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/cookies/CanonicalCookieTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/cookies/CanonicalCookieTest.java
new file mode 100644
index 0000000..9c1c3143
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/cookies/CanonicalCookieTest.java
@@ -0,0 +1,99 @@
+// 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.cookies;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit test serialization code.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public class CanonicalCookieTest {
+    // Name meant to match CanonicalCookie method.
+    private static byte[] saveListToStream(final List<CanonicalCookie> cookies)
+            throws Exception {
+        ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
+        DataOutputStream out = new DataOutputStream(outByteStream);
+        try {
+            CanonicalCookie cookiesArray[] = new CanonicalCookie[cookies.size()];
+            cookies.toArray(cookiesArray);
+            CanonicalCookie.saveListToStream(out, cookiesArray);
+        } finally {
+            out.close();
+            outByteStream.close();
+        }
+        return outByteStream.toByteArray();
+    }
+
+    // Name meant to match CanonicalCookie method.
+    private static List<CanonicalCookie> readListFromStream(final byte[] byteArray)
+            throws Exception {
+        ByteArrayInputStream inByteStream = new ByteArrayInputStream(byteArray);
+        DataInputStream in = new DataInputStream(inByteStream);
+        try {
+            return CanonicalCookie.readListFromStream(in);
+        } finally {
+            in.close();
+            inByteStream.close();
+        }
+    }
+
+    private static void assertCookiesEqual(CanonicalCookie lhs, CanonicalCookie rhs) {
+        Assert.assertEquals(lhs.getUrl(), rhs.getUrl());
+        Assert.assertEquals(lhs.getName(), rhs.getName());
+        Assert.assertEquals(lhs.getValue(), rhs.getValue());
+        Assert.assertEquals(lhs.getDomain(), rhs.getDomain());
+        Assert.assertEquals(lhs.getPath(), rhs.getPath());
+        Assert.assertEquals(lhs.getCreationDate(), rhs.getCreationDate());
+        Assert.assertEquals(lhs.getExpirationDate(), rhs.getExpirationDate());
+        Assert.assertEquals(lhs.getLastAccessDate(), rhs.getLastAccessDate());
+        Assert.assertEquals(lhs.isSecure(), rhs.isSecure());
+        Assert.assertEquals(lhs.isHttpOnly(), rhs.isHttpOnly());
+        Assert.assertEquals(lhs.getSameSite(), rhs.getSameSite());
+        Assert.assertEquals(lhs.getPriority(), rhs.getPriority());
+    }
+
+    private static void doSaveRestoreCookiesListTest(final List<CanonicalCookie> cookies)
+            throws Exception {
+        byte[] byteArray = saveListToStream(cookies);
+        List<CanonicalCookie> readCookies = readListFromStream(byteArray);
+
+        Assert.assertEquals(cookies.size(), readCookies.size());
+        for (int i = 0; i < cookies.size(); ++i) {
+            assertCookiesEqual(cookies.get(i), readCookies.get(i));
+        }
+    }
+
+    @Test
+    public void testSaveRestoreEmptyList() throws Exception {
+        doSaveRestoreCookiesListTest(new ArrayList<CanonicalCookie>());
+    }
+
+    @Test
+    public void testSaveRestore() throws Exception {
+        ArrayList<CanonicalCookie> cookies = new ArrayList<>();
+        cookies.add(new CanonicalCookie("http://url", "name", "value", "domain", "path",
+                0 /* creation */, 1 /* expiration */, 0 /* lastAccess */, false /* secure */,
+                true /* httpOnly */, 0 /* sameSite */, 0 /* priority */));
+        cookies.add(new CanonicalCookie("http://url2", "name2", "value2", "domain2", "path2",
+                10 /* creation */, 20 /* expiration */, 15 /* lastAccess */, true /* secure */,
+                false /* httpOnly */, 1 /* sameSite */, 1 /* priority */));
+        cookies.add(new CanonicalCookie("http://url3", "name3", "value3", "domain3", "path3",
+                10 /* creation */, 20 /* expiration */, 15 /* lastAccess */, true /* secure */,
+                false /* httpOnly */, 2 /* sameSite */, 2 /* priority */));
+
+        doSaveRestoreCookiesListTest(cookies);
+    }
+}
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index ce6210a0..8ea00c77 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -5,6 +5,7 @@
 #include "chrome/app/chrome_main_delegate.h"
 
 #include <stddef.h>
+#include <string>
 
 #include "base/base_paths.h"
 #include "base/command_line.h"
@@ -110,7 +111,7 @@
 #if defined(USE_X11)
 #include <stdlib.h>
 #include <string.h>
-#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util.h"  // nogncheck
 #endif
 
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
diff --git a/chrome/app/mojo/chrome_manifest.json b/chrome/app/mojo/chrome_manifest.json
index 2b4611e..cd488366 100644
--- a/chrome/app/mojo/chrome_manifest.json
+++ b/chrome/app/mojo/chrome_manifest.json
@@ -2,5 +2,9 @@
   "manifest_version": 1,
   "name": "exe:chrome",
   "display_name": "Chrome",
-  "capabilities": {}
+  "capabilities": {
+    "provided": {
+      "mash:launchable": [ "mash::mojom::Launchable" ]
+    }
+  }
 }
diff --git a/chrome/app/nibs/BUILD.gn b/chrome/app/nibs/BUILD.gn
new file mode 100644
index 0000000..5742872
--- /dev/null
+++ b/chrome/app/nibs/BUILD.gn
@@ -0,0 +1,55 @@
+# 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("//build/config/mac/rules.gni")
+
+# GYP version: chrome/chrome_nibs.gypi
+mac_xib_bundle_data("chrome_xibs") {
+  sources = [
+    "AppMenu.xib",
+    "AvatarMenuItem.xib",
+    "BookmarkAllTabs.xib",
+    "BookmarkBar.xib",
+    "BookmarkBarFolderWindow.xib",
+    "BookmarkBubble.xib",
+    "BookmarkEditor.xib",
+    "BookmarkNameFolder.xib",
+    "CollectedCookies.xib",
+    "ContentBlockedCookies.xib",
+    "ContentBlockedDownloads.xib",
+    "ContentBlockedGeolocation.xib",
+    "ContentBlockedMIDISysEx.xib",
+    "ContentBlockedMedia.xib",
+    "ContentBlockedMixedScript.xib",
+    "ContentBlockedPlugins.xib",
+    "ContentBlockedPopups.xib",
+    "ContentBlockedSimple.xib",
+    "ContentProtocolHandlers.xib",
+    "CookieDetailsView.xib",
+    "DevicePermissionsPrompt.xib",
+    "DownloadItem.xib",
+    "DownloadShelf.xib",
+    "EditSearchEngine.xib",
+    "ExclusiveAccessBubble.xib",
+    "ExtensionInstallPrompt.xib",
+    "ExtensionInstallPromptNoWarnings.xib",
+    "ExtensionInstallPromptWebstoreData.xib",
+    "ExtensionInstalledBubble.xib",
+    "FindBar.xib",
+    "FirstRunBubble.xib",
+    "FirstRunDialog.xib",
+    "GlobalErrorBubble.xib",
+    "HttpAuthLoginSheet.xib",
+    "HungRendererDialog.xib",
+    "ImportProgressDialog.xib",
+    "InfoBar.xib",
+    "MainMenu.xib",
+    "OneClickSigninBubble.xib",
+    "OneClickSigninDialog.xib",
+    "Panel.xib",
+    "SaveAccessoryView.xib",
+    "TaskManager.xib",
+    "Toolbar.xib",
+  ]
+}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 91cc214..92157b9 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -149,6 +149,7 @@
     "//components/navigation_metrics",
     "//components/network_time",
     "//components/ntp_snippets",
+    "//components/ntp_tiles",
     "//components/offline_pages",
     "//components/omnibox/browser",
     "//components/os_crypt",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 7280898..30b44c6 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -43,6 +43,7 @@
 #include "components/flags_ui/flags_storage.h"
 #include "components/flags_ui/flags_ui_switches.h"
 #include "components/nacl/common/nacl_switches.h"
+#include "components/ntp_tiles/switches.h"
 #include "components/offline_pages/offline_page_feature.h"
 #include "components/omnibox/browser/omnibox_switches.h"
 #include "components/password_manager/core/common/password_manager_features.h"
@@ -1593,8 +1594,8 @@
 #if defined(OS_ANDROID)
     {"enable-ntp-popular-sites", IDS_FLAGS_NTP_POPULAR_SITES_NAME,
      IDS_FLAGS_NTP_POPULAR_SITES_DESCRIPTION, kOsAndroid,
-     ENABLE_DISABLE_VALUE_TYPE(switches::kEnableNTPPopularSites,
-                               switches::kDisableNTPPopularSites)},
+     ENABLE_DISABLE_VALUE_TYPE(ntp_tiles::switches::kEnableNTPPopularSites,
+                               ntp_tiles::switches::kDisableNTPPopularSites)},
     {"ntp-switch-to-existing-tab", IDS_FLAGS_NTP_SWITCH_TO_EXISTING_TAB_NAME,
      IDS_FLAGS_NTP_SWITCH_TO_EXISTING_TAB_DESCRIPTION, kOsAndroid,
      MULTI_VALUE_TYPE(kNtpSwitchToExistingTabChoices)},
diff --git a/chrome/browser/android/banners/app_banner_data_fetcher_android.cc b/chrome/browser/android/banners/app_banner_data_fetcher_android.cc
index 46be568..b8dd12d 100644
--- a/chrome/browser/android/banners/app_banner_data_fetcher_android.cc
+++ b/chrome/browser/android/banners/app_banner_data_fetcher_android.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/manifest/manifest_icon_selector.h"
 #include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h"
 #include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/screen.h"
 
 namespace banners {
 
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index 63d81e7..d1f8edf 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -68,6 +68,7 @@
 #include "chrome/browser/android/omnibox/autocomplete_controller_android.h"
 #include "chrome/browser/android/omnibox/omnibox_prerender.h"
 #include "chrome/browser/android/password_ui_view_android.h"
+#include "chrome/browser/android/policy/policy_auditor.h"
 #include "chrome/browser/android/precache/precache_launcher.h"
 #include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h"
 #include "chrome/browser/android/preferences/pref_service_bridge.h"
@@ -334,6 +335,7 @@
      PermissionUpdateInfoBarDelegate::RegisterPermissionUpdateInfoBarDelegate},
     {"PersonalDataManagerAndroid",
      autofill::PersonalDataManagerAndroid::Register},
+    {"PolicyAuditor", RegisterPolicyAuditor},
     {"PrecacheLauncher", RegisterPrecacheLauncher},
     {"PrefServiceBridge", PrefServiceBridge::RegisterPrefServiceBridge},
     {"ProfileAndroid", ProfileAndroid::RegisterProfileAndroid},
diff --git a/chrome/browser/android/compositor/layer/tab_layer_unittest.cc b/chrome/browser/android/compositor/layer/tab_layer_unittest.cc
index 0b525b38..b40448d 100644
--- a/chrome/browser/android/compositor/layer/tab_layer_unittest.cc
+++ b/chrome/browser/android/compositor/layer/tab_layer_unittest.cc
@@ -10,9 +10,6 @@
 
 using chrome::android::TabLayer;
 
-// A test class for TabLayer class.
-class TabLayerTest : public testing::Test {};
-
 TEST(ComputePaddingPositionsTest, NoSideOrBottomPadding) {
   gfx::Size content_size(100, 400);
   gfx::Size desired_size(100, 400);
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc
index c0eb607..8a8e6832 100644
--- a/chrome/browser/android/compositor/tab_content_manager.cc
+++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -29,10 +29,8 @@
 #include "jni/TabContentManager_jni.h"
 #include "ui/android/resources/ui_resource_provider.h"
 #include "ui/gfx/android/java_bitmap.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/dip_util.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
 #include "url/gurl.h"
 
 namespace {
diff --git a/chrome/browser/android/cookies/cookies_fetcher.cc b/chrome/browser/android/cookies/cookies_fetcher.cc
index b2054916..9ed9472 100644
--- a/chrome/browser/android/cookies/cookies_fetcher.cc
+++ b/chrome/browser/android/cookies/cookies_fetcher.cc
@@ -134,7 +134,7 @@
                            jlong last_access,
                            jboolean secure,
                            jboolean httponly,
-                           jboolean same_site,
+                           jint same_site,
                            jint priority) {
   Profile* profile = ProfileManager::GetPrimaryUserProfile();
   if (!profile->HasOffTheRecordProfile()) {
@@ -154,8 +154,7 @@
       base::Time::FromInternalValue(creation),
       base::Time::FromInternalValue(expiration),
       base::Time::FromInternalValue(last_access), secure, httponly,
-      same_site ? net::CookieSameSite::LAX_MODE
-                : net::CookieSameSite::NO_RESTRICTION,
+      static_cast<net::CookieSameSite>(same_site),
       static_cast<net::CookiePriority>(priority));
 
   // The rest must be done from the IO thread.
diff --git a/chrome/browser/android/feedback/screenshot_task.cc b/chrome/browser/android/feedback/screenshot_task.cc
index 824969c0..a8e75be 100644
--- a/chrome/browser/android/feedback/screenshot_task.cc
+++ b/chrome/browser/android/feedback/screenshot_task.cc
@@ -13,9 +13,7 @@
 #include "jni/ScreenshotTask_jni.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/android/window_android.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
 #include "ui/snapshot/snapshot.h"
 
 using base::android::AttachCurrentThread;
diff --git a/chrome/browser/android/net/external_estimate_provider_android.h b/chrome/browser/android/net/external_estimate_provider_android.h
index c74d39d..b99e82e 100644
--- a/chrome/browser/android/net/external_estimate_provider_android.h
+++ b/chrome/browser/android/net/external_estimate_provider_android.h
@@ -15,8 +15,8 @@
 #include "base/thread_task_runner_handle.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
-#include "net/base/external_estimate_provider.h"
 #include "net/base/network_change_notifier.h"
+#include "net/nqe/external_estimate_provider.h"
 
 namespace chrome {
 namespace android {
diff --git a/chrome/browser/android/net/external_estimate_provider_android_unittest.cc b/chrome/browser/android/net/external_estimate_provider_android_unittest.cc
index 1cb913b..1af0fe9f 100644
--- a/chrome/browser/android/net/external_estimate_provider_android_unittest.cc
+++ b/chrome/browser/android/net/external_estimate_provider_android_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/test/histogram_tester.h"
 #include "base/time/time.h"
 #include "content/public/test/test_browser_thread_bundle.h"
-#include "net/base/network_quality_estimator.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
diff --git a/chrome/browser/android/ntp/most_visited_sites.cc b/chrome/browser/android/ntp/most_visited_sites.cc
index 3f5e907..ac625b2a 100644
--- a/chrome/browser/android/ntp/most_visited_sites.cc
+++ b/chrome/browser/android/ntp/most_visited_sites.cc
@@ -24,9 +24,9 @@
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
 #include "chrome/browser/thumbnails/thumbnail_list_source.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
 #include "components/history/core/browser/top_sites.h"
+#include "components/ntp_tiles/pref_names.h"
+#include "components/ntp_tiles/switches.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/variations/variations_associated_data.h"
@@ -40,7 +40,6 @@
 using history::TopSites;
 using suggestions::ChromeSuggestion;
 using suggestions::SuggestionsProfile;
-using suggestions::SuggestionsService;
 using suggestions::SuggestionsServiceFactory;
 
 namespace {
@@ -106,9 +105,9 @@
   const std::string group_name =
       base::FieldTrialList::FindFullName(kPopularSitesFieldTrialName);
   base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
-  if (cmd_line->HasSwitch(switches::kDisableNTPPopularSites))
+  if (cmd_line->HasSwitch(ntp_tiles::switches::kDisableNTPPopularSites))
     return false;
-  if (cmd_line->HasSwitch(switches::kEnableNTPPopularSites))
+  if (cmd_line->HasSwitch(ntp_tiles::switches::kEnableNTPPopularSites))
     return true;
   return base::StartsWith(group_name, "Enabled",
                           base::CompareCase::INSENSITIVE_ASCII);
@@ -128,7 +127,7 @@
 // |num_tiles| tiles.
 bool NeedPopularSites(const PrefService* prefs, size_t num_tiles) {
   const base::ListValue* source_list =
-      prefs->GetList(prefs::kNTPSuggestionsIsPersonal);
+      prefs->GetList(ntp_tiles::prefs::kNTPSuggestionsIsPersonal);
   // If there aren't enough previous suggestions to fill the grid, we need
   // popular suggestions.
   if (source_list->GetSize() < num_tiles)
@@ -179,9 +178,12 @@
 MostVisitedSites::Suggestion::operator=(Suggestion&&) = default;
 
 MostVisitedSites::MostVisitedSites(Profile* profile)
-    : profile_(profile), observer_(nullptr), num_sites_(0),
+    : profile_(profile), top_sites_(TopSitesFactory::GetForProfile(profile)),
+      suggestions_service_(SuggestionsServiceFactory::GetForProfile(profile_)),
+      observer_(nullptr), num_sites_(0),
       received_most_visited_sites_(false), received_popular_sites_(false),
-      recorded_uma_(false), scoped_observer_(this), weak_ptr_factory_(this) {
+      recorded_uma_(false), scoped_observer_(this),
+      mv_source_(SUGGESTIONS_SERVICE), weak_ptr_factory_(this) {
   // Register the thumbnails debugging page.
   content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_));
 
@@ -198,6 +200,7 @@
 
 void MostVisitedSites::SetMostVisitedURLsObserver(
       MostVisitedSites::Observer* observer, int num_sites) {
+  DCHECK(observer);
   observer_ = observer;
   num_sites_ = num_sites;
 
@@ -216,40 +219,35 @@
     received_popular_sites_ = true;
   }
 
-  scoped_refptr<TopSites> top_sites = TopSitesFactory::GetForProfile(profile_);
-  if (top_sites) {
+  if (top_sites_) {
     // TopSites updates itself after a delay. To ensure up-to-date results,
     // force an update now.
-    top_sites->SyncWithHistory();
+    top_sites_->SyncWithHistory();
 
     // Register as TopSitesObserver so that we can update ourselves when the
     // TopSites changes.
-    scoped_observer_.Add(top_sites.get());
+    scoped_observer_.Add(top_sites_.get());
   }
 
-  SuggestionsService* suggestions_service =
-      SuggestionsServiceFactory::GetForProfile(profile_);
-  suggestions_subscription_ = suggestions_service->AddCallback(
+  suggestions_subscription_ = suggestions_service_->AddCallback(
       base::Bind(&MostVisitedSites::OnSuggestionsProfileAvailable,
                  base::Unretained(this)));
 
-  // Immediately get the current suggestions from the cache. If the cache is
-  // empty, this will fall back to TopSites.
-  OnSuggestionsProfileAvailable(
-      suggestions_service->GetSuggestionsDataFromCache());
+  // Immediately build the current suggestions, getting personal suggestions
+  // from the SuggestionsService's cache or, if that is empty, from TopSites.
+  BuildCurrentSuggestions();
   // Also start a request for fresh suggestions.
-  suggestions_service->FetchSuggestionsData();
+  suggestions_service_->FetchSuggestionsData();
 }
 
 void MostVisitedSites::GetURLThumbnail(
     const GURL& url,
     const ThumbnailCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  scoped_refptr<TopSites> top_sites(TopSitesFactory::GetForProfile(profile_));
 
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::DB, FROM_HERE,
-      base::Bind(&MaybeFetchLocalThumbnail, url, top_sites),
+      base::Bind(&MaybeFetchLocalThumbnail, url, top_sites_),
       base::Bind(&MostVisitedSites::OnLocalThumbnailFetched,
                  weak_ptr_factory_.GetWeakPtr(), url, callback));
 }
@@ -262,27 +260,24 @@
   if (!bitmap.get()) {
     // A thumbnail is not locally available for |url|. Make sure it is put in
     // the list to be fetched at the next visit to this site.
-    scoped_refptr<TopSites> top_sites(TopSitesFactory::GetForProfile(profile_));
-    if (top_sites)
-      top_sites->AddForcedURL(url, base::Time::Now());
+    if (top_sites_)
+      top_sites_->AddForcedURL(url, base::Time::Now());
     // Also fetch a remote thumbnail if possible. PopularSites or the
     // SuggestionsService can supply a thumbnail download URL.
-    SuggestionsService* suggestions_service =
-        SuggestionsServiceFactory::GetForProfile(profile_);
     if (popular_sites_) {
       const std::vector<PopularSites::Site>& sites = popular_sites_->sites();
       auto it = std::find_if(
           sites.begin(), sites.end(),
           [&url](const PopularSites::Site& site) { return site.url == url; });
       if (it != sites.end() && it->thumbnail_url.is_valid()) {
-        return suggestions_service->GetPageThumbnailWithURL(
+        return suggestions_service_->GetPageThumbnailWithURL(
             url, it->thumbnail_url,
             base::Bind(&MostVisitedSites::OnObtainedThumbnail,
                        weak_ptr_factory_.GetWeakPtr(), false, callback));
       }
     }
     if (mv_source_ == SUGGESTIONS_SERVICE) {
-      return suggestions_service->GetPageThumbnail(
+      return suggestions_service_->GetPageThumbnail(
           url, base::Bind(&MostVisitedSites::OnObtainedThumbnail,
                           weak_ptr_factory_.GetWeakPtr(), false, callback));
     }
@@ -302,22 +297,19 @@
 void MostVisitedSites::AddOrRemoveBlacklistedUrl(
     const GURL& url, bool add_url) {
   // Always blacklist in the local TopSites.
-  scoped_refptr<TopSites> top_sites = TopSitesFactory::GetForProfile(profile_);
-  if (top_sites) {
+  if (top_sites_) {
     if (add_url)
-      top_sites->AddBlacklistedURL(url);
+      top_sites_->AddBlacklistedURL(url);
     else
-      top_sites->RemoveBlacklistedURL(url);
+      top_sites_->RemoveBlacklistedURL(url);
   }
 
   // Only blacklist in the server-side suggestions service if it's active.
   if (mv_source_ == SUGGESTIONS_SERVICE) {
-    SuggestionsService* suggestions_service =
-        SuggestionsServiceFactory::GetForProfile(profile_);
     if (add_url)
-      suggestions_service->BlacklistURL(url);
+      suggestions_service_->BlacklistURL(url);
     else
-      suggestions_service->UndoBlacklistURL(url);
+      suggestions_service_->UndoBlacklistURL(url);
   }
 }
 
@@ -357,37 +349,28 @@
 }
 
 void MostVisitedSites::OnURLFilterChanged() {
-  QueryMostVisitedURLs();
+  BuildCurrentSuggestions();
 }
 
 // static
 void MostVisitedSites::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterListPref(prefs::kNTPSuggestionsURL);
-  registry->RegisterListPref(prefs::kNTPSuggestionsIsPersonal);
+  registry->RegisterListPref(ntp_tiles::prefs::kNTPSuggestionsURL);
+  registry->RegisterListPref(ntp_tiles::prefs::kNTPSuggestionsIsPersonal);
 }
 
-void MostVisitedSites::QueryMostVisitedURLs() {
-  SuggestionsService* suggestions_service =
-      SuggestionsServiceFactory::GetForProfile(profile_);
-  if (suggestions_service->FetchSuggestionsData()) {
-    // A suggestions network request is on its way. We'll be called back via
-    // OnSuggestionsProfileAvailable.
-    return;
-  }
-  // If no network request could be sent, try to get suggestions from the
-  // cache. If that also returns nothing, OnSuggestionsProfileAvailable will
-  // call InitiateTopSitesQuery.
+void MostVisitedSites::BuildCurrentSuggestions() {
+  // Get the current suggestions from cache. If the cache is empty, this will
+  // fall back to TopSites.
   OnSuggestionsProfileAvailable(
-      suggestions_service->GetSuggestionsDataFromCache());
+      suggestions_service_->GetSuggestionsDataFromCache());
 }
 
 void MostVisitedSites::InitiateTopSitesQuery() {
-  scoped_refptr<TopSites> top_sites = TopSitesFactory::GetForProfile(profile_);
-  if (!top_sites)
+  if (!top_sites_)
     return;
 
-  top_sites->GetMostVisitedURLs(
+  top_sites_->GetMostVisitedURLs(
       base::Bind(&MostVisitedSites::OnMostVisitedURLsAvailable,
                  weak_ptr_factory_.GetWeakPtr()),
       false);
@@ -442,7 +425,7 @@
 void MostVisitedSites::OnSuggestionsProfileAvailable(
     const SuggestionsProfile& suggestions_profile) {
   int num_tiles = suggestions_profile.suggestions_size();
-  // With no server suggestions, fall back to local Most Visited.
+  // With no server suggestions, fall back to local TopSites.
   if (num_tiles == 0) {
     InitiateTopSitesQuery();
     return;
@@ -496,11 +479,10 @@
   std::set<std::string> personal_hosts;
   for (const auto& suggestion : personal_suggestions)
     personal_hosts.insert(suggestion->url.host());
-  scoped_refptr<TopSites> top_sites(TopSitesFactory::GetForProfile(profile_));
 
   for (const auto& whitelist : supervised_user_service->whitelists()) {
     // Skip blacklisted sites.
-    if (top_sites && top_sites->IsBlacklisted(whitelist->entry_point()))
+    if (top_sites_ && top_sites_->IsBlacklisted(whitelist->entry_point()))
       continue;
 
     // Skip suggestions already present.
@@ -551,10 +533,9 @@
       hosts.insert(suggestion->url.host());
     for (const auto& suggestion : whitelist_suggestions)
       hosts.insert(suggestion->url.host());
-    scoped_refptr<TopSites> top_sites(TopSitesFactory::GetForProfile(profile_));
     for (const PopularSites::Site& popular_site : popular_sites_->sites()) {
       // Skip blacklisted sites.
-      if (top_sites && top_sites->IsBlacklisted(popular_site.url))
+      if (top_sites_ && top_sites_->IsBlacklisted(popular_site.url))
         continue;
       std::string host = popular_site.url.host();
       // Skip suggestions already present in personal or whitelists.
@@ -658,9 +639,10 @@
     std::vector<std::string>* old_sites_url,
     std::vector<bool>* old_sites_is_personal) const {
   const PrefService* prefs = profile_->GetPrefs();
-  const base::ListValue* url_list = prefs->GetList(prefs::kNTPSuggestionsURL);
+  const base::ListValue* url_list = prefs->GetList(
+      ntp_tiles::prefs::kNTPSuggestionsURL);
   const base::ListValue* source_list =
-      prefs->GetList(prefs::kNTPSuggestionsIsPersonal);
+      prefs->GetList(ntp_tiles::prefs::kNTPSuggestionsIsPersonal);
   DCHECK_EQ(url_list->GetSize(), source_list->GetSize());
   if (url_list->GetSize() < num_tiles)
     num_tiles = url_list->GetSize();
@@ -690,8 +672,8 @@
     source_list.AppendBoolean(suggestion.source != MostVisitedSites::POPULAR);
   }
   PrefService* prefs = profile_->GetPrefs();
-  prefs->Set(prefs::kNTPSuggestionsIsPersonal, source_list);
-  prefs->Set(prefs::kNTPSuggestionsURL, url_list);
+  prefs->Set(ntp_tiles::prefs::kNTPSuggestionsIsPersonal, source_list);
+  prefs->Set(ntp_tiles::prefs::kNTPSuggestionsURL, url_list);
 }
 
 // static
@@ -743,7 +725,7 @@
     size_t src = insert_positions[src_pos++];
     std::swap((*dst_suggestions)[i], (*src_suggestions)[src]);
   }
-  // Return destination postions filled so far which becomes the start_position
+  // Return destination positions filled so far which becomes the start_position
   // for future runs.
   return i;
 }
@@ -771,11 +753,12 @@
     return;
   }
 
-  if (!observer_)
-    return;
-
+  // Pass the popular sites to the observer. This will cause it to fetch any
+  // missing icons, but will *not* cause it to display the popular sites.
   observer_->OnPopularURLsAvailable(popular_sites_->sites());
-  QueryMostVisitedURLs();
+
+  // Re-build the suggestions list. Once done, this will notify the observer.
+  BuildCurrentSuggestions();
 }
 
 void MostVisitedSites::RecordImpressionUMAMetrics() {
diff --git a/chrome/browser/android/ntp/most_visited_sites.h b/chrome/browser/android/ntp/most_visited_sites.h
index 3939ee74..86b0927 100644
--- a/chrome/browser/android/ntp/most_visited_sites.h
+++ b/chrome/browser/android/ntp/most_visited_sites.h
@@ -89,9 +89,9 @@
 
   ~MostVisitedSites() override;
 
-  // Does not take ownership of |observer|, which must outlive this object.
-  void SetMostVisitedURLsObserver(
-      Observer* observer, int num_sites);
+  // Does not take ownership of |observer|, which must outlive this object and
+  // must not be null.
+  void SetMostVisitedURLsObserver(Observer* observer, int num_sites);
 
   using ThumbnailCallback = base::Callback<
       void(bool /* is_local_thumbnail */, const SkBitmap* /* bitmap */)>;
@@ -111,7 +111,7 @@
   // TODO(treib): use SuggestionsVector in internal functions. crbug.com/601734
   using SuggestionsPtrVector = std::vector<std::unique_ptr<Suggestion>>;
 
-  void QueryMostVisitedURLs();
+  void BuildCurrentSuggestions();
 
   // Initialize the query to Top Sites. Called if the SuggestionsService is not
   // enabled, or if it returns no data.
@@ -212,6 +212,9 @@
   // The profile whose most visited sites will be queried.
   Profile* profile_;
 
+  scoped_refptr<history::TopSites> top_sites_;
+  suggestions::SuggestionsService* suggestions_service_;
+
   Observer* observer_;
 
   // The maximum number of most visited sites to return.
diff --git a/chrome/browser/android/ntp/popular_sites.cc b/chrome/browser/android/ntp/popular_sites.cc
index 13ee926..a434991 100644
--- a/chrome/browser/android/ntp/popular_sites.cc
+++ b/chrome/browser/android/ntp/popular_sites.cc
@@ -19,8 +19,8 @@
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
 #include "components/google/core/browser/google_util.h"
+#include "components/ntp_tiles/switches.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/search_engines/search_engine_type.h"
@@ -51,7 +51,8 @@
   DCHECK(template_url_service);
 
   base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
-  if (!cmd_line->HasSwitch(switches::kEnableNTPSearchEngineCountryDetection))
+  if (!cmd_line->HasSwitch(
+          ntp_tiles::switches::kEnableNTPSearchEngineCountryDetection))
     return std::string();
 
   const TemplateURL* default_provider =
diff --git a/chrome/browser/android/policy/policy_auditor.cc b/chrome/browser/android/policy/policy_auditor.cc
new file mode 100644
index 0000000..5fe17d3d
--- /dev/null
+++ b/chrome/browser/android/policy/policy_auditor.cc
@@ -0,0 +1,71 @@
+// 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/android/policy/policy_auditor.h"
+
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/ssl_status.h"
+#include "jni/PolicyAuditor_jni.h"
+#include "net/cert/cert_status_flags.h"
+
+int GetCertificateFailure(JNIEnv* env,
+                          const JavaParamRef<jclass>& obj,
+                          const JavaParamRef<jobject>& java_web_contents) {
+  // This function is similar to
+  // ToolbarModelImpl::GetSecurityLevelForWebContents, but has a custom mapping
+  // for policy auditing
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.policy
+  // GENERATED_JAVA_PREFIX_TO_STRIP: CERTIFICATE_FAIL_
+  enum CertificateFailure {
+    NONE = 0,
+    CERTIFICATE_FAIL_UNSPECIFIED = 1,
+    CERTIFICATE_FAIL_UNTRUSTED = 2,
+    CERTIFICATE_FAIL_REVOKED = 3,
+    CERTIFICATE_FAIL_NOT_YET_VALID = 4,
+    CERTIFICATE_FAIL_EXPIRED = 5,
+    CERTIFICATE_FAIL_UNABLE_TO_CHECK_REVOCATION_STATUS = 6,
+  };
+
+  content::WebContents* web_contents =
+      content::WebContents::FromJavaWebContents(java_web_contents);
+  content::NavigationEntry* entry =
+      web_contents->GetController().GetVisibleEntry();
+  if (!entry)
+    return NONE;
+
+  const content::SSLStatus& ssl = entry->GetSSL();
+  switch (ssl.security_style) {
+    case content::SECURITY_STYLE_WARNING:
+    case content::SECURITY_STYLE_UNKNOWN:
+    case content::SECURITY_STYLE_UNAUTHENTICATED:
+      return NONE;
+
+    case content::SECURITY_STYLE_AUTHENTICATION_BROKEN:
+    case content::SECURITY_STYLE_AUTHENTICATED: {
+      if (net::IsCertStatusError(ssl.cert_status)) {
+        if (ssl.cert_status & net::CERT_STATUS_AUTHORITY_INVALID)
+          return CERTIFICATE_FAIL_UNTRUSTED;
+        if (ssl.cert_status & net::CERT_STATUS_REVOKED)
+          return CERTIFICATE_FAIL_REVOKED;
+        // No mapping for CERTIFICATE_FAIL_NOT_YET_VALID.
+        if (ssl.cert_status & net::CERT_STATUS_DATE_INVALID)
+          return CERTIFICATE_FAIL_EXPIRED;
+        if (ssl.cert_status & net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION)
+          return CERTIFICATE_FAIL_UNABLE_TO_CHECK_REVOCATION_STATUS;
+        return CERTIFICATE_FAIL_UNSPECIFIED;
+      }
+      if (ssl.content_status &
+             content::SSLStatus::DISPLAYED_INSECURE_CONTENT) {
+        return CERTIFICATE_FAIL_UNSPECIFIED;
+      }
+    }
+  }
+  return NONE;
+}
+
+bool RegisterPolicyAuditor(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
diff --git a/chrome/browser/android/policy/policy_auditor.h b/chrome/browser/android/policy/policy_auditor.h
new file mode 100644
index 0000000..1864d6b
--- /dev/null
+++ b/chrome/browser/android/policy/policy_auditor.h
@@ -0,0 +1,12 @@
+// 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_ANDROID_POLICY_POLICY_AUDITOR_H_
+#define CHROME_BROWSER_ANDROID_POLICY_POLICY_AUDITOR_H_
+
+#include <jni.h>
+
+bool RegisterPolicyAuditor(JNIEnv* env);
+
+#endif  // CHROME_BROWSER_ANDROID_POLICY_POLICY_AUDITOR_H_
diff --git a/chrome/browser/android/profiles/profile_downloader_android.cc b/chrome/browser/android/profiles/profile_downloader_android.cc
index 4dd48be..0a79c35 100644
--- a/chrome/browser/android/profiles/profile_downloader_android.cc
+++ b/chrome/browser/android/profiles/profile_downloader_android.cc
@@ -24,7 +24,6 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/screen.h"
 
 namespace {
 
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
index 7c8803f..4c41f27 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
@@ -27,9 +27,9 @@
 #include "content/public/common/frame_navigate_params.h"
 #include "content/public/common/manifest.h"
 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/favicon_size.h"
-#include "ui/gfx/screen.h"
 #include "url/gurl.h"
 
 using content::Manifest;
@@ -193,7 +193,7 @@
   // otherwise using the largest icon among all avaliable icons.
   int ideal_icon_size_in_px =
       ideal_icon_size_in_dp_ *
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
   int threshold_to_get_any_largest_icon = ideal_icon_size_in_px - 1;
   favicon_service->GetLargestRawFaviconForPageURL(
       shortcut_info_.url,
diff --git a/chrome/browser/banners/app_banner_data_fetcher.cc b/chrome/browser/banners/app_banner_data_fetcher.cc
index bd7667e..48589c01 100644
--- a/chrome/browser/banners/app_banner_data_fetcher.cc
+++ b/chrome/browser/banners/app_banner_data_fetcher.cc
@@ -29,7 +29,6 @@
 #include "net/base/load_flags.h"
 #include "third_party/WebKit/public/platform/WebDisplayMode.h"
 #include "third_party/WebKit/public/platform/modules/app_banner/WebAppBannerPromptReply.h"
-#include "ui/gfx/screen.h"
 
 namespace {
 
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc
index 6fe5b9c..d2b697f 100644
--- a/chrome/browser/banners/app_banner_manager.cc
+++ b/chrome/browser/banners/app_banner_manager.cc
@@ -13,7 +13,6 @@
 #include "content/public/common/frame_navigate_params.h"
 #include "content/public/common/origin_util.h"
 #include "net/base/load_flags.h"
-#include "ui/gfx/screen.h"
 
 namespace {
 bool gDisableSecureCheckForTesting = false;
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 821a5c1..309177a8 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -46,6 +46,7 @@
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/personal_data_manager_observer.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/test/bookmark_test_helpers.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -132,7 +133,6 @@
 const char kTestOriginDevTools[] = "chrome-devtools://abcdefghijklmnopqrstuvw/";
 
 // For Autofill.
-const char kChromeOrigin[] = "Chrome settings";
 const char kWebOrigin[] = "https://www.example.com/";
 
 const GURL kOrigin1(kTestOrigin1);
@@ -729,7 +729,7 @@
     profiles.push_back(profile);
 
     profile.set_guid(base::GenerateGUID());
-    profile.set_origin(kChromeOrigin);
+    profile.set_origin(autofill::kSettingsOrigin);
     profiles.push_back(profile);
 
     personal_data_manager_->SetProfiles(&profiles);
@@ -744,7 +744,7 @@
     cards.push_back(card);
 
     card.set_guid(base::GenerateGUID());
-    card.set_origin(kChromeOrigin);
+    card.set_origin(autofill::kSettingsOrigin);
     cards.push_back(card);
 
     personal_data_manager_->SetCreditCards(&cards);
@@ -2123,7 +2123,7 @@
   tester.AddProfilesAndCards();
   EXPECT_FALSE(tester.HasOrigin(std::string()));
   EXPECT_TRUE(tester.HasOrigin(kWebOrigin));
-  EXPECT_TRUE(tester.HasOrigin(kChromeOrigin));
+  EXPECT_TRUE(tester.HasOrigin(autofill::kSettingsOrigin));
 
   BlockUntilBrowsingDataRemoved(
       BrowsingDataRemover::LAST_HOUR,
@@ -2133,7 +2133,7 @@
   EXPECT_EQ(BrowsingDataHelper::UNPROTECTED_WEB, GetOriginTypeMask());
   EXPECT_TRUE(tester.HasOrigin(std::string()));
   EXPECT_FALSE(tester.HasOrigin(kWebOrigin));
-  EXPECT_TRUE(tester.HasOrigin(kChromeOrigin));
+  EXPECT_TRUE(tester.HasOrigin(autofill::kSettingsOrigin));
 }
 
 TEST_F(BrowsingDataRemoverTest, CompletionInhibition) {
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 1c084e8..fe29846 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -50,6 +50,7 @@
 #include "chrome/browser/chrome_browser_main_extra_parts.h"
 #include "chrome/browser/component_updater/cld_component_installer.h"
 #include "chrome/browser/component_updater/ev_whitelist_component_installer.h"
+#include "chrome/browser/component_updater/origin_trials_component_installer.h"
 #include "chrome/browser/component_updater/pepper_flash_component_installer.h"
 #include "chrome/browser/component_updater/recovery_component_installer.h"
 #include "chrome/browser/component_updater/sth_set_component_installer.h"
@@ -495,6 +496,7 @@
     // Chrome OS: On Chrome OS this registration is delayed until user login.
     RegisterSTHSetComponent(cus, path);
 #endif  // defined(OS_ANDROID)
+    RegisterOriginTrialsComponent(cus, path);
   }
 
 #if defined(OS_WIN)
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc
index a481b6a..b33f957 100644
--- a/chrome/browser/chrome_browser_main_android.cc
+++ b/chrome/browser/chrome_browser_main_android.cc
@@ -11,9 +11,9 @@
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/trace_event/trace_event.h"
-#include "chrome/browser/android/chrome_media_client_android.h"
 #include "chrome/browser/android/seccomp_support_detector.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/chrome_media_client_android.h"
 #include "chrome/common/chrome_paths.h"
 #include "components/crash/content/app/breakpad_linux.h"
 #include "components/crash/content/browser/crash_dump_manager_android.h"
diff --git a/chrome/browser/chromeos/accessibility/chromevox_panel.cc b/chrome/browser/chromeos/accessibility/chromevox_panel.cc
index 3ed98fc..5c956d4 100644
--- a/chrome/browser/chromeos/accessibility/chromevox_panel.cc
+++ b/chrome/browser/chromeos/accessibility/chromevox_panel.cc
@@ -15,6 +15,7 @@
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/view_type_utils.h"
 #include "ui/chromeos/accessibility_types.h"
+#include "ui/display/screen.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/widget/widget.h"
@@ -93,11 +94,11 @@
   widget_->Init(params);
   SetShadowType(widget_->GetNativeWindow(), wm::SHADOW_TYPE_RECTANGULAR);
 
-  gfx::Screen::GetScreen()->AddObserver(this);
+  display::Screen::GetScreen()->AddObserver(this);
 }
 
 ChromeVoxPanel::~ChromeVoxPanel() {
-  gfx::Screen::GetScreen()->RemoveObserver(this);
+  display::Screen::GetScreen()->RemoveObserver(this);
 }
 
 aura::Window* ChromeVoxPanel::GetRootWindow() {
@@ -163,7 +164,7 @@
   return web_view_;
 }
 
-void ChromeVoxPanel::OnDisplayMetricsChanged(const gfx::Display& display,
+void ChromeVoxPanel::OnDisplayMetricsChanged(const display::Display& display,
                                              uint32_t changed_metrics) {
   UpdateWidgetBounds();
 }
diff --git a/chrome/browser/chromeos/accessibility/chromevox_panel.h b/chrome/browser/chromeos/accessibility/chromevox_panel.h
index f05ecc9d..fb761f1 100644
--- a/chrome/browser/chromeos/accessibility/chromevox_panel.h
+++ b/chrome/browser/chromeos/accessibility/chromevox_panel.h
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "ui/gfx/display_observer.h"
+#include "ui/display/display_observer.h"
 #include "ui/views/widget/widget_delegate.h"
 
 class ChromeVoxPanelWebContentsObserver;
@@ -22,7 +22,7 @@
 }
 
 class ChromeVoxPanel : public views::WidgetDelegate,
-                       public gfx::DisplayObserver {
+                       public display::DisplayObserver {
  public:
   explicit ChromeVoxPanel(content::BrowserContext* browser_context);
   ~ChromeVoxPanel() override;
@@ -45,9 +45,9 @@
   views::View* GetContentsView() override;
 
   // DisplayObserver overrides;
-  void OnDisplayAdded(const gfx::Display& new_display) override {}
-  void OnDisplayRemoved(const gfx::Display& old_display) override {}
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  void OnDisplayAdded(const display::Display& new_display) override {}
+  void OnDisplayRemoved(const display::Display& old_display) override {}
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override;
 
  private:
diff --git a/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc b/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc
index ca93ce7..88afe74 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.cc
@@ -15,8 +15,8 @@
 #include "components/user_manager/user_manager.h"
 #include "extensions/browser/extension_system.h"
 #include "ui/base/user_activity/user_activity_detector.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 
 namespace chromeos {
 
@@ -76,7 +76,8 @@
 
 void KioskModeIdleAppNameNotification::OnUserActivity(const ui::Event* event) {
   if (show_notification_upon_next_user_activity_) {
-    gfx::Display display = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+    display::Display display =
+        display::Screen::GetScreen()->GetPrimaryDisplay();
     // Display the notification only on internal display.
     if (display.IsInternal()) {
       base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
diff --git a/chrome/browser/chromeos/arc/arc_auth_service.cc b/chrome/browser/chromeos/arc/arc_auth_service.cc
index ed8322b..574a71a 100644
--- a/chrome/browser/chromeos/arc/arc_auth_service.cc
+++ b/chrome/browser/chromeos/arc/arc_auth_service.cc
@@ -230,6 +230,12 @@
     return;
   }
 
+  if (user_manager::UserManager::Get()
+          ->IsCurrentUserCryptohomeDataEphemeral()) {
+    VLOG(2) << "Users with ephemeral data are not supported in Arc.";
+    return;
+  }
+
   profile_ = profile;
   PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver(
       prefs::kArcEnabled, this);
diff --git a/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc b/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc
index 5b9d661..ba66555a 100644
--- a/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc
@@ -15,11 +15,13 @@
 #include "chrome/browser/chromeos/arc/arc_auth_service.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
+#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/prefs/pref_service_syncable_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
+#include "chromeos/login/user_names.h"
 #include "components/arc/arc_bridge_service.h"
 #include "components/arc/test/fake_arc_bridge_service.h"
 #include "components/prefs/pref_service.h"
@@ -74,6 +76,8 @@
         AccountId::FromUserEmailGaiaId("user@gmail.com", "1234567890"));
     GetFakeUserManager()->AddUser(account_id);
     GetFakeUserManager()->LoginUser(account_id);
+
+    chromeos::WallpaperManager::Initialize();
   }
 
   void TearDown() override {}
@@ -128,6 +132,43 @@
   auth_service()->Shutdown();
 }
 
+TEST_F(ArcAuthServiceTest, DisabledForEphemeralDataUsers) {
+  PrefService* const prefs = profile()->GetPrefs();
+  EXPECT_FALSE(prefs->GetBoolean(prefs::kArcSignedIn));
+  prefs->SetBoolean(prefs::kArcEnabled, true);
+
+  chromeos::FakeChromeUserManager* const fake_user_manager =
+      GetFakeUserManager();
+
+  fake_user_manager->AddUser(fake_user_manager->GetGuestAccountId());
+  fake_user_manager->SwitchActiveUser(fake_user_manager->GetGuestAccountId());
+  auth_service()->OnPrimaryUserProfilePrepared(profile());
+  ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state());
+
+  fake_user_manager->AddUser(chromeos::login::DemoAccountId());
+  fake_user_manager->SwitchActiveUser(chromeos::login::DemoAccountId());
+  auth_service()->OnPrimaryUserProfilePrepared(profile());
+  ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state());
+
+  const AccountId public_account_id(
+      AccountId::FromUserEmail("public_user@gmail.com"));
+  fake_user_manager->AddPublicAccountUser(public_account_id);
+  fake_user_manager->SwitchActiveUser(public_account_id);
+  auth_service()->OnPrimaryUserProfilePrepared(profile());
+  ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state());
+
+  const AccountId not_in_list_account_id(
+      AccountId::FromUserEmail("not_in_list_user@gmail.com"));
+  fake_user_manager->AddUser(not_in_list_account_id);
+  fake_user_manager->SwitchActiveUser(not_in_list_account_id);
+  fake_user_manager->RemoveUserFromList(not_in_list_account_id);
+  auth_service()->OnPrimaryUserProfilePrepared(profile());
+  ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state());
+
+  // Correctly stop service.
+  auth_service()->Shutdown();
+}
+
 TEST_F(ArcAuthServiceTest, BaseWorkflow) {
   ASSERT_EQ(ArcBridgeService::State::STOPPED, bridge_service()->state());
   ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state());
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 798bcfd..43000fe 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -117,6 +117,8 @@
 #include "chromeos/network/portal_detector/network_portal_detector_stub.h"
 #include "chromeos/system/statistics_provider.h"
 #include "chromeos/tpm/tpm_token_loader.h"
+#include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service_manager.h"
 #include "components/browser_sync/common/browser_sync_switches.h"
 #include "components/device_event_log/device_event_log.h"
 #include "components/metrics/metrics_service.h"
@@ -688,6 +690,14 @@
   // available.
   idle_action_warning_observer_.reset(new IdleActionWarningObserver());
 
+  // Tell the window manager observer to monitor window manager changes. To do
+  // so, the ash::shell needs to be available (which it is now).
+  if (arc::ArcBridgeService::GetEnabled(
+          base::CommandLine::ForCurrentProcess())) {
+    DCHECK(arc::ArcServiceManager::Get());
+    arc::ArcServiceManager::Get()->OnAshStarted();
+  }
+
   ChromeBrowserMainPartsLinux::PostProfileInit();
 }
 
diff --git a/chrome/browser/chromeos/display/display_preferences.cc b/chrome/browser/chromeos/display/display_preferences.cc
index a3ab9efb..a05e3673 100644
--- a/chrome/browser/chromeos/display/display_preferences.cc
+++ b/chrome/browser/chromeos/display/display_preferences.cc
@@ -25,9 +25,8 @@
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/user_manager/user_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 #include "ui/gfx/geometry/insets.h"
-#include "ui/gfx/screen.h"
 #include "url/url_canon.h"
 #include "url/url_util.h"
 
@@ -150,18 +149,18 @@
     const base::DictionaryValue* dict_value = nullptr;
     if (!it.value().GetAsDictionary(&dict_value) || dict_value == nullptr)
       continue;
-    int64_t id = gfx::Display::kInvalidDisplayID;
+    int64_t id = display::Display::kInvalidDisplayID;
     if (!base::StringToInt64(it.key(), &id) ||
-        id == gfx::Display::kInvalidDisplayID) {
+        id == display::Display::kInvalidDisplayID) {
       continue;
     }
-    gfx::Display::Rotation rotation = gfx::Display::ROTATE_0;
+    display::Display::Rotation rotation = display::Display::ROTATE_0;
     float ui_scale = 1.0f;
     const gfx::Insets* insets_to_set = nullptr;
 
     int rotation_value = 0;
     if (dict_value->GetInteger("rotation", &rotation_value)) {
-      rotation = static_cast<gfx::Display::Rotation>(rotation_value);
+      rotation = static_cast<display::Display::Rotation>(rotation_value);
     }
     int ui_scale_value = 0;
     if (dict_value->GetInteger("ui-scale", &ui_scale_value))
@@ -204,12 +203,12 @@
   if (!properties->GetBoolean("lock", &rotation_lock))
     return;
 
-  int rotation = gfx::Display::ROTATE_0;
+  int rotation = display::Display::ROTATE_0;
   if (!properties->GetInteger("orientation", &rotation))
     return;
 
-  GetDisplayManager()->RegisterDisplayRotationProperties(rotation_lock,
-      static_cast<gfx::Display::Rotation>(rotation));
+  GetDisplayManager()->RegisterDisplayRotationProperties(
+      rotation_lock, static_cast<display::Display::Rotation>(rotation));
 }
 
 void StoreDisplayLayoutPref(const display::DisplayIdList& list,
@@ -251,7 +250,7 @@
 
   size_t num = display_manager->GetNumDisplays();
   for (size_t i = 0; i < num; ++i) {
-    const gfx::Display& display = display_manager->GetDisplayAt(i);
+    const display::Display& display = display_manager->GetDisplayAt(i);
     int64_t id = display.id();
     ash::DisplayInfo info = display_manager->GetDisplayInfo(id);
 
@@ -261,9 +260,9 @@
     // size and modes can change depending on the combination of displays.
     if (display_manager->IsInUnifiedMode())
       continue;
-    property_value->SetInteger(
-        "rotation",
-        static_cast<int>(info.GetRotation(gfx::Display::ROTATION_SOURCE_USER)));
+    property_value->SetInteger("rotation",
+                               static_cast<int>(info.GetRotation(
+                                   display::Display::ROTATION_SOURCE_USER)));
     property_value->SetInteger(
         "ui-scale", static_cast<int>(info.configured_ui_scale() * 1000));
 
@@ -360,17 +359,17 @@
 }
 
 void StoreDisplayRotationPrefs(bool rotation_lock) {
-  if (!gfx::Display::HasInternalDisplay())
+  if (!display::Display::HasInternalDisplay())
     return;
 
   PrefService* local_state = g_browser_process->local_state();
   DictionaryPrefUpdate update(local_state, prefs::kDisplayRotationLock);
   base::DictionaryValue* pref_data = update.Get();
   pref_data->SetBoolean("lock", rotation_lock);
-  gfx::Display::Rotation rotation =
+  display::Display::Rotation rotation =
       GetDisplayManager()
-          ->GetDisplayInfo(gfx::Display::InternalDisplayId())
-          .GetRotation(gfx::Display::ROTATION_SOURCE_ACCELEROMETER);
+          ->GetDisplayInfo(display::Display::InternalDisplayId())
+          .GetRotation(display::Display::ROTATION_SOURCE_ACCELEROMETER);
   pref_data->SetInteger("orientation", static_cast<int>(rotation));
 }
 
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc
index 60b22f6..c1cc550d 100644
--- a/chrome/browser/chromeos/display/display_preferences_unittest.cc
+++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -36,8 +36,8 @@
 #include "components/prefs/testing_pref_service.h"
 #include "ui/display/chromeos/display_configurator.h"
 #include "ui/display/manager/display_layout_builder.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/vector3d_f.h"
-#include "ui/gfx/screen.h"
 #include "ui/message_center/message_center.h"
 
 using ash::ResolutionNotificationController;
@@ -186,7 +186,7 @@
   }
 
   void StoreDisplayRotationPrefsForTest(bool rotation_lock,
-                                        gfx::Display::Rotation rotation) {
+                                        display::Display::Rotation rotation) {
     DictionaryPrefUpdate update(local_state(), prefs::kDisplayRotationLock);
     base::DictionaryValue* pref_data = update.Get();
     pref_data->SetBoolean("lock", rotation_lock);
@@ -262,7 +262,7 @@
       ash::Shell::GetInstance()->display_manager();
 
   UpdateDisplay("200x200*2, 400x300#400x400|300x200*1.25");
-  int64_t id1 = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   ash::test::ScopedSetInternalDisplayId set_internal(id1);
   int64_t id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
   int64_t dummy_id = id2 + 1;
@@ -296,11 +296,11 @@
 
   // Can't switch to a display that does not exist.
   window_tree_host_manager->SetPrimaryDisplayId(dummy_id);
-  EXPECT_NE(dummy_id, gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  EXPECT_NE(dummy_id, display::Screen::GetScreen()->GetPrimaryDisplay().id());
 
   window_tree_host_manager->SetOverscanInsets(id1, gfx::Insets(10, 11, 12, 13));
-  display_manager->SetDisplayRotation(id1, gfx::Display::ROTATE_90,
-                                      gfx::Display::ROTATION_SOURCE_USER);
+  display_manager->SetDisplayRotation(id1, display::Display::ROTATE_90,
+                                      display::Display::ROTATION_SOURCE_USER);
   EXPECT_TRUE(ash::SetDisplayUIScale(id1, 1.25f));
   EXPECT_FALSE(ash::SetDisplayUIScale(id2, 1.25f));
 
@@ -383,7 +383,7 @@
 
   window_tree_host_manager->SetPrimaryDisplayId(id2);
 
-  EXPECT_EQ(id2, gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  EXPECT_EQ(id2, display::Screen::GetScreen()->GetPrimaryDisplay().id());
 
   EXPECT_TRUE(properties->GetDictionary(base::Int64ToString(id1), &property));
   width = 0;
@@ -464,7 +464,7 @@
   EXPECT_EQ(200, height);
 
   // Set new display's selected resolution.
-  display_manager->RegisterDisplayProperty(id2 + 1, gfx::Display::ROTATE_0,
+  display_manager->RegisterDisplayProperty(id2 + 1, display::Display::ROTATE_0,
                                            1.0f, nullptr, gfx::Size(500, 400),
                                            1.0f, ui::COLOR_PROFILE_STANDARD);
 
@@ -490,7 +490,7 @@
   EXPECT_FALSE(property->GetInteger("height", &height));
 
   // Set yet another new display's selected resolution.
-  display_manager->RegisterDisplayProperty(id2 + 1, gfx::Display::ROTATE_0,
+  display_manager->RegisterDisplayProperty(id2 + 1, display::Display::ROTATE_0,
                                            1.0f, nullptr, gfx::Size(500, 400),
                                            1.0f, ui::COLOR_PROFILE_STANDARD);
   // Disconnect 2nd display first to generate new id for external display.
@@ -522,7 +522,7 @@
   ResolutionNotificationController::SuppressTimerForTest();
   LoggedInAsUser();
   UpdateDisplay("400x300#500x400|400x300|300x200");
-  int64_t id = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   // Set display's resolution in single display. It creates the notification and
   // display preferences should not stored meanwhile.
   ash::Shell* shell = ash::Shell::GetInstance();
@@ -568,7 +568,7 @@
 
 TEST_F(DisplayPreferencesTest, StoreForSwappedDisplay) {
   UpdateDisplay("100x100,200x200");
-  int64_t id1 = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   int64_t id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
 
   LoggedInAsUser();
@@ -637,7 +637,7 @@
   ash::DisplayManager* display_manager =
       ash::Shell::GetInstance()->display_manager();
 
-  int64_t id1 = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
 
   StoreColorProfile(id1, "dynamic");
 
@@ -669,7 +669,7 @@
   UpdateDisplay("200x200*2,200x200");
 
   LoggedInAsGuest();
-  int64_t id1 = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   ash::test::ScopedSetInternalDisplayId set_internal(id1);
   int64_t id2 = ash::ScreenUtil::GetSecondaryDisplay().id();
   ash::DisplayManager* display_manager =
@@ -678,11 +678,11 @@
       ash::test::CreateDisplayLayout(display::DisplayPlacement::TOP, 10));
   ash::SetDisplayUIScale(id1, 1.25f);
   window_tree_host_manager->SetPrimaryDisplayId(id2);
-  int64_t new_primary = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t new_primary = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   window_tree_host_manager->SetOverscanInsets(new_primary,
                                               gfx::Insets(10, 11, 12, 13));
-  display_manager->SetDisplayRotation(new_primary, gfx::Display::ROTATE_90,
-                                      gfx::Display::ROTATION_SOURCE_USER);
+  display_manager->SetDisplayRotation(new_primary, display::Display::ROTATE_90,
+                                      display::Display::ROTATION_SOURCE_USER);
 
   // Does not store the preferences locally.
   EXPECT_FALSE(local_state()->FindPreference(
@@ -691,22 +691,22 @@
       prefs::kDisplayProperties)->HasUserSetting());
 
   // Settings are still notified to the system.
-  gfx::Screen* screen = gfx::Screen::GetScreen();
+  display::Screen* screen = display::Screen::GetScreen();
   EXPECT_EQ(id2, screen->GetPrimaryDisplay().id());
   const display::DisplayPlacement& placement =
       display_manager->GetCurrentDisplayLayout().placement_list[0];
   EXPECT_EQ(display::DisplayPlacement::BOTTOM, placement.position);
   EXPECT_EQ(-10, placement.offset);
-  const gfx::Display& primary_display = screen->GetPrimaryDisplay();
+  const display::Display& primary_display = screen->GetPrimaryDisplay();
   EXPECT_EQ("178x176", primary_display.bounds().size().ToString());
-  EXPECT_EQ(gfx::Display::ROTATE_90, primary_display.rotation());
+  EXPECT_EQ(display::Display::ROTATE_90, primary_display.rotation());
 
   const ash::DisplayInfo& info1 = display_manager->GetDisplayInfo(id1);
   EXPECT_EQ(1.25f, info1.configured_ui_scale());
 
   const ash::DisplayInfo& info_primary =
       display_manager->GetDisplayInfo(new_primary);
-  EXPECT_EQ(gfx::Display::ROTATE_90, info_primary.GetActiveRotation());
+  EXPECT_EQ(display::Display::ROTATE_90, info_primary.GetActiveRotation());
   EXPECT_EQ(1.0f, info_primary.configured_ui_scale());
 }
 
@@ -770,18 +770,18 @@
 // are not saved.
 TEST_F(DisplayPreferencesTest, DontSaveMaximizeModeControllerRotations) {
   ash::Shell* shell = ash::Shell::GetInstance();
-  gfx::Display::SetInternalDisplayId(
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  display::Display::SetInternalDisplayId(
+      display::Screen::GetScreen()->GetPrimaryDisplay().id());
   ash::DisplayManager* display_manager = shell->display_manager();
   LoggedInAsUser();
   // Populate the properties.
-  display_manager->SetDisplayRotation(gfx::Display::InternalDisplayId(),
-                                      gfx::Display::ROTATE_180,
-                                      gfx::Display::ROTATION_SOURCE_USER);
+  display_manager->SetDisplayRotation(display::Display::InternalDisplayId(),
+                                      display::Display::ROTATE_180,
+                                      display::Display::ROTATION_SOURCE_USER);
   // Reset property to avoid rotation lock
-  display_manager->SetDisplayRotation(gfx::Display::InternalDisplayId(),
-                                      gfx::Display::ROTATE_0,
-                                      gfx::Display::ROTATION_SOURCE_USER);
+  display_manager->SetDisplayRotation(display::Display::InternalDisplayId(),
+                                      display::Display::ROTATE_0,
+                                      display::Display::ROTATION_SOURCE_USER);
 
   // Open up 270 degrees to trigger maximize mode
   scoped_refptr<chromeos::AccelerometerUpdate> update(
@@ -799,16 +799,16 @@
   update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, -kMeanGravity, 0.0f, 0.0f);
   controller->OnAccelerometerUpdated(update);
   shell->screen_orientation_controller()->OnAccelerometerUpdated(update);
-  EXPECT_EQ(gfx::Display::ROTATE_90, GetCurrentInternalDisplayRotation());
+  EXPECT_EQ(display::Display::ROTATE_90, GetCurrentInternalDisplayRotation());
 
   const base::DictionaryValue* properties =
       local_state()->GetDictionary(prefs::kDisplayProperties);
   const base::DictionaryValue* property = nullptr;
   EXPECT_TRUE(properties->GetDictionary(
-      base::Int64ToString(gfx::Display::InternalDisplayId()), &property));
+      base::Int64ToString(display::Display::InternalDisplayId()), &property));
   int rotation = -1;
   EXPECT_TRUE(property->GetInteger("rotation", &rotation));
-  EXPECT_EQ(gfx::Display::ROTATE_0, rotation);
+  EXPECT_EQ(display::Display::ROTATE_0, rotation);
 
   // Trigger a save, the acceleration rotation should not be saved as the user
   // rotation.
@@ -816,16 +816,16 @@
   properties = local_state()->GetDictionary(prefs::kDisplayProperties);
   property = nullptr;
   EXPECT_TRUE(properties->GetDictionary(
-      base::Int64ToString(gfx::Display::InternalDisplayId()), &property));
+      base::Int64ToString(display::Display::InternalDisplayId()), &property));
   rotation = -1;
   EXPECT_TRUE(property->GetInteger("rotation", &rotation));
-  EXPECT_EQ(gfx::Display::ROTATE_0, rotation);
+  EXPECT_EQ(display::Display::ROTATE_0, rotation);
 }
 
 // Tests that the rotation state is saved without a user being logged in.
 TEST_F(DisplayPreferencesTest, StoreRotationStateNoLogin) {
-  gfx::Display::SetInternalDisplayId(
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  display::Display::SetInternalDisplayId(
+      display::Screen::GetScreen()->GetPrimaryDisplay().id());
   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
 
   bool current_rotation_lock = IsRotationLocked();
@@ -839,15 +839,16 @@
   EXPECT_EQ(current_rotation_lock, rotation_lock);
 
   int orientation;
-  gfx::Display::Rotation current_rotation = GetCurrentInternalDisplayRotation();
+  display::Display::Rotation current_rotation =
+      GetCurrentInternalDisplayRotation();
   EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
   EXPECT_EQ(current_rotation, orientation);
 }
 
 // Tests that the rotation state is saved when a guest is logged in.
 TEST_F(DisplayPreferencesTest, StoreRotationStateGuest) {
-  gfx::Display::SetInternalDisplayId(
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  display::Display::SetInternalDisplayId(
+      display::Screen::GetScreen()->GetPrimaryDisplay().id());
   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
   LoggedInAsGuest();
 
@@ -862,15 +863,16 @@
   EXPECT_EQ(current_rotation_lock, rotation_lock);
 
   int orientation;
-  gfx::Display::Rotation current_rotation = GetCurrentInternalDisplayRotation();
+  display::Display::Rotation current_rotation =
+      GetCurrentInternalDisplayRotation();
   EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
   EXPECT_EQ(current_rotation, orientation);
 }
 
 // Tests that the rotation state is saved when a normal user is logged in.
 TEST_F(DisplayPreferencesTest, StoreRotationStateNormalUser) {
-  gfx::Display::SetInternalDisplayId(
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  display::Display::SetInternalDisplayId(
+      display::Screen::GetScreen()->GetPrimaryDisplay().id());
   EXPECT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
   LoggedInAsGuest();
 
@@ -885,7 +887,8 @@
   EXPECT_EQ(current_rotation_lock, rotation_lock);
 
   int orientation;
-  gfx::Display::Rotation current_rotation = GetCurrentInternalDisplayRotation();
+  display::Display::Rotation current_rotation =
+      GetCurrentInternalDisplayRotation();
   EXPECT_TRUE(properties->GetInteger("orientation", &orientation));
   EXPECT_EQ(current_rotation, orientation);
 }
@@ -893,21 +896,22 @@
 // Tests that rotation state is loaded without a user being logged in, and that
 // entering maximize mode applies the state.
 TEST_F(DisplayPreferencesTest, LoadRotationNoLogin) {
-  gfx::Display::SetInternalDisplayId(
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  display::Display::SetInternalDisplayId(
+      display::Screen::GetScreen()->GetPrimaryDisplay().id());
   ASSERT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
 
   ash::Shell* shell = ash::Shell::GetInstance();
   bool initial_rotation_lock = IsRotationLocked();
   ASSERT_FALSE(initial_rotation_lock);
   ash::DisplayManager* display_manager = shell->display_manager();
-  gfx::Display::Rotation initial_rotation = GetCurrentInternalDisplayRotation();
-  ASSERT_EQ(gfx::Display::ROTATE_0, initial_rotation);
+  display::Display::Rotation initial_rotation =
+      GetCurrentInternalDisplayRotation();
+  ASSERT_EQ(display::Display::ROTATE_0, initial_rotation);
 
   StoreDisplayRotationPrefs(initial_rotation_lock);
   ASSERT_TRUE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
 
-  StoreDisplayRotationPrefsForTest(true, gfx::Display::ROTATE_90);
+  StoreDisplayRotationPrefsForTest(true, display::Display::ROTATE_90);
   LoadDisplayPreferences(false);
 
   bool display_rotation_lock =
@@ -915,15 +919,15 @@
   bool display_rotation =
       display_manager->registered_internal_display_rotation();
   EXPECT_TRUE(display_rotation_lock);
-  EXPECT_EQ(gfx::Display::ROTATE_90, display_rotation);
+  EXPECT_EQ(display::Display::ROTATE_90, display_rotation);
 
   bool rotation_lock = IsRotationLocked();
-  gfx::Display::Rotation before_maximize_mode_rotation =
+  display::Display::Rotation before_maximize_mode_rotation =
       GetCurrentInternalDisplayRotation();
 
   // Settings should not be applied until maximize mode activates
   EXPECT_FALSE(rotation_lock);
-  EXPECT_EQ(gfx::Display::ROTATE_0, before_maximize_mode_rotation);
+  EXPECT_EQ(display::Display::ROTATE_0, before_maximize_mode_rotation);
 
   // Open up 270 degrees to trigger maximize mode
   scoped_refptr<chromeos::AccelerometerUpdate> update(
@@ -936,16 +940,16 @@
   maximize_mode_controller->OnAccelerometerUpdated(update);
   EXPECT_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
   bool screen_orientation_rotation_lock = IsRotationLocked();
-  gfx::Display::Rotation maximize_mode_rotation =
+  display::Display::Rotation maximize_mode_rotation =
       GetCurrentInternalDisplayRotation();
   EXPECT_TRUE(screen_orientation_rotation_lock);
-  EXPECT_EQ(gfx::Display::ROTATE_90, maximize_mode_rotation);
+  EXPECT_EQ(display::Display::ROTATE_90, maximize_mode_rotation);
 }
 
 // Tests that rotation lock being set causes the rotation state to be saved.
 TEST_F(DisplayPreferencesTest, RotationLockTriggersStore) {
-  gfx::Display::SetInternalDisplayId(
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().id());
+  display::Display::SetInternalDisplayId(
+      display::Screen::GetScreen()->GetPrimaryDisplay().id());
   ASSERT_FALSE(local_state()->HasPrefPath(prefs::kDisplayRotationLock));
 
   ash::Shell::GetInstance()->screen_orientation_controller()->SetRotationLocked(
@@ -968,8 +972,9 @@
 
   UpdateDisplay("200x200,100x100");
   display::DisplayIdList list = display_manager->GetCurrentDisplayIdList();
-  EXPECT_EQ("400x200",
-            gfx::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
+  EXPECT_EQ(
+      "400x200",
+      display::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
 
   const base::DictionaryValue* secondary_displays =
       local_state()->GetDictionary(prefs::kSecondaryDisplays);
@@ -984,13 +989,14 @@
 
   const base::DictionaryValue* displays =
       local_state()->GetDictionary(prefs::kDisplayProperties);
-  int64_t unified_id = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t unified_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   EXPECT_FALSE(
       displays->GetDictionary(base::Int64ToString(unified_id), &new_value));
 
   ash::test::SetDisplayResolution(unified_id, gfx::Size(200, 100));
-  EXPECT_EQ("200x100",
-            gfx::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
+  EXPECT_EQ(
+      "200x100",
+      display::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
   EXPECT_FALSE(
       displays->GetDictionary(base::Int64ToString(unified_id), &new_value));
 
@@ -1020,7 +1026,7 @@
 }
 
 TEST_F(DisplayPreferencesTest, RestoreUnifiedMode) {
-  int64_t id1 = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   display::DisplayIdList list = ash::test::CreateDisplayIdList2(id1, id1 + 1);
   StoreDisplayBoolPropertyForList(list, "default_unified", true);
   StoreDisplayPropertyForList(
@@ -1087,7 +1093,7 @@
   LoggedInAsUser();
   ash::DisplayManager* display_manager =
       ash::Shell::GetInstance()->display_manager();
-  int64_t id1 = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t id1 = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   display::DisplayIdList list =
       ash::test::CreateDisplayIdListN(3, id1, id1 + 1, id1 + 2);
 
diff --git a/chrome/browser/chromeos/display/output_protection_delegate.cc b/chrome/browser/chromeos/display/output_protection_delegate.cc
index 2c347d0..af8c711f 100644
--- a/chrome/browser/chromeos/display/output_protection_delegate.cc
+++ b/chrome/browser/chromeos/display/output_protection_delegate.cc
@@ -11,7 +11,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace chromeos {
 
@@ -22,10 +22,11 @@
   DCHECK(rfh);
   DCHECK(display_id);
 
-  gfx::Screen* screen = gfx::Screen::GetScreen();
+  display::Screen* screen = display::Screen::GetScreen();
   if (!screen)
     return false;
-  gfx::Display display = screen->GetDisplayNearestWindow(rfh->GetNativeView());
+  display::Display display =
+      screen->GetDisplayNearestWindow(rfh->GetNativeView());
   *display_id = display.id();
   return true;
 }
diff --git a/chrome/browser/chromeos/display/overscan_calibrator.cc b/chrome/browser/chromeos/display/overscan_calibrator.cc
index 86fa15e..d268c01 100644
--- a/chrome/browser/chromeos/display/overscan_calibrator.cc
+++ b/chrome/browser/chromeos/display/overscan_calibrator.cc
@@ -71,8 +71,8 @@
 
 }  // namespace
 
-OverscanCalibrator::OverscanCalibrator(
-    const gfx::Display& target_display, const gfx::Insets& initial_insets)
+OverscanCalibrator::OverscanCalibrator(const display::Display& target_display,
+                                       const gfx::Insets& initial_insets)
     : display_(target_display),
       insets_(initial_insets),
       initial_insets_(initial_insets),
diff --git a/chrome/browser/chromeos/display/overscan_calibrator.h b/chrome/browser/chromeos/display/overscan_calibrator.h
index 4cd0982..cd4973cf 100644
--- a/chrome/browser/chromeos/display/overscan_calibrator.h
+++ b/chrome/browser/chromeos/display/overscan_calibrator.h
@@ -9,7 +9,7 @@
 
 #include "base/macros.h"
 #include "ui/compositor/layer_delegate.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -23,7 +23,7 @@
 // calibrating display overscan settings.
 class OverscanCalibrator : public ui::LayerDelegate {
  public:
-  OverscanCalibrator(const gfx::Display& target_display,
+  OverscanCalibrator(const display::Display& target_display,
                      const gfx::Insets& initial_insets);
   ~OverscanCalibrator() override;
 
@@ -48,7 +48,7 @@
   base::Closure PrepareForLayerBoundsChange() override;
 
   // The target display.
-  const gfx::Display display_;
+  const display::Display display_;
 
   // The current insets.
   gfx::Insets insets_;
diff --git a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc
index fa47c93..5180bc0 100644
--- a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc
+++ b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/chromeos/input_method/mode_indicator_controller.h"
 #include "ui/base/ime/ime_bridge.h"
 #include "ui/chromeos/ime/infolist_window.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/widget/widget.h"
 
 namespace chromeos {
diff --git a/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc b/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc
index 37b9069..32a691e 100644
--- a/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc
+++ b/chrome/browser/chromeos/input_method/mode_indicator_browsertest.cc
@@ -171,8 +171,9 @@
   EXPECT_EQ(mi1_bounds.width(),  mi2_bounds.width());
   EXPECT_EQ(mi1_bounds.height(), mi2_bounds.height());
 
-  const gfx::Rect screen_bounds =
-      gfx::Screen::GetScreen()->GetDisplayMatching(cursor1_bounds).work_area();
+  const gfx::Rect screen_bounds = display::Screen::GetScreen()
+                                      ->GetDisplayMatching(cursor1_bounds)
+                                      .work_area();
 
   // Check if the location of the mode indicator is concidered with
   // the screen size.
diff --git a/chrome/browser/chromeos/login/helper.cc b/chrome/browser/chromeos/login/helper.cc
index 85e4283..acaba4a 100644
--- a/chrome/browser/chromeos/login/helper.cc
+++ b/chrome/browser/chromeos/login/helper.cc
@@ -27,8 +27,8 @@
 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/screen.h"
 
 namespace chromeos {
 
@@ -87,7 +87,7 @@
 }  // namespace
 
 gfx::Rect CalculateScreenBounds(const gfx::Size& size) {
-  gfx::Rect bounds = gfx::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+  gfx::Rect bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
   if (!size.IsEmpty()) {
     int horizontal_diff = bounds.width() - size.width();
     int vertical_diff = bounds.height() - size.height();
@@ -100,7 +100,7 @@
   // The biggest size that the profile picture is displayed at is currently
   // 220px, used for the big preview on OOBE and Change Picture options page.
   static const int kBaseUserImageSize = 220;
-  float scale_factor = gfx::Display::GetForcedDeviceScaleFactor();
+  float scale_factor = display::Display::GetForcedDeviceScaleFactor();
   if (scale_factor > 1.0f)
     return static_cast<int>(scale_factor * kBaseUserImageSize);
   return kBaseUserImageSize * gfx::ImageSkia::GetMaxSupportedScale();
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
index 7ff73d2c..df9569d9 100644
--- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
@@ -31,7 +31,7 @@
 #include "ui/aura/client/capture_client.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/x/x11_util.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/keyboard/keyboard_controller.h"
 #include "ui/keyboard/keyboard_util.h"
 #include "ui/views/controls/webview/webview.h"
@@ -70,7 +70,7 @@
   set_should_emit_login_prompt_visible(false);
   ash::Shell::GetInstance()->lock_state_controller()->AddObserver(this);
   ash::Shell::GetInstance()->delegate()->AddVirtualKeyboardStateObserver(this);
-  gfx::Screen::GetScreen()->AddObserver(this);
+  display::Screen::GetScreen()->AddObserver(this);
   DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
 
   if (keyboard::KeyboardController::GetInstance()) {
@@ -80,7 +80,7 @@
 }
 
 void WebUIScreenLocker::LockScreen() {
-  gfx::Rect bounds = gfx::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+  gfx::Rect bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
 
   lock_time_ = base::TimeTicks::Now();
   LockWindow* lock_window = LockWindow::Create();
@@ -164,7 +164,7 @@
 
 WebUIScreenLocker::~WebUIScreenLocker() {
   DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
-  gfx::Screen::GetScreen()->RemoveObserver(this);
+  display::Screen::GetScreen()->RemoveObserver(this);
   ash::Shell::GetInstance()->
       lock_state_controller()->RemoveObserver(this);
 
@@ -407,17 +407,16 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// gfx::DisplayObserver:
+// display::DisplayObserver:
 
-void WebUIScreenLocker::OnDisplayAdded(const gfx::Display& new_display) {
-}
+void WebUIScreenLocker::OnDisplayAdded(const display::Display& new_display) {}
 
-void WebUIScreenLocker::OnDisplayRemoved(const gfx::Display& old_display) {
-}
+void WebUIScreenLocker::OnDisplayRemoved(const display::Display& old_display) {}
 
-void WebUIScreenLocker::OnDisplayMetricsChanged(const gfx::Display& display,
+void WebUIScreenLocker::OnDisplayMetricsChanged(const display::Display& display,
                                                 uint32_t changed_metrics) {
-  gfx::Display primary_display = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+  display::Display primary_display =
+      display::Screen::GetScreen()->GetPrimaryDisplay();
   if (display.id() != primary_display.id() ||
       !(changed_metrics & DISPLAY_METRIC_BOUNDS)) {
     return;
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.h b/chrome/browser/chromeos/login/lock/webui_screen_locker.h
index 72b5513..4c0fff3 100644
--- a/chrome/browser/chromeos/login/lock/webui_screen_locker.h
+++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.h
@@ -24,7 +24,7 @@
 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
 #include "chromeos/dbus/power_manager_client.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "ui/gfx/display_observer.h"
+#include "ui/display/display_observer.h"
 #include "ui/keyboard/keyboard_controller_observer.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_observer.h"
@@ -58,7 +58,7 @@
                           public PowerManagerClient::Observer,
                           public ash::VirtualKeyboardStateObserver,
                           public keyboard::KeyboardControllerObserver,
-                          public gfx::DisplayObserver,
+                          public display::DisplayObserver,
                           public content::WebContentsObserver {
  public:
   explicit WebUIScreenLocker(ScreenLocker* screen_locker);
@@ -129,10 +129,10 @@
   // keyboard::KeyboardControllerObserver:
   void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) override;
 
-  // gfx::DisplayObserver:
-  void OnDisplayAdded(const gfx::Display& new_display) override;
-  void OnDisplayRemoved(const gfx::Display& old_display) override;
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  // display::DisplayObserver:
+  void OnDisplayAdded(const display::Display& new_display) override;
+  void OnDisplayRemoved(const display::Display& old_display) override;
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override;
 
   // Returns instance of the OOBE WebUI.
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
index 80dabaa..a209a8a 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
@@ -90,11 +90,11 @@
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_observer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/events/event_utils.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/transform.h"
 #include "ui/keyboard/keyboard_controller.h"
 #include "ui/keyboard/keyboard_util.h"
@@ -285,7 +285,7 @@
   }
 
   ash::Shell::GetInstance()->delegate()->AddVirtualKeyboardStateObserver(this);
-  gfx::Screen::GetScreen()->AddObserver(this);
+  display::Screen::GetScreen()->AddObserver(this);
 
   // We need to listen to CLOSE_ALL_BROWSERS_REQUEST but not APP_TERMINATING
   // because/ APP_TERMINATING will never be fired as long as this keeps
@@ -391,7 +391,7 @@
 
   ash::Shell::GetInstance()->delegate()->
       RemoveVirtualKeyboardStateObserver(this);
-  gfx::Screen::GetScreen()->RemoveObserver(this);
+  display::Screen::GetScreen()->RemoveObserver(this);
 
   if (login_view_ && login_window_)
     login_window_->RemoveRemovalsObserver(this);
@@ -907,17 +907,19 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// LoginDisplayHostImpl, gfx::DisplayObserver implementation:
+// LoginDisplayHostImpl, display::DisplayObserver implementation:
 
-void LoginDisplayHostImpl::OnDisplayAdded(const gfx::Display& new_display) {
+void LoginDisplayHostImpl::OnDisplayAdded(const display::Display& new_display) {
 }
 
-void LoginDisplayHostImpl::OnDisplayRemoved(const gfx::Display& old_display) {
-}
+void LoginDisplayHostImpl::OnDisplayRemoved(
+    const display::Display& old_display) {}
 
-void LoginDisplayHostImpl::OnDisplayMetricsChanged(const gfx::Display& display,
-                                                   uint32_t changed_metrics) {
-  gfx::Display primary_display = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+void LoginDisplayHostImpl::OnDisplayMetricsChanged(
+    const display::Display& display,
+    uint32_t changed_metrics) {
+  display::Display primary_display =
+      display::Screen::GetScreen()->GetPrimaryDisplay();
   if (display.id() != primary_display.id() ||
       !(changed_metrics & DISPLAY_METRIC_BOUNDS)) {
     return;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.h b/chrome/browser/chromeos/login/ui/login_display_host_impl.h
index 47b2185b..4114523 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_impl.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.h
@@ -29,7 +29,7 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "ui/gfx/display_observer.h"
+#include "ui/display/display_observer.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/keyboard/keyboard_controller_observer.h"
 #include "ui/views/widget/widget_removals_observer.h"
@@ -60,7 +60,7 @@
                              public chromeos::CrasAudioHandler::AudioObserver,
                              public ash::VirtualKeyboardStateObserver,
                              public keyboard::KeyboardControllerObserver,
-                             public gfx::DisplayObserver,
+                             public display::DisplayObserver,
                              public views::WidgetRemovalsObserver,
                              public chrome::MultiUserWindowManager::Observer {
  public:
@@ -130,10 +130,10 @@
   // Overridden from keyboard::KeyboardControllerObserver:
   void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) override;
 
-  // Overridden from gfx::DisplayObserver:
-  void OnDisplayAdded(const gfx::Display& new_display) override;
-  void OnDisplayRemoved(const gfx::Display& old_display) override;
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  // Overridden from display::DisplayObserver:
+  void OnDisplayAdded(const display::Display& new_display) override;
+  void OnDisplayRemoved(const display::Display& old_display) override;
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override;
 
   // Overriden from views::WidgetRemovalsObserver:
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
index 36fb73c..93cc330 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -139,9 +139,16 @@
   ProfileHelper::Get()->ActiveUserHashChanged(
       ProfileHelper::GetUserIdHashByUserIdForTesting(
           account_id.GetUserEmail()));
+  active_user_ = nullptr;
   if (!users_.empty() && active_account_id_.is_valid()) {
-    for (user_manager::User* user : users_)
-      user->set_is_active(user->GetAccountId() == active_account_id_);
+    for (user_manager::User* const user : users_) {
+      if (user->GetAccountId() == active_account_id_) {
+        active_user_ = user;
+        user->set_is_active(true);
+      } else {
+        user->set_is_active(false);
+      }
+    }
   }
 }
 
diff --git a/chrome/browser/chromeos/net/network_portal_web_dialog.cc b/chrome/browser/chromeos/net/network_portal_web_dialog.cc
index 364fbb7..0578168 100644
--- a/chrome/browser/chromeos/net/network_portal_web_dialog.cc
+++ b/chrome/browser/chromeos/net/network_portal_web_dialog.cc
@@ -8,9 +8,9 @@
 #include "components/captive_portal/captive_portal_detector.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/ui_base_types.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/widget/widget.h"
 #include "url/gurl.h"
 
@@ -20,12 +20,13 @@
 const float kNetworkPortalWebDialogHeightFraction = .8;
 
 gfx::Size GetPortalDialogSize() {
-  const gfx::Display display = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+  const display::Display display =
+      display::Screen::GetScreen()->GetPrimaryDisplay();
 
   gfx::Size display_size = display.size();
 
-  if (display.rotation() == gfx::Display::ROTATE_90 ||
-      display.rotation() == gfx::Display::ROTATE_270) {
+  if (display.rotation() == display::Display::ROTATE_90 ||
+      display.rotation() == display::Display::ROTATE_270) {
     display_size = gfx::Size(display_size.height(), display_size.width());
   }
 
diff --git a/chrome/browser/chromeos/policy/android_management_client.cc b/chrome/browser/chromeos/policy/android_management_client.cc
new file mode 100644
index 0000000..3b29621
--- /dev/null
+++ b/chrome/browser/chromeos/policy/android_management_client.cc
@@ -0,0 +1,116 @@
+// Copyright (c) 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/chromeos/policy/android_management_client.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/guid.h"
+#include "base/logging.h"
+#include "components/policy/core/common/cloud/device_management_service.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "policy/proto/device_management_backend.pb.h"
+
+namespace em = enterprise_management;
+
+namespace policy {
+
+AndroidManagementClient::AndroidManagementClient(
+    DeviceManagementService* device_management_service,
+    scoped_refptr<net::URLRequestContextGetter> request_context,
+    const std::string& account_id,
+    OAuth2TokenService* token_service)
+    : OAuth2TokenService::Consumer("android_management_client"),
+      device_management_service_(device_management_service),
+      request_context_(request_context),
+      account_id_(account_id),
+      token_service_(token_service),
+      weak_ptr_factory_(this) {}
+
+AndroidManagementClient::~AndroidManagementClient() {}
+
+void AndroidManagementClient::StartCheckAndroidManagement(
+    const StatusCallback& callback) {
+  DCHECK(device_management_service_);
+  DCHECK(callback_.is_null());
+
+  callback_ = callback;
+  RequestAccessToken();
+}
+
+void AndroidManagementClient::OnGetTokenSuccess(
+    const OAuth2TokenService::Request* request,
+    const std::string& access_token,
+    const base::Time& expiration_time) {
+  DCHECK_EQ(token_request_.get(), request);
+  token_request_.reset();
+
+  CheckAndroidManagement(access_token);
+}
+
+void AndroidManagementClient::OnGetTokenFailure(
+    const OAuth2TokenService::Request* request,
+    const GoogleServiceAuthError& error) {
+  DCHECK_EQ(token_request_.get(), request);
+  token_request_.reset();
+  LOG(ERROR) << "Token request failed: " << error.ToString();
+
+  callback_.Run(RESULT_ERROR);
+  callback_.Reset();
+}
+
+void AndroidManagementClient::RequestAccessToken() {
+  DCHECK(!token_request_);
+  // The user must be signed in already.
+  DCHECK(token_service_->RefreshTokenIsAvailable(account_id_));
+
+  OAuth2TokenService::ScopeSet scopes;
+  scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
+  scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
+  token_request_ = token_service_->StartRequest(account_id_, scopes, this);
+}
+
+void AndroidManagementClient::CheckAndroidManagement(
+    const std::string& access_token) {
+  request_job_.reset(device_management_service_->CreateJob(
+      DeviceManagementRequestJob::TYPE_ANDROID_MANAGEMENT_CHECK,
+      request_context_.get()));
+  request_job_->SetOAuthToken(access_token);
+  request_job_->SetClientID(base::GenerateGUID());
+  request_job_->GetRequest()->mutable_check_android_management_request();
+
+  request_job_->Start(
+      base::Bind(&AndroidManagementClient::OnAndroidManagementChecked,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AndroidManagementClient::OnAndroidManagementChecked(
+    DeviceManagementStatus status,
+    int net_error,
+    const em::DeviceManagementResponse& response) {
+  if (status == DM_STATUS_SUCCESS &&
+      !response.has_check_android_management_response()) {
+    LOG(WARNING) << "Invalid check android management response.";
+    status = DM_STATUS_RESPONSE_DECODING_ERROR;
+  }
+
+  Result result;
+  switch (status) {
+    case DM_STATUS_SUCCESS:
+      result = RESULT_UNMANAGED;
+      break;
+    case DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
+      result = RESULT_MANAGED;
+      break;
+    default:
+      result = RESULT_ERROR;
+  }
+
+  request_job_.reset();
+  callback_.Run(result);
+  callback_.Reset();
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/android_management_client.h b/chrome/browser/chromeos/policy/android_management_client.h
new file mode 100644
index 0000000..44915a6
--- /dev/null
+++ b/chrome/browser/chromeos/policy/android_management_client.h
@@ -0,0 +1,100 @@
+// Copyright (c) 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_CHROMEOS_POLICY_ANDROID_MANAGEMENT_CLIENT_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_ANDROID_MANAGEMENT_CLIENT_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "google_apis/gaia/oauth2_token_service.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace enterprise_management {
+class DeviceManagementResponse;
+}
+
+namespace policy {
+
+class DeviceManagementRequestJob;
+class DeviceManagementService;
+
+// Interacts with the device management service and determines whether Android
+// management is enabled for the user or not. Uses the OAuth2TokenService to
+// acquire access tokens for the device management.
+class AndroidManagementClient : public OAuth2TokenService::Consumer {
+ public:
+  // Indicates result of the android management check.
+  enum Result {
+    RESULT_MANAGED,    // Android management is enabled.
+    RESULT_UNMANAGED,  // Android management is disabled.
+    RESULT_ERROR,      // Received a error.
+  };
+
+  // A callback which receives Result status of an operation.
+  using StatusCallback = base::Callback<void(Result)>;
+
+  AndroidManagementClient(
+      DeviceManagementService* service,
+      scoped_refptr<net::URLRequestContextGetter> request_context,
+      const std::string& account_id,
+      OAuth2TokenService* token_service);
+  ~AndroidManagementClient() override;
+
+  // Starts sending of check Android management request to DM server, issues
+  // access token if neccessary. |callback| is called on check Android
+  // management completion.
+  void StartCheckAndroidManagement(const StatusCallback& callback);
+
+  // |access_token| is owned by caller and must exist before
+  // StartCheckAndroidManagement is called for testing.
+  static void SetAccessTokenForTesting(const char* access_token);
+
+ private:
+  // OAuth2TokenService::Consumer:
+  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
+                         const std::string& access_token,
+                         const base::Time& expiration_time) override;
+  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
+                         const GoogleServiceAuthError& error) override;
+
+  // Requests an access token.
+  void RequestAccessToken();
+
+  // Sends a CheckAndroidManagementRequest to DM server.
+  void CheckAndroidManagement(const std::string& access_token);
+
+  // Callback for check Android management requests.
+  void OnAndroidManagementChecked(
+      DeviceManagementStatus status,
+      int net_error,
+      const enterprise_management::DeviceManagementResponse& response);
+
+  // Used to communicate with the device management service.
+  DeviceManagementService* const device_management_service_;
+  scoped_refptr<net::URLRequestContextGetter> request_context_;
+  std::unique_ptr<DeviceManagementRequestJob> request_job_;
+
+  // The account ID that will be used for the access token fetch.
+  const std::string account_id_;
+  // The token service used to retrieve the access token.
+  OAuth2TokenService* const token_service_;
+  // The OAuth request to receive the access token.
+  std::unique_ptr<OAuth2TokenService::Request> token_request_;
+
+  StatusCallback callback_;
+
+  base::WeakPtrFactory<AndroidManagementClient> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AndroidManagementClient);
+};
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_ANDROID_MANAGEMENT_CLIENT_H_
diff --git a/chrome/browser/chromeos/policy/android_management_client_unittest.cc b/chrome/browser/chromeos/policy/android_management_client_unittest.cc
new file mode 100644
index 0000000..09f4e02
--- /dev/null
+++ b/chrome/browser/chromeos/policy/android_management_client_unittest.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 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 <string>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
+#include "chrome/browser/chromeos/policy/android_management_client.h"
+#include "components/policy/core/common/cloud/mock_device_management_service.h"
+#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_test_util.h"
+#include "policy/proto/device_management_backend.pb.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::SaveArg;
+using testing::StrictMock;
+using testing::_;
+
+namespace em = enterprise_management;
+
+namespace policy {
+
+namespace {
+
+const char kAccountId[] = "fake-account-id";
+const char kRefreshToken[] = "fake-refresh-token";
+const char kOAuthToken[] = "fake-oauth-token";
+
+MATCHER_P(MatchProto, expected, "matches protobuf") {
+  return arg.SerializePartialAsString() == expected.SerializePartialAsString();
+}
+
+// A mock class to allow us to set expectations on upload callbacks.
+class MockStatusCallbackObserver {
+ public:
+  MockStatusCallbackObserver() {}
+
+  MOCK_METHOD1(OnCallbackComplete, void(AndroidManagementClient::Result));
+};
+
+}  // namespace
+
+class AndroidManagementClientTest : public testing::Test {
+ protected:
+  AndroidManagementClientTest() {
+    android_management_request_.mutable_check_android_management_request();
+    android_management_response_.mutable_check_android_management_response();
+  }
+
+  // testing::Test:
+  void SetUp() override {
+    request_context_ =
+        new net::TestURLRequestContextGetter(loop_.task_runner());
+    client_.reset(new AndroidManagementClient(&service_, request_context_,
+                                              kAccountId, &token_service_));
+  }
+
+  // Request protobuf is used as extectation for the client requests.
+  em::DeviceManagementRequest android_management_request_;
+
+  // Protobuf is used in successfil responsees.
+  em::DeviceManagementResponse android_management_response_;
+
+  base::MessageLoop loop_;
+  MockDeviceManagementService service_;
+  StrictMock<MockStatusCallbackObserver> callback_observer_;
+  std::unique_ptr<AndroidManagementClient> client_;
+  // Pointer to the client's request context.
+  scoped_refptr<net::URLRequestContextGetter> request_context_;
+  std::string oauh_token_;
+  FakeProfileOAuth2TokenService token_service_;
+};
+
+TEST_F(AndroidManagementClientTest, CheckAndroidManagementCall) {
+  std::string client_id;
+  EXPECT_CALL(
+      service_,
+      CreateJob(DeviceManagementRequestJob::TYPE_ANDROID_MANAGEMENT_CHECK,
+                request_context_))
+      .WillOnce(service_.SucceedJob(android_management_response_));
+  EXPECT_CALL(service_,
+              StartJob(dm_protocol::kValueRequestCheckAndroidManagement,
+                       std::string(), kOAuthToken, std::string(), _,
+                       MatchProto(android_management_request_)))
+      .WillOnce(SaveArg<4>(&client_id));
+  EXPECT_CALL(
+      callback_observer_,
+      OnCallbackComplete(AndroidManagementClient::Result::RESULT_UNMANAGED))
+      .Times(1);
+
+  AndroidManagementClient::StatusCallback callback =
+      base::Bind(&MockStatusCallbackObserver::OnCallbackComplete,
+                 base::Unretained(&callback_observer_));
+
+  token_service_.UpdateCredentials(kAccountId, kRefreshToken);
+  client_->StartCheckAndroidManagement(callback);
+  token_service_.IssueAllTokensForAccount(kAccountId, kOAuthToken,
+                                          base::Time::Max());
+  ASSERT_LT(client_id.size(), 64U);
+}
+
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
index 03f72fb..a9e18c3e 100644
--- a/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
+++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.cc
@@ -67,13 +67,14 @@
       ash::Shell::GetInstance()->display_manager();
   const size_t num_displays = display_manager->GetNumDisplays();
   for (size_t i = 0; i < num_displays; ++i) {
-    const gfx::Display& display = display_manager->GetDisplayAt(i);
+    const display::Display& display = display_manager->GetDisplayAt(i);
     const int64_t id = display.id();
     if (rotated_displays_.find(id) == rotated_displays_.end()) {
       rotated_displays_.insert(id);
       if (display.rotation() != display_rotation_default_) {
-        display_manager->SetDisplayRotation(id, display_rotation_default_,
-            gfx::Display::ROTATION_SOURCE_ACTIVE);
+        display_manager->SetDisplayRotation(
+            id, display_rotation_default_,
+            display::Display::ROTATION_SOURCE_ACTIVE);
       }
     }
   }
@@ -84,12 +85,13 @@
   int new_rotation;
   bool new_policy_enabled = chromeos::CrosSettings::Get()->GetInteger(
       chromeos::kDisplayRotationDefault, &new_rotation);
-  gfx::Display::Rotation new_display_rotation_default = gfx::Display::ROTATE_0;
+  display::Display::Rotation new_display_rotation_default =
+      display::Display::ROTATE_0;
   if (new_policy_enabled) {
-    if (new_rotation >= gfx::Display::ROTATE_0 &&
-        new_rotation <= gfx::Display::ROTATE_270) {
+    if (new_rotation >= display::Display::ROTATE_0 &&
+        new_rotation <= display::Display::ROTATE_270) {
       new_display_rotation_default =
-          static_cast<gfx::Display::Rotation>(new_rotation);
+          static_cast<display::Display::Rotation>(new_rotation);
     } else {
       LOG(ERROR) << "CrosSettings contains invalid value " << new_rotation
                  << " for DisplayRotationDefault. Ignoring setting.";
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler.h b/chrome/browser/chromeos/policy/display_rotation_default_handler.h
index eb01c57f..78d99f0 100644
--- a/chrome/browser/chromeos/policy/display_rotation_default_handler.h
+++ b/chrome/browser/chromeos/policy/display_rotation_default_handler.h
@@ -14,7 +14,7 @@
 #include "ash/shell_observer.h"
 #include "base/macros.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 
 namespace policy {
 
@@ -56,7 +56,8 @@
   bool UpdateFromCrosSettings();
 
   bool policy_enabled_ = false;
-  gfx::Display::Rotation display_rotation_default_ = gfx::Display::ROTATE_0;
+  display::Display::Rotation display_rotation_default_ =
+      display::Display::ROTATE_0;
   std::set<int64_t> rotated_displays_;
   bool rotation_in_progress_ = false;
 
diff --git a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
index faf4c46..0ad7f41 100644
--- a/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
+++ b/chrome/browser/chromeos/policy/display_rotation_default_handler_browsertest.cc
@@ -32,8 +32,8 @@
 #include "chromeos/settings/cros_settings_names.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/display.h"
 #include "ui/display/manager/display_layout.h"
-#include "ui/gfx/display.h"
 
 namespace em = enterprise_management;
 
@@ -43,25 +43,25 @@
   return ash::Shell::GetInstance()->display_manager();
 }
 
-gfx::Display::Rotation GetRotationOfFirstDisplay() {
+display::Display::Rotation GetRotationOfFirstDisplay() {
   const ash::DisplayManager* const display_manager = GetDisplayManager();
   const int64_t first_display_id = display_manager->first_display_id();
-  const gfx::Display& first_display =
+  const display::Display& first_display =
       display_manager->GetDisplayForId(first_display_id);
   return first_display.rotation();
 }
 
 // Fails the test and returns ROTATE_0 if there is no second display.
-gfx::Display::Rotation GetRotationOfSecondDisplay() {
+display::Display::Rotation GetRotationOfSecondDisplay() {
   const ash::DisplayManager* const display_manager = GetDisplayManager();
   if (display_manager->GetNumDisplays() < 2) {
     ADD_FAILURE()
         << "Requested rotation of second display while there was only one.";
-    return gfx::Display::ROTATE_0;
+    return display::Display::ROTATE_0;
   }
   const display::DisplayIdList display_id_pair =
       display_manager->GetCurrentDisplayIdList();
-  const gfx::Display& second_display =
+  const display::Display& second_display =
       display_manager->GetDisplayForId(display_id_pair[1]);
   return second_display.rotation();
 }
@@ -72,7 +72,7 @@
 
 class DisplayRotationDefaultTest
     : public policy::DevicePolicyCrosBrowserTest,
-      public testing::WithParamInterface<gfx::Display::Rotation> {
+      public testing::WithParamInterface<display::Display::Rotation> {
  public:
   DisplayRotationDefaultTest() {}
 
@@ -144,7 +144,7 @@
   DISALLOW_COPY_AND_ASSIGN(DisplayRotationDefaultTest);
 };
 
-// If gfx::Display::Rotation is ever modified and this test fails, there are
+// If display::Display::Rotation is ever modified and this test fails, there are
 // hardcoded enum-values in the following files that might need adjustment:
 // * this file: range check in this function, initializations, expected values,
 //              the list of parameters at the bottom of the file
@@ -154,10 +154,10 @@
 // * chrome/browser/chromeos/policy/proto/chrome_device_policy.proto:
 //       DisplayRotationDefaultProto::Rotation should match one to one
 IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, EnumsInSync) {
-  const gfx::Display::Rotation rotation = GetParam();
+  const display::Display::Rotation rotation = GetParam();
   EXPECT_EQ(em::DisplayRotationDefaultProto::Rotation_ARRAYSIZE,
-            gfx::Display::ROTATE_270 + 1)
-      << "Enums gfx::Display::Rotation and "
+            display::Display::ROTATE_270 + 1)
+      << "Enums display::Display::Rotation and "
       << "em::DisplayRotationDefaultProto::Rotation are not in sync.";
   EXPECT_TRUE(em::DisplayRotationDefaultProto::Rotation_IsValid(rotation))
       << rotation << " is invalid as rotation. All valid values lie in "
@@ -166,8 +166,8 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, FirstDisplay) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
-  EXPECT_EQ(gfx::Display::ROTATE_0, GetRotationOfFirstDisplay())
+  const display::Display::Rotation policy_rotation = GetParam();
+  EXPECT_EQ(display::Display::ROTATE_0, GetRotationOfFirstDisplay())
       << "Initial primary rotation before policy";
 
   SetPolicy(policy_rotation);
@@ -181,9 +181,9 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, RefreshSecondDisplay) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
+  const display::Display::Rotation policy_rotation = GetParam();
   ToggleSecondDisplay();
-  EXPECT_EQ(gfx::Display::ROTATE_0, GetRotationOfSecondDisplay())
+  EXPECT_EQ(display::Display::ROTATE_0, GetRotationOfSecondDisplay())
       << "Rotation of secondary display before policy";
   SetPolicy(policy_rotation);
   EXPECT_EQ(policy_rotation, GetRotationOfSecondDisplay())
@@ -191,7 +191,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, ConnectSecondDisplay) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
+  const display::Display::Rotation policy_rotation = GetParam();
   SetPolicy(policy_rotation);
   ToggleSecondDisplay();
   EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay())
@@ -201,11 +201,11 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, UserInteraction) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
-  const gfx::Display::Rotation user_rotation = gfx::Display::ROTATE_90;
+  const display::Display::Rotation policy_rotation = GetParam();
+  const display::Display::Rotation user_rotation = display::Display::ROTATE_90;
   GetDisplayManager()->SetDisplayRotation(
       GetDisplayManager()->first_display_id(), user_rotation,
-      gfx::Display::ROTATION_SOURCE_USER);
+      display::Display::ROTATION_SOURCE_USER);
   EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay())
       << "Rotation of primary display after user change";
   SetPolicy(policy_rotation);
@@ -213,7 +213,7 @@
       << "Rotation of primary display after policy overrode user change";
   GetDisplayManager()->SetDisplayRotation(
       GetDisplayManager()->first_display_id(), user_rotation,
-      gfx::Display::ROTATION_SOURCE_USER);
+      display::Display::ROTATION_SOURCE_USER);
   EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay())
       << "Rotation of primary display after user overrode policy change";
   SetADifferentPolicy();
@@ -222,7 +222,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest, SetAndUnsetPolicy) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
+  const display::Display::Rotation policy_rotation = GetParam();
   SetPolicy(policy_rotation);
   UnsetPolicy();
   EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay())
@@ -231,12 +231,12 @@
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationDefaultTest,
                        SetAndUnsetPolicyWithUserInteraction) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
-  const gfx::Display::Rotation user_rotation = gfx::Display::ROTATE_90;
+  const display::Display::Rotation policy_rotation = GetParam();
+  const display::Display::Rotation user_rotation = display::Display::ROTATE_90;
   SetPolicy(policy_rotation);
   GetDisplayManager()->SetDisplayRotation(
       GetDisplayManager()->first_display_id(), user_rotation,
-      gfx::Display::ROTATION_SOURCE_USER);
+      display::Display::ROTATION_SOURCE_USER);
   UnsetPolicy();
   EXPECT_EQ(user_rotation, GetRotationOfFirstDisplay())
       << "Rotation of primary display after policy was set to "
@@ -246,10 +246,10 @@
 
 INSTANTIATE_TEST_CASE_P(PolicyDisplayRotationDefault,
                         DisplayRotationDefaultTest,
-                        testing::Values(gfx::Display::ROTATE_0,
-                                        gfx::Display::ROTATE_90,
-                                        gfx::Display::ROTATE_180,
-                                        gfx::Display::ROTATE_270));
+                        testing::Values(display::Display::ROTATE_0,
+                                        display::Display::ROTATE_90,
+                                        display::Display::ROTATE_180,
+                                        display::Display::ROTATE_270));
 
 // This class tests that the policy is reapplied after a reboot. To persist from
 // PRE_Reboot to Reboot, the policy is inserted into a FakeSessionManagerClient.
@@ -260,7 +260,7 @@
 // device_settings_cache::Retrieve()).
 class DisplayRotationBootTest
     : public InProcessBrowserTest,
-      public testing::WithParamInterface<gfx::Display::Rotation> {
+      public testing::WithParamInterface<display::Display::Rotation> {
  protected:
   DisplayRotationBootTest()
       : fake_session_manager_client_(new chromeos::FakeSessionManagerClient) {}
@@ -283,8 +283,8 @@
 };
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationBootTest, PRE_Reboot) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
-  const gfx::Display::Rotation user_rotation = gfx::Display::ROTATE_180;
+  const display::Display::Rotation policy_rotation = GetParam();
+  const display::Display::Rotation user_rotation = display::Display::ROTATE_180;
 
   // Set policy.
   policy::DevicePolicyBuilder* const device_policy(
@@ -305,19 +305,19 @@
   // Check the display's rotation.
   ash::DisplayManager* const display_manager = GetDisplayManager();
   const int64_t first_display_id = display_manager->first_display_id();
-  const gfx::Display& first_display =
+  const display::Display& first_display =
       display_manager->GetDisplayForId(first_display_id);
   EXPECT_EQ(policy_rotation, first_display.rotation());
 
   // Let the user rotate the display to a different orientation, to check that
   // the policy value is restored after reboot.
   display_manager->SetDisplayRotation(first_display_id, user_rotation,
-                                      gfx::Display::ROTATION_SOURCE_USER);
+                                      display::Display::ROTATION_SOURCE_USER);
   EXPECT_EQ(user_rotation, first_display.rotation());
 }
 
 IN_PROC_BROWSER_TEST_P(DisplayRotationBootTest, Reboot) {
-  const gfx::Display::Rotation policy_rotation = GetParam();
+  const display::Display::Rotation policy_rotation = GetParam();
 
   // Check that the policy rotation is restored.
   EXPECT_EQ(policy_rotation, GetRotationOfFirstDisplay());
@@ -325,9 +325,9 @@
 
 INSTANTIATE_TEST_CASE_P(PolicyDisplayRotationDefault,
                         DisplayRotationBootTest,
-                        testing::Values(gfx::Display::ROTATE_0,
-                                        gfx::Display::ROTATE_90,
-                                        gfx::Display::ROTATE_180,
-                                        gfx::Display::ROTATE_270));
+                        testing::Values(display::Display::ROTATE_0,
+                                        display::Display::ROTATE_90,
+                                        display::Display::ROTATE_180,
+                                        display::Display::ROTATE_270));
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/power/extension_event_observer_unittest.cc b/chrome/browser/chromeos/power/extension_event_observer_unittest.cc
index d5becf0..32782aa 100644
--- a/chrome/browser/chromeos/power/extension_event_observer_unittest.cc
+++ b/chrome/browser/chromeos/power/extension_event_observer_unittest.cc
@@ -34,7 +34,7 @@
 #include "extensions/common/value_builder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/aura/test/test_screen.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace chromeos {
 
@@ -65,7 +65,7 @@
   void SetUp() override {
     ::testing::Test::SetUp();
 
-    gfx::Screen::SetScreenInstance(test_screen_.get());
+    display::Screen::SetScreenInstance(test_screen_.get());
 
     // Must be called from ::testing::Test::SetUp.
     ASSERT_TRUE(profile_manager_->SetUp());
@@ -82,7 +82,7 @@
   void TearDown() override {
     profile_ = NULL;
     profile_manager_->DeleteAllTestingProfiles();
-    gfx::Screen::SetScreenInstance(nullptr);
+    display::Screen::SetScreenInstance(nullptr);
     ::testing::Test::TearDown();
   }
 
diff --git a/chrome/browser/chromeos/settings/owner_flags_storage.cc b/chrome/browser/chromeos/settings/owner_flags_storage.cc
index 3b1a836..8b52ea8 100644
--- a/chrome/browser/chromeos/settings/owner_flags_storage.cc
+++ b/chrome/browser/chromeos/settings/owner_flags_storage.cc
@@ -21,32 +21,7 @@
     PrefService* prefs,
     ownership::OwnerSettingsService* owner_settings_service)
     : flags_ui::PrefServiceFlagsStorage(prefs),
-      owner_settings_service_(owner_settings_service) {
-  // Make this code more unit test friendly.
-  if (g_browser_process->local_state()) {
-    const base::ListValue* legacy_experiments =
-        g_browser_process->local_state()->GetList(
-            flags_ui::prefs::kEnabledLabsExperiments);
-    if (!legacy_experiments->empty()) {
-      // If there are any flags set in local state migrate them to the owner's
-      // prefs and device settings.
-      std::set<std::string> flags;
-      for (base::ListValue::const_iterator it = legacy_experiments->begin();
-           it != legacy_experiments->end(); ++it) {
-        std::string experiment_name;
-        if (!(*it)->GetAsString(&experiment_name)) {
-          LOG(WARNING) << "Invalid entry in "
-                       << flags_ui::prefs::kEnabledLabsExperiments;
-          continue;
-        }
-        flags.insert(experiment_name);
-      }
-      SetFlags(flags);
-      g_browser_process->local_state()->ClearPref(
-          flags_ui::prefs::kEnabledLabsExperiments);
-    }
-  }
-}
+      owner_settings_service_(owner_settings_service) {}
 
 OwnerFlagsStorage::~OwnerFlagsStorage() {}
 
diff --git a/chrome/browser/chromeos/ui/accessibility_cursor_ring_layer.cc b/chrome/browser/chromeos/ui/accessibility_cursor_ring_layer.cc
index fe841c3..6d1d776 100644
--- a/chrome/browser/chromeos/ui/accessibility_cursor_ring_layer.cc
+++ b/chrome/browser/chromeos/ui/accessibility_cursor_ring_layer.cc
@@ -45,7 +45,8 @@
   int inset = kGradientWidth + kCursorRingRadius + kLayerMargin;
   bounds.Inset(-inset, -inset, -inset, -inset);
 
-  gfx::Display display = gfx::Screen::GetScreen()->GetDisplayMatching(bounds);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayMatching(bounds);
   aura::Window* root_window = ash::Shell::GetInstance()
                                   ->window_tree_host_manager()
                                   ->GetRootWindowForDisplayId(display.id());
diff --git a/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc b/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc
index 6cbad6e4..b41a0ea 100644
--- a/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc
+++ b/chrome/browser/chromeos/ui/accessibility_focus_ring_controller.cc
@@ -12,7 +12,7 @@
 #include "ash/shell.h"
 #include "base/logging.h"
 #include "chrome/browser/chromeos/ui/focus_ring_layer.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace chromeos {
 
@@ -106,7 +106,8 @@
 
 ui::Compositor* AccessibilityFocusRingController::CompositorForBounds(
     const gfx::Rect& bounds) {
-  gfx::Display display = gfx::Screen::GetScreen()->GetDisplayMatching(bounds);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayMatching(bounds);
   aura::Window* root_window = ash::Shell::GetInstance()
                                   ->window_tree_host_manager()
                                   ->GetRootWindowForDisplayId(display.id());
diff --git a/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc b/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc
index 8303aac..b03d026 100644
--- a/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc
+++ b/chrome/browser/chromeos/ui/accessibility_focus_ring_layer.cc
@@ -102,7 +102,8 @@
   int inset = kGradientWidth;
   bounds.Inset(-inset, -inset, -inset, -inset);
 
-  gfx::Display display = gfx::Screen::GetScreen()->GetDisplayMatching(bounds);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayMatching(bounds);
   aura::Window* root_window = ash::Shell::GetInstance()
                                   ->window_tree_host_manager()
                                   ->GetRootWindowForDisplayId(display.id());
diff --git a/chrome/browser/component_updater/origin_trials_component_installer.cc b/chrome/browser/component_updater/origin_trials_component_installer.cc
new file mode 100644
index 0000000..3ef12e9e
--- /dev/null
+++ b/chrome/browser/component_updater/origin_trials_component_installer.cc
@@ -0,0 +1,108 @@
+// 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/component_updater/origin_trials_component_installer.h"
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "chrome/common/chrome_switches.h"
+#include "components/component_updater/component_updater_paths.h"
+
+// The client-side configuration for the origin trial framework can be
+// overridden by an installed component named 'OriginTrials' (extension id
+// kfoklmclfodeliojeaekpoflbkkhojea. This component currently consists of just a
+// manifest.json file, which can contain a custom key named 'origin-trials'. The
+// value of this key is a dictionary:
+//
+// {
+//   "public-key": "<base64-encoding of replacement public key>",
+//   "disabled-features": [<list of features to disable>],
+//   "revoked-tokens": "<base64-encoded data>"
+// }
+//
+// TODO(iclelland): Implement support for revoked tokens and disabled features.
+//
+// If the component is not present in the user data directory, the default
+// configuration will be used.
+
+namespace component_updater {
+
+namespace {
+
+// Extension id is kfoklmclfodeliojeaekpoflbkkhojea
+const uint8_t kSha256Hash[] = {0xa5, 0xea, 0xbc, 0x2b, 0x5e, 0x34, 0xb8, 0xe9,
+                               0x40, 0x4a, 0xfe, 0x5b, 0x1a, 0xa7, 0xe9, 0x40,
+                               0xa8, 0xc5, 0xef, 0xa1, 0x9e, 0x20, 0x5a, 0x39,
+                               0x73, 0x98, 0x98, 0x0f, 0x7a, 0x76, 0x62, 0xfa};
+
+}  // namespace
+
+bool OriginTrialsComponentInstallerTraits::VerifyInstallation(
+    const base::DictionaryValue& manifest,
+    const base::FilePath& install_dir) const {
+  // Test if the "origin-trials" key is present in the manifest.
+  return manifest.HasKey("origin-trials");
+}
+
+bool OriginTrialsComponentInstallerTraits::CanAutoUpdate() const {
+  return true;
+}
+
+bool OriginTrialsComponentInstallerTraits::RequiresNetworkEncryption() const {
+  return true;
+}
+
+bool OriginTrialsComponentInstallerTraits::OnCustomInstall(
+    const base::DictionaryValue& manifest,
+    const base::FilePath& install_dir) {
+  return true;
+}
+
+void OriginTrialsComponentInstallerTraits::ComponentReady(
+    const base::Version& version,
+    const base::FilePath& install_dir,
+    std::unique_ptr<base::DictionaryValue> manifest) {
+  // Read the public key from the manifest and set the command line.
+  std::string override_public_key;
+  if (manifest->GetString("origin-trials.public-key", &override_public_key)) {
+    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+    command_line->AppendSwitchASCII(switches::kOriginTrialPublicKey,
+                                    override_public_key);
+  }
+}
+
+base::FilePath OriginTrialsComponentInstallerTraits::GetBaseDirectory() const {
+  base::FilePath result;
+  PathService::Get(DIR_ORIGIN_TRIAL_KEYS, &result);
+  return result;
+}
+
+void OriginTrialsComponentInstallerTraits::GetHash(
+    std::vector<uint8_t>* hash) const {
+  if (!hash)
+    return;
+  hash->assign(kSha256Hash, kSha256Hash + arraysize(kSha256Hash));
+}
+
+std::string OriginTrialsComponentInstallerTraits::GetName() const {
+  return "Origin Trials";
+}
+
+std::string OriginTrialsComponentInstallerTraits::GetAp() const {
+  return std::string();
+}
+
+void RegisterOriginTrialsComponent(ComponentUpdateService* cus,
+                                   const base::FilePath& user_data_dir) {
+  std::unique_ptr<ComponentInstallerTraits> traits(
+      new OriginTrialsComponentInstallerTraits());
+  // |cus| will take ownership of |installer| during installer->Register(cus).
+  DefaultComponentInstaller* installer =
+      new DefaultComponentInstaller(std::move(traits));
+  installer->Register(cus, base::Closure());
+}
+
+}  // namespace component_updater
diff --git a/chrome/browser/component_updater/origin_trials_component_installer.h b/chrome/browser/component_updater/origin_trials_component_installer.h
new file mode 100644
index 0000000..c097b21
--- /dev/null
+++ b/chrome/browser/component_updater/origin_trials_component_installer.h
@@ -0,0 +1,54 @@
+// 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_COMPONENT_UPDATER_ORIGIN_TRIALS_COMPONENT_INSTALLER_H_
+#define CHROME_BROWSER_COMPONENT_UPDATER_ORIGIN_TRIALS_COMPONENT_INSTALLER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "components/component_updater/default_component_installer.h"
+
+namespace component_updater {
+
+class ComponentUpdateService;
+
+class OriginTrialsComponentInstallerTraits : public ComponentInstallerTraits {
+ public:
+  OriginTrialsComponentInstallerTraits() = default;
+  ~OriginTrialsComponentInstallerTraits() override = default;
+
+ private:
+  bool VerifyInstallation(const base::DictionaryValue& manifest,
+                          const base::FilePath& install_dir) const override;
+  bool CanAutoUpdate() const override;
+  bool RequiresNetworkEncryption() const override;
+  bool OnCustomInstall(const base::DictionaryValue& manifest,
+                       const base::FilePath& install_dir) override;
+  void ComponentReady(const base::Version& version,
+                      const base::FilePath& install_dir,
+                      std::unique_ptr<base::DictionaryValue> manifest) override;
+  base::FilePath GetBaseDirectory() const override;
+  void GetHash(std::vector<uint8_t>* hash) const override;
+  std::string GetName() const override;
+  std::string GetAp() const override;
+
+  DISALLOW_COPY_AND_ASSIGN(OriginTrialsComponentInstallerTraits);
+};
+
+// Call once during startup to make the component update service aware of
+// the origin trials update component.
+void RegisterOriginTrialsComponent(ComponentUpdateService* cus,
+                                   const base::FilePath& user_data_dir);
+
+}  // namespace component_updater
+
+#endif  // CHROME_BROWSER_COMPONENT_UPDATER_ORIGIN_TRIALS_COMPONENT_INSTALLER_H_
diff --git a/chrome/browser/download/drag_download_item_views.cc b/chrome/browser/download/drag_download_item_views.cc
index ed618310..32ac0a1d 100644
--- a/chrome/browser/download/drag_download_item_views.cc
+++ b/chrome/browser/download/drag_download_item_views.cc
@@ -16,10 +16,10 @@
 #include "ui/base/dragdrop/drag_utils.h"
 #include "ui/base/dragdrop/file_info.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/widget/widget.h"
 #include "ui/wm/public/drag_drop_client.h"
 #include "url/gurl.h"
@@ -61,7 +61,7 @@
   if (!root_window || !aura::client::GetDragDropClient(root_window))
     return;
 
-  gfx::Point location = gfx::Screen::GetScreen()->GetCursorScreenPoint();
+  gfx::Point location = display::Screen::GetScreen()->GetCursorScreenPoint();
   // TODO(varunjain): Properly determine and send DRAG_EVENT_SOURCE below.
   aura::client::GetDragDropClient(root_window)->StartDragAndDrop(
       data,
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index 0c497e9..f25a5a5 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -735,6 +735,11 @@
   int64_t actual_file_size = -1;
   EXPECT_TRUE(base::GetFileSize(full_file_name, &actual_file_size));
   EXPECT_LE(kFileSizeMin, actual_file_size);
+
+  std::string contents;
+  EXPECT_TRUE(base::ReadFileToString(full_file_name, &contents));
+  // Test for a CSS encoded character.  This used to use HTML encoding.
+  EXPECT_THAT(contents, HasSubstr("content: \"\\e003 \\e004 b\""));
 }
 
 IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SavePageBrowserTest_NonMHTML) {
diff --git a/chrome/browser/extensions/display_info_provider_aura.cc b/chrome/browser/extensions/display_info_provider_aura.cc
index 99c3b37..640858d 100644
--- a/chrome/browser/extensions/display_info_provider_aura.cc
+++ b/chrome/browser/extensions/display_info_provider_aura.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/extensions/display_info_provider_aura.h"
 
 #include "base/logging.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace extensions {
 
@@ -24,7 +24,7 @@
 }
 
 void DisplayInfoProviderAura::UpdateDisplayUnitInfoForPlatform(
-    const gfx::Display& display,
+    const display::Display& display,
     extensions::api::system_display::DisplayUnitInfo* unit) {
   static bool logged_once = false;
   if (!logged_once) {
diff --git a/chrome/browser/extensions/display_info_provider_aura.h b/chrome/browser/extensions/display_info_provider_aura.h
index e2314ce4..0032af5 100644
--- a/chrome/browser/extensions/display_info_provider_aura.h
+++ b/chrome/browser/extensions/display_info_provider_aura.h
@@ -20,7 +20,7 @@
                const api::system_display::DisplayProperties& info,
                std::string* error) override;
   void UpdateDisplayUnitInfoForPlatform(
-      const gfx::Display& display,
+      const display::Display& display,
       api::system_display::DisplayUnitInfo* unit) override;
 
  private:
diff --git a/chrome/browser/extensions/display_info_provider_chromeos.cc b/chrome/browser/extensions/display_info_provider_chromeos.cc
index f35c6cc..486c0d7 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/display_info_provider_chromeos.cc
@@ -13,8 +13,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/chromeos/display/display_preferences.h"
 #include "extensions/common/api/system_display.h"
+#include "ui/display/display.h"
 #include "ui/display/manager/display_layout.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -36,19 +36,19 @@
 }
 
 // Converts integer integer value in degrees to Rotation enum value.
-gfx::Display::Rotation DegreesToRotation(int degrees) {
+display::Display::Rotation DegreesToRotation(int degrees) {
   DCHECK(IsValidRotationValue(degrees));
   switch (degrees) {
     case 0:
-      return gfx::Display::ROTATE_0;
+      return display::Display::ROTATE_0;
     case 90:
-      return gfx::Display::ROTATE_90;
+      return display::Display::ROTATE_90;
     case 180:
-      return gfx::Display::ROTATE_180;
+      return display::Display::ROTATE_180;
     case 270:
-      return gfx::Display::ROTATE_270;
+      return display::Display::ROTATE_270;
     default:
-      return gfx::Display::ROTATE_0;
+      return display::Display::ROTATE_0;
   }
 }
 
@@ -184,7 +184,7 @@
 // Returns whether the parameters are valid. On failure |error| is set to the
 // error message.
 bool ValidateParamsForDisplay(const DisplayProperties& info,
-                              const gfx::Display& display,
+                              const display::Display& display,
                               ash::DisplayManager* display_manager,
                               int64_t primary_display_id,
                               std::string* error) {
@@ -198,7 +198,7 @@
     int64_t mirroring_id;
     if (!base::StringToInt64(*info.mirroring_source_id, &mirroring_id) ||
         display_manager->GetDisplayForId(mirroring_id).id() ==
-            gfx::Display::kInvalidDisplayID) {
+            display::Display::kInvalidDisplayID) {
       *error = "Display " + *info.mirroring_source_id + " not found.";
       return false;
     }
@@ -299,7 +299,7 @@
       return false;
     }
 
-    if (!gfx::Display::IsInternalDisplayId(id)) {
+    if (!display::Display::IsInternalDisplayId(id)) {
       // For external displays, show a notification confirming the resolution
       // change.
       ash::Shell::GetInstance()
@@ -312,12 +312,12 @@
 }
 
 // Gets the display with the provided string id.
-gfx::Display GetTargetDisplay(const std::string& display_id_str,
-                              ash::DisplayManager* manager) {
+display::Display GetTargetDisplay(const std::string& display_id_str,
+                                  ash::DisplayManager* manager) {
   int64_t display_id;
   if (!base::StringToInt64(display_id_str, &display_id)) {
     // This should return invalid display.
-    return gfx::Display();
+    return display::Display();
   }
   return manager->GetDisplayForId(display_id);
 }
@@ -328,8 +328,8 @@
     const ash::DisplayMode& display_mode) {
   extensions::api::system_display::DisplayMode result;
 
-  bool is_internal = gfx::Display::HasInternalDisplay() &&
-                     gfx::Display::InternalDisplayId() == display_info.id();
+  bool is_internal = display::Display::HasInternalDisplay() &&
+                     display::Display::InternalDisplayId() == display_info.id();
   gfx::Size size_dip = display_mode.GetSizeInDIP(is_internal);
   result.width = size_dip.width();
   result.height = size_dip.height();
@@ -359,15 +359,17 @@
   ash::DisplayConfigurationController* display_configuration_controller =
       ash::Shell::GetInstance()->display_configuration_controller();
 
-  const gfx::Display target = GetTargetDisplay(display_id_str, display_manager);
+  const display::Display target =
+      GetTargetDisplay(display_id_str, display_manager);
 
-  if (target.id() == gfx::Display::kInvalidDisplayID) {
+  if (target.id() == display::Display::kInvalidDisplayID) {
     *error = "Display not found.";
     return false;
   }
 
   int64_t display_id = target.id();
-  const gfx::Display& primary = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+  const display::Display& primary =
+      display::Screen::GetScreen()->GetPrimaryDisplay();
 
   if (!ValidateParamsForDisplay(
           info, target, display_manager, primary.id(), error)) {
@@ -400,7 +402,7 @@
   if (info.rotation) {
     display_configuration_controller->SetDisplayRotation(
         display_id, DegreesToRotation(*info.rotation),
-        gfx::Display::ROTATION_SOURCE_ACTIVE, true /* user_action */);
+        display::Display::ROTATION_SOURCE_ACTIVE, true /* user_action */);
   }
 
   // Process new display origin parameters.
@@ -422,7 +424,7 @@
 }
 
 void DisplayInfoProviderChromeOS::UpdateDisplayUnitInfoForPlatform(
-    const gfx::Display& display,
+    const display::Display& display,
     extensions::api::system_display::DisplayUnitInfo* unit) {
   ash::DisplayManager* display_manager =
       ash::Shell::GetInstance()->display_manager();
@@ -464,14 +466,14 @@
   if (!display_manager->IsInUnifiedMode())
     return DisplayInfoProvider::GetAllDisplaysInfo();
 
-  std::vector<gfx::Display> displays =
+  std::vector<display::Display> displays =
       display_manager->software_mirroring_display_list();
   CHECK_GT(displays.size(), 0u);
 
   // Use first display as primary.
   int64_t primary_id = displays[0].id();
   DisplayUnitInfoList all_displays;
-  for (const gfx::Display& display : displays) {
+  for (const display::Display& display : displays) {
     api::system_display::DisplayUnitInfo unit =
         CreateDisplayUnitInfo(display, primary_id);
     UpdateDisplayUnitInfoForPlatform(display, &unit);
diff --git a/chrome/browser/extensions/display_info_provider_chromeos.h b/chrome/browser/extensions/display_info_provider_chromeos.h
index 51f83c5..5db2116d 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos.h
+++ b/chrome/browser/extensions/display_info_provider_chromeos.h
@@ -20,7 +20,7 @@
                const api::system_display::DisplayProperties& info,
                std::string* error) override;
   void UpdateDisplayUnitInfoForPlatform(
-      const gfx::Display& display,
+      const display::Display& display,
       api::system_display::DisplayUnitInfo* unit) override;
   void EnableUnifiedDesktop(bool enable) override;
   DisplayUnitInfoList GetAllDisplaysInfo() override;
diff --git a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
index 67b4baa..f9ee301e 100644
--- a/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
+++ b/chrome/browser/extensions/display_info_provider_chromeos_unittest.cc
@@ -19,8 +19,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "extensions/common/api/system_display.h"
+#include "ui/display/display.h"
 #include "ui/display/manager/display_layout.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace extensions {
@@ -50,9 +50,9 @@
   }
 
   bool DisplayExists(int64_t display_id) const {
-    const gfx::Display& display =
+    const display::Display& display =
         GetDisplayManager()->GetDisplayForId(display_id);
-    return display.id() != gfx::Display::kInvalidDisplayID;
+    return display.id() != display::Display::kInvalidDisplayID;
   }
 
   ash::DisplayManager* GetDisplayManager() const {
@@ -242,8 +242,9 @@
   EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0].bounds));
   EXPECT_EQ(90, result[0].rotation);
 
-  GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_270,
-                                          gfx::Display::ROTATION_SOURCE_ACTIVE);
+  GetDisplayManager()->SetDisplayRotation(
+      display_id, display::Display::ROTATE_270,
+      display::Display::ROTATION_SOURCE_ACTIVE);
 
   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
 
@@ -253,8 +254,9 @@
   EXPECT_EQ("0,0 600x500", SystemInfoDisplayBoundsToString(result[0].bounds));
   EXPECT_EQ(270, result[0].rotation);
 
-  GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_180,
-                                          gfx::Display::ROTATION_SOURCE_ACTIVE);
+  GetDisplayManager()->SetDisplayRotation(
+      display_id, display::Display::ROTATE_180,
+      display::Display::ROTATION_SOURCE_ACTIVE);
 
   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
 
@@ -264,8 +266,9 @@
   EXPECT_EQ("0,0 500x600", SystemInfoDisplayBoundsToString(result[0].bounds));
   EXPECT_EQ(180, result[0].rotation);
 
-  GetDisplayManager()->SetDisplayRotation(display_id, gfx::Display::ROTATE_0,
-                                          gfx::Display::ROTATION_SOURCE_ACTIVE);
+  GetDisplayManager()->SetDisplayRotation(
+      display_id, display::Display::ROTATE_0,
+      display::Display::ROTATION_SOURCE_ACTIVE);
 
   result = DisplayInfoProvider::Get()->GetAllDisplaysInfo();
 
@@ -434,7 +437,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftExact) {
   UpdateDisplay("1200x600,520x400");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(-520));
   info.bounds_origin_y.reset(new int(50));
@@ -453,7 +456,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightExact) {
   UpdateDisplay("1200x600,520x400");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(1200));
   info.bounds_origin_y.reset(new int(100));
@@ -472,7 +475,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopExact) {
   UpdateDisplay("1200x600,520x400");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(1100));
   info.bounds_origin_y.reset(new int(-400));
@@ -491,7 +494,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginBottomExact) {
   UpdateDisplay("1200x600,520x400");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(-350));
   info.bounds_origin_y.reset(new int(600));
@@ -510,7 +513,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSameCenter) {
   UpdateDisplay("1200x600,520x400");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(340));
   info.bounds_origin_y.reset(new int(100));
@@ -529,7 +532,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftOutside) {
   UpdateDisplay("1200x600,520x400");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(-1040));
   info.bounds_origin_y.reset(new int(100));
@@ -548,7 +551,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopOutside) {
   UpdateDisplay("1200x600,520x400");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(-360));
   info.bounds_origin_y.reset(new int(-301));
@@ -568,7 +571,7 @@
        SetBoundsOriginLeftButSharesBottomSide) {
   UpdateDisplay("1200x600,1000x100");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(-650));
   info.bounds_origin_y.reset(new int(700));
@@ -587,7 +590,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightButSharesTopSide) {
   UpdateDisplay("1200x600,1000x100");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(850));
   info.bounds_origin_y.reset(new int(-150));
@@ -606,7 +609,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopButSharesLeftSide) {
   UpdateDisplay("1200x600,1000x100/l");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(-150));
   info.bounds_origin_y.reset(new int(-650));
@@ -626,7 +629,7 @@
        SetBoundsOriginBottomButSharesRightSide) {
   UpdateDisplay("1200x600,1000x100/l");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(1350));
   info.bounds_origin_y.reset(new int(450));
@@ -645,7 +648,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginPrimaryHiDPI) {
   UpdateDisplay("1200x600*2,500x500");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(250));
   info.bounds_origin_y.reset(new int(-100));
@@ -664,7 +667,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSecondaryHiDPI) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(450));
   info.bounds_origin_y.reset(new int(-100));
@@ -683,7 +686,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBounds) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(0x200001));
   info.bounds_origin_y.reset(new int(-100));
@@ -702,7 +705,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBoundsNegative) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(300));
   info.bounds_origin_y.reset(new int(-0x200001));
@@ -721,7 +724,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginMaxValues) {
   UpdateDisplay("1200x4600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(200000));
   info.bounds_origin_y.reset(new int(10));
@@ -740,7 +743,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOnPrimary) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(300));
   info.is_primary.reset(new bool(true));
@@ -756,14 +759,16 @@
   EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
   // The operation failed because the primary property would be set before
   // setting bounds. The primary display shouldn't have been changed, though.
-  EXPECT_NE(gfx::Screen::GetScreen()->GetPrimaryDisplay().id(), secondary.id());
+  EXPECT_NE(display::Screen::GetScreen()->GetPrimaryDisplay().id(),
+            secondary.id());
 }
 
 TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginWithMirroring) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
-  const gfx::Display& primary = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& primary =
+      display::Screen::GetScreen()->GetPrimaryDisplay();
 
   api::system_display::DisplayProperties info;
   info.bounds_origin_x.reset(new int(300));
@@ -783,7 +788,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetRotation) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.rotation.reset(new int(90));
 
@@ -796,7 +801,7 @@
   EXPECT_TRUE(error.empty());
 
   EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
-  EXPECT_EQ(gfx::Display::ROTATE_90, secondary.rotation());
+  EXPECT_EQ(display::Display::ROTATE_90, secondary.rotation());
 
   info.rotation.reset(new int(270));
   CallSetDisplayUnitInfo(
@@ -806,7 +811,7 @@
   EXPECT_TRUE(error.empty());
 
   EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
-  EXPECT_EQ(gfx::Display::ROTATE_270, secondary.rotation());
+  EXPECT_EQ(display::Display::ROTATE_270, secondary.rotation());
 
   info.rotation.reset(new int(180));
   // Switch primary display.
@@ -818,8 +823,9 @@
   EXPECT_TRUE(error.empty());
 
   EXPECT_EQ("0,0 300x500", secondary.bounds().ToString());
-  EXPECT_EQ(gfx::Display::ROTATE_180, secondary.rotation());
-  EXPECT_EQ(gfx::Screen::GetScreen()->GetPrimaryDisplay().id(), secondary.id());
+  EXPECT_EQ(display::Display::ROTATE_180, secondary.rotation());
+  EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().id(),
+            secondary.id());
 
   info.rotation.reset(new int(0));
   CallSetDisplayUnitInfo(
@@ -829,8 +835,9 @@
   EXPECT_TRUE(error.empty());
 
   EXPECT_EQ("0,0 300x500", secondary.bounds().ToString());
-  EXPECT_EQ(gfx::Display::ROTATE_0, secondary.rotation());
-  EXPECT_EQ(gfx::Screen::GetScreen()->GetPrimaryDisplay().id(), secondary.id());
+  EXPECT_EQ(display::Display::ROTATE_0, secondary.rotation());
+  EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().id(),
+            secondary.id());
 }
 
 // Tests that rotation changes made before entering maximize mode are restored
@@ -843,8 +850,9 @@
 
   bool success = false;
   std::string error;
-  CallSetDisplayUnitInfo(base::Int64ToString(gfx::Display::InternalDisplayId()),
-                         info, &success, &error);
+  CallSetDisplayUnitInfo(
+      base::Int64ToString(display::Display::InternalDisplayId()), info,
+      &success, &error);
 
   ASSERT_TRUE(success);
   EXPECT_TRUE(error.empty());
@@ -860,14 +868,14 @@
 
   // ScreenOrientationController rotations override display info.
   screen_orientation_controller->SetDisplayRotation(
-      gfx::Display::ROTATE_0, gfx::Display::ROTATION_SOURCE_ACTIVE);
-  EXPECT_EQ(gfx::Display::ROTATE_0, GetCurrentInternalDisplayRotation());
+      display::Display::ROTATE_0, display::Display::ROTATION_SOURCE_ACTIVE);
+  EXPECT_EQ(display::Display::ROTATE_0, GetCurrentInternalDisplayRotation());
 
   // Exiting maximize mode should restore the initial rotation
   ash::Shell::GetInstance()
       ->maximize_mode_controller()
       ->EnableMaximizeModeWindowManager(false);
-  EXPECT_EQ(gfx::Display::ROTATE_90, GetCurrentInternalDisplayRotation());
+  EXPECT_EQ(display::Display::ROTATE_90, GetCurrentInternalDisplayRotation());
 }
 
 // Tests that rotation changes made during maximize mode lock the display
@@ -887,8 +895,9 @@
 
   bool success = false;
   std::string error;
-  CallSetDisplayUnitInfo(base::Int64ToString(gfx::Display::InternalDisplayId()),
-                         info, &success, &error);
+  CallSetDisplayUnitInfo(
+      base::Int64ToString(display::Display::InternalDisplayId()), info,
+      &success, &error);
 
   ASSERT_TRUE(success);
   EXPECT_TRUE(error.empty());
@@ -900,7 +909,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetInvalidRotation) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.rotation.reset(new int(91));
 
@@ -916,7 +925,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetNegativeOverscan) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.overscan.reset(new api::system_display::Insets);
   info.overscan->left = -10;
@@ -979,7 +988,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanHorizontalBounds) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.overscan.reset(new api::system_display::Insets);
   // Horizontal overscan is 151, which would make the bounds width 149.
@@ -1001,7 +1010,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanVerticalBounds) {
   UpdateDisplay("1200x600,600x1000");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.overscan.reset(new api::system_display::Insets);
   // Vertical overscan is 501, which would make the bounds height 499.
@@ -1022,7 +1031,7 @@
 TEST_F(DisplayInfoProviderChromeosTest, SetOverscan) {
   UpdateDisplay("1200x600,600x1000*2");
 
-  const gfx::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
+  const display::Display& secondary = ash::ScreenUtil::GetSecondaryDisplay();
   api::system_display::DisplayProperties info;
   info.overscan.reset(new api::system_display::Insets);
   info.overscan->left = 20;
diff --git a/chrome/browser/extensions/display_info_provider_mac.cc b/chrome/browser/extensions/display_info_provider_mac.cc
index f998c70..3eb0db9 100644
--- a/chrome/browser/extensions/display_info_provider_mac.cc
+++ b/chrome/browser/extensions/display_info_provider_mac.cc
@@ -23,7 +23,7 @@
 }
 
 void DisplayInfoProviderMac::UpdateDisplayUnitInfoForPlatform(
-    const gfx::Display& display,
+    const display::Display& display,
     extensions::api::system_display::DisplayUnitInfo* unit) {
   static bool logged_once = false;
   if (!logged_once) {
diff --git a/chrome/browser/extensions/display_info_provider_mac.h b/chrome/browser/extensions/display_info_provider_mac.h
index edae287..b7b6e05 100644
--- a/chrome/browser/extensions/display_info_provider_mac.h
+++ b/chrome/browser/extensions/display_info_provider_mac.h
@@ -20,7 +20,7 @@
                const api::system_display::DisplayProperties& info,
                std::string* error) override;
   void UpdateDisplayUnitInfoForPlatform(
-      const gfx::Display& display,
+      const display::Display& display,
       api::system_display::DisplayUnitInfo* unit) override;
 
  private:
diff --git a/chrome/browser/extensions/display_info_provider_win.cc b/chrome/browser/extensions/display_info_provider_win.cc
index f4e32d1..4da5ae2a 100644
--- a/chrome/browser/extensions/display_info_provider_win.cc
+++ b/chrome/browser/extensions/display_info_provider_win.cc
@@ -12,8 +12,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/win_util.h"
 #include "extensions/common/api/system_display.h"
+#include "ui/display/display.h"
 #include "ui/display/win/dpi.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace extensions {
@@ -65,7 +65,7 @@
 }
 
 void DisplayInfoProviderWin::UpdateDisplayUnitInfoForPlatform(
-    const gfx::Display& display,
+    const display::Display& display,
     extensions::api::system_display::DisplayUnitInfo* unit) {
   DisplayUnitInfoList all_displays;
   EnumDisplayMonitors(
diff --git a/chrome/browser/extensions/display_info_provider_win.h b/chrome/browser/extensions/display_info_provider_win.h
index 41abed3..aab7f5c 100644
--- a/chrome/browser/extensions/display_info_provider_win.h
+++ b/chrome/browser/extensions/display_info_provider_win.h
@@ -20,7 +20,7 @@
                const api::system_display::DisplayProperties& info,
                std::string* error) override;
   void UpdateDisplayUnitInfoForPlatform(
-      const gfx::Display& display,
+      const display::Display& display,
       api::system_display::DisplayUnitInfo* unit) override;
 
  private:
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 99a914c8..0351b5c 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -61,9 +61,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/user_agent.h"
-#include "net/base/external_estimate_provider.h"
 #include "net/base/host_mapping_rules.h"
-#include "net/base/network_quality_estimator.h"
 #include "net/base/sdch_manager.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert/cert_verify_proc.h"
@@ -83,6 +81,8 @@
 #include "net/http/http_auth_preferences.h"
 #include "net/http/http_network_layer.h"
 #include "net/http/http_server_properties_impl.h"
+#include "net/nqe/external_estimate_provider.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_config_service.h"
 #include "net/proxy/proxy_script_fetcher_impl.h"
 #include "net/proxy/proxy_service.h"
@@ -1252,7 +1252,6 @@
     if (receive_buffer_size != 0) {
       params->quic_socket_receive_buffer_size = receive_buffer_size;
     }
-    params->quic_delay_tcp_race = ShouldQuicDelayTcpRace(quic_trial_params);
     float load_server_info_timeout_srtt_multiplier =
         GetQuicLoadServerInfoTimeoutSrttMultiplier(quic_trial_params);
     if (load_server_info_timeout_srtt_multiplier != 0) {
@@ -1522,13 +1521,6 @@
 }
 
 // static
-bool IOThread::NetworkSessionConfigurator::ShouldQuicDelayTcpRace(
-    const VariationParameters& quic_trial_params) {
-  return base::LowerCaseEqualsASCII(
-      GetVariationParam(quic_trial_params, "delay_tcp_race"), "true");
-}
-
-// static
 bool IOThread::NetworkSessionConfigurator::ShouldQuicCloseSessionsOnIpChange(
     const VariationParameters& quic_trial_params) {
   return base::LowerCaseEqualsASCII(
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 7a3fdada..2922a2b 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -338,10 +338,6 @@
     static int GetQuicSocketReceiveBufferSize(
         const VariationParameters& quic_trial_params);
 
-    // Returns true if QUIC should delay TCP connection when QUIC works.
-    static bool ShouldQuicDelayTcpRace(
-        const VariationParameters& quic_trial_params);
-
     // Returns true if QUIC should close sessions when any of the client's IP
     // addresses change.
     static bool ShouldQuicCloseSessionsOnIpChange(
diff --git a/chrome/browser/io_thread_unittest.cc b/chrome/browser/io_thread_unittest.cc
index c1bfd0f..d6a37e92 100644
--- a/chrome/browser/io_thread_unittest.cc
+++ b/chrome/browser/io_thread_unittest.cc
@@ -255,7 +255,6 @@
   EXPECT_FALSE(params_.enable_alternative_service_with_different_host);
   EXPECT_EQ(0, params_.quic_max_number_of_lossy_connections);
   EXPECT_EQ(1.0f, params_.quic_packet_loss_threshold);
-  EXPECT_FALSE(params_.quic_delay_tcp_race);
   EXPECT_FALSE(params_.quic_close_sessions_on_ip_change);
   EXPECT_EQ(net::kIdleConnectionTimeoutSeconds,
             params_.quic_idle_connection_timeout_seconds);
@@ -627,17 +626,6 @@
   EXPECT_EQ(2097152, params_.quic_socket_receive_buffer_size);
 }
 
-TEST_F(NetworkSessionConfiguratorTest, QuicDelayTcpConnection) {
-  std::map<std::string, std::string> field_trial_params;
-  field_trial_params["delay_tcp_race"] = "true";
-  variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
-  base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
-
-  ParseFieldTrials();
-
-  EXPECT_TRUE(params_.quic_delay_tcp_race);
-}
-
 TEST_F(NetworkSessionConfiguratorTest, QuicOriginsToForceQuicOn) {
   base::CommandLine::ForCurrentProcess()->AppendSwitch("enable-quic");
   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
diff --git a/chrome/browser/manifest/manifest_icon_downloader.cc b/chrome/browser/manifest/manifest_icon_downloader.cc
index 3f9eb8b..abc3e388 100644
--- a/chrome/browser/manifest/manifest_icon_downloader.cc
+++ b/chrome/browser/manifest/manifest_icon_downloader.cc
@@ -15,7 +15,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/console_message_level.h"
 #include "skia/ext/image_operations.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 // DevToolsConsoleHelper is a class that holds a WebContents in order to be able
 // to send a message to the WebContents' main frame. It is used so
@@ -56,7 +56,7 @@
     return false;
 
   const float device_scale_factor =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
   const int ideal_icon_size_in_px =
       static_cast<int>(round(ideal_icon_size_in_dp * device_scale_factor));
   const int minimum_icon_size_in_px =
diff --git a/chrome/browser/manifest/manifest_icon_selector.cc b/chrome/browser/manifest/manifest_icon_selector.cc
index adf037b..0a3592df 100644
--- a/chrome/browser/manifest/manifest_icon_selector.cc
+++ b/chrome/browser/manifest/manifest_icon_selector.cc
@@ -13,7 +13,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "components/mime_util/mime_util.h"
 #include "content/public/browser/web_contents.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 using content::Manifest;
 
@@ -154,5 +154,5 @@
 int ManifestIconSelector::ConvertIconSizeFromDpToPx(int icon_size_in_dp) {
   return static_cast<int>(round(
       icon_size_in_dp *
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor()));
+      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor()));
 }
diff --git a/chrome/browser/manifest/manifest_icon_selector_unittest.cc b/chrome/browser/manifest/manifest_icon_selector_unittest.cc
index 685574c..8d2d3ce 100644
--- a/chrome/browser/manifest/manifest_icon_selector_unittest.cc
+++ b/chrome/browser/manifest/manifest_icon_selector_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/test/test_screen.h"
 
 namespace {
@@ -22,11 +22,11 @@
   ManifestIconSelectorTest() {
     test_screen_.display()->set_id(0x1337);
     test_screen_.display()->set_bounds(gfx::Rect(0, 0, 2560, 1440));
-    gfx::Screen::SetScreenInstance(&test_screen_);
+    display::Screen::SetScreenInstance(&test_screen_);
   }
 
   ~ManifestIconSelectorTest() override {
-    gfx::Screen::SetScreenInstance(nullptr);
+    display::Screen::SetScreenInstance(nullptr);
   }
 
   void SetUp() override {
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index 58f4af4a..4c343f2 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -25,8 +25,8 @@
 #include "content/public/browser/browser_thread.h"
 #include "ui/base/touch/touch_device.h"
 #include "ui/base/ui_base_switches.h"
+#include "ui/display/screen.h"
 #include "ui/events/event_switches.h"
-#include "ui/gfx/screen.h"
 
 #if !defined(OS_ANDROID)
 #include "chrome/browser/metrics/first_web_contents_profiler.h"
@@ -310,7 +310,7 @@
 
 ChromeBrowserMainExtraPartsMetrics::~ChromeBrowserMainExtraPartsMetrics() {
   if (is_screen_observer_)
-    gfx::Screen::GetScreen()->RemoveObserver(this);
+    display::Screen::GetScreen()->RemoveObserver(this);
 }
 
 void ChromeBrowserMainExtraPartsMetrics::PreProfileInit() {
@@ -355,9 +355,9 @@
       base::Bind(&RecordStartupMetricsOnBlockingPool),
       base::TimeDelta::FromSeconds(kStartupMetricsGatheringDelaySeconds));
 
-  display_count_ = gfx::Screen::GetScreen()->GetNumDisplays();
+  display_count_ = display::Screen::GetScreen()->GetNumDisplays();
   UMA_HISTOGRAM_COUNTS_100("Hardware.Display.Count.OnStartup", display_count_);
-  gfx::Screen::GetScreen()->AddObserver(this);
+  display::Screen::GetScreen()->AddObserver(this);
   is_screen_observer_ = true;
 
 #if !defined(OS_ANDROID)
@@ -366,22 +366,21 @@
 }
 
 void ChromeBrowserMainExtraPartsMetrics::OnDisplayAdded(
-    const gfx::Display& new_display) {
+    const display::Display& new_display) {
   EmitDisplaysChangedMetric();
 }
 
 void ChromeBrowserMainExtraPartsMetrics::OnDisplayRemoved(
-    const gfx::Display& old_display) {
+    const display::Display& old_display) {
   EmitDisplaysChangedMetric();
 }
 
 void ChromeBrowserMainExtraPartsMetrics::OnDisplayMetricsChanged(
-    const gfx::Display& display,
-    uint32_t changed_metrics) {
-}
+    const display::Display& display,
+    uint32_t changed_metrics) {}
 
 void ChromeBrowserMainExtraPartsMetrics::EmitDisplaysChangedMetric() {
-  int display_count = gfx::Screen::GetScreen()->GetNumDisplays();
+  int display_count = display::Screen::GetScreen()->GetNumDisplays();
   if (display_count != display_count_) {
     display_count_ = display_count;
     UMA_HISTOGRAM_COUNTS_100("Hardware.Display.Count.OnChange", display_count_);
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h
index f8c4bf7a..521a883 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h
@@ -13,7 +13,7 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "chrome/browser/chrome_browser_main_extra_parts.h"
-#include "ui/gfx/display_observer.h"
+#include "ui/display/display_observer.h"
 
 class ChromeBrowserMainParts;
 
@@ -25,9 +25,8 @@
 class InputDeviceEventObserver;
 }  // namespace ui
 
-class ChromeBrowserMainExtraPartsMetrics
-    : public ChromeBrowserMainExtraParts,
-      public gfx::DisplayObserver {
+class ChromeBrowserMainExtraPartsMetrics : public ChromeBrowserMainExtraParts,
+                                           public display::DisplayObserver {
  public:
   ChromeBrowserMainExtraPartsMetrics();
   ~ChromeBrowserMainExtraPartsMetrics() override;
@@ -44,9 +43,9 @@
 #endif  // defined(OS_MACOSX)
 
   // DisplayObserver overrides.
-  void OnDisplayAdded(const gfx::Display& new_display) override;
-  void OnDisplayRemoved(const gfx::Display& old_display) override;
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  void OnDisplayAdded(const display::Display& new_display) override;
+  void OnDisplayRemoved(const display::Display& old_display) override;
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override;
 
   // If the number of displays has changed, emit a UMA metric.
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
index 27ba4bb..b65c6fa 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc
@@ -10,9 +10,9 @@
 #include "base/message_loop/message_loop.h"
 #include "base/test/histogram_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/screen.h"
 #include "ui/events/test/device_data_manager_test_api.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/test/test_screen.h"
 
 namespace {
@@ -43,12 +43,12 @@
 
 ChromeBrowserMainExtraPartsMetricsTest::ChromeBrowserMainExtraPartsMetricsTest()
     : device_data_manager_test_api_() {
-  gfx::Screen::SetScreenInstance(&test_screen_);
+  display::Screen::SetScreenInstance(&test_screen_);
 }
 
 ChromeBrowserMainExtraPartsMetricsTest::
     ~ChromeBrowserMainExtraPartsMetricsTest() {
-  gfx::Screen::SetScreenInstance(nullptr);
+  display::Screen::SetScreenInstance(nullptr);
 }
 
 // Verify a TouchEventsEnabled value isn't recorded during construction.
diff --git a/chrome/browser/metrics/chromeos_metrics_provider.cc b/chrome/browser/metrics/chromeos_metrics_provider.cc
index a3b2e385..c63f9e1 100644
--- a/chrome/browser/metrics/chromeos_metrics_provider.cc
+++ b/chrome/browser/metrics/chromeos_metrics_provider.cc
@@ -25,8 +25,8 @@
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
+#include "ui/display/display.h"
 #include "ui/events/event_utils.h"
-#include "ui/gfx/screen.h"
 
 #if defined(USE_X11)
 #include "ui/events/devices/x11/touch_factory_x11.h"
@@ -196,10 +196,11 @@
   metrics::SystemProfileProto::Hardware* hardware =
       system_profile_proto->mutable_hardware();
   hardware->set_hardware_class(hardware_class_);
-  gfx::Display::TouchSupport has_touch = ui::GetInternalDisplayTouchSupport();
-  if (has_touch == gfx::Display::TOUCH_SUPPORT_AVAILABLE)
+  display::Display::TouchSupport has_touch =
+      ui::GetInternalDisplayTouchSupport();
+  if (has_touch == display::Display::TOUCH_SUPPORT_AVAILABLE)
     hardware->set_internal_display_supports_touch(true);
-  else if (has_touch == gfx::Display::TOUCH_SUPPORT_UNAVAILABLE)
+  else if (has_touch == display::Display::TOUCH_SUPPORT_UNAVAILABLE)
     hardware->set_internal_display_supports_touch(false);
   WriteExternalTouchscreensProto(hardware);
 }
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc
index ea20cee..a04cb13 100644
--- a/chrome/browser/net/predictor.cc
+++ b/chrome/browser/net/predictor.cc
@@ -16,7 +16,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/metrics/histogram.h"
-#include "base/profiler/scoped_tracker.h"
 #include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
 #include "base/strings/string_split.h"
diff --git a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc
index a55a924..dc2349a 100644
--- a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc
@@ -239,18 +239,25 @@
 }
 
 // static
-bool FromGWSPageLoadMetricsLogger::IsGoogleRedirectorUrl(const GURL& url) {
-  return IsGoogleSearchHostname(url.host_piece()) &&
-         url.path_piece() == "/url" && url.has_query();
-}
-
-// static
 bool FromGWSPageLoadMetricsLogger::IsGoogleSearchRedirectorUrl(
     const GURL& url) {
-  return IsGoogleRedirectorUrl(url) &&
-         // Google search result redirects are differentiated from other
-         // redirects by 'source=web'.
-         QueryContainsComponent(url.query_piece(), "source=web");
+  if (!IsGoogleSearchHostname(url.host_piece()))
+    return false;
+
+  // The primary search redirector.  Google search result redirects are
+  // differentiated from other general google redirects by 'source=web' in the
+  // query string.
+  if (url.path_piece() == "/url" && url.has_query() &&
+      QueryContainsComponent(url.query_piece(), "source=web")) {
+    return true;
+  }
+
+  // Intent-based navigations from search are redirected through a second
+  // redirector, which receives its redirect URL in the fragment/hash/ref
+  // portion of the URL (the portion after '#'). We don't check for the presence
+  // of certain params in the ref since this redirector is only used for
+  // redirects from search.
+  return url.path_piece() == "/searchurl/r.html" && url.has_ref();
 }
 
 // static
@@ -328,8 +335,9 @@
 }
 
 void FromGWSPageLoadMetricsLogger::SetProvisionalUrl(const GURL& url) {
-  provisional_url_is_search_results_or_google_redirector_ =
-      IsGoogleSearchResultUrl(url) || IsGoogleRedirectorUrl(url);
+  provisional_url_has_search_hostname_ =
+      IsGoogleSearchHostname(url.host_piece());
+  provisional_url_is_non_http_or_https_ = !url.SchemeIsHTTPOrHTTPS();
 }
 
 FromGWSPageLoadMetricsObserver::FromGWSPageLoadMetricsObserver() {}
@@ -345,10 +353,15 @@
     content::NavigationHandle* navigation_handle) {
   // We'd like to also check navigation_handle->HasUserGesture() here, however
   // this signal is not carried forward for navigations that open links in new
-  // tabs, so we look only at PAGE_TRANSITION_LINK.
+  // tabs, so we look only at PAGE_TRANSITION_LINK. Back/forward navigations
+  // that were originally navigated from a link will continue to report a core
+  // type of link, so to filter out back/forward navs, we also check that the
+  // page transition is a new navigation.
   logger_.set_navigation_initiated_via_link(
       ui::PageTransitionCoreTypeIs(navigation_handle->GetPageTransition(),
-                                   ui::PAGE_TRANSITION_LINK));
+                                   ui::PAGE_TRANSITION_LINK) &&
+      ui::PageTransitionIsNewNavigation(
+          navigation_handle->GetPageTransition()));
 }
 
 void FromGWSPageLoadMetricsObserver::OnComplete(
@@ -387,25 +400,31 @@
 }
 
 bool FromGWSPageLoadMetricsLogger::ShouldLogMetrics(const GURL& committed_url) {
-  // If this page is a known google redirector URL or Google search results URL,
-  // then we should not log stats. Use the provisional url if the navigation
-  // never commit. Note that this might throw away navigations to the Javascript
-  // redirector url.
+  // If this page has a URL on a known google search hostname, then it may be a
+  // page associated with search (either a search results page, or a search
+  // redirector url), so we should not log stats. We could try to detect only
+  // the specific known search URLs here, and log navigations to other pages on
+  // the google search hostname (for example, a search for 'about google'
+  // includes a result for https://www.google.com/about/), however, we assume
+  // these cases are relatively uncommon, and we run the risk of logging metrics
+  // for some search redirector URLs. Thus we choose the more conservative
+  // approach of ignoring all urls on known search hostnames. We use the
+  // provisional url if the navigation didn't commit. Also ignore navigations to
+  // other URL schemes, such as app navigations via intent://.
   if (committed_url.is_empty()) {
-    if (provisional_url_is_search_results_or_google_redirector_)
+    if (provisional_url_has_search_hostname_ ||
+        provisional_url_is_non_http_or_https_)
       return false;
   } else {
-    if (IsGoogleSearchResultUrl(committed_url) ||
-        IsGoogleRedirectorUrl(committed_url)) {
+    if (IsGoogleSearchHostname(committed_url.host_piece()) ||
+        !committed_url.SchemeIsHTTPOrHTTPS())
       return false;
-    }
   }
 
-  // We're only interested in tracking user gesture initiated navigations
-  // (e.g. clicks) initiated via links. Note that the redirector will mask
-  // these, so don't enforce this if the navigation came from a redirect url.
-  // TODO(csharrison): Use this signal for provisional loads when the content
-  // APIs allow for it.
+  // We're only interested in tracking navigations (e.g. clicks) initiated via
+  // links. Note that the redirector will mask these, so don't enforce this if
+  // the navigation came from a redirect url. TODO(csharrison): Use this signal
+  // for provisional loads when the content APIs allow for it.
   if (previously_committed_url_is_search_results_ &&
       (committed_url.is_empty() || navigation_initiated_via_link_)) {
     return true;
diff --git a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.h
index b00e965..e2f5c911 100644
--- a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.h
@@ -46,7 +46,6 @@
   // The methods below are public only for testing.
   static bool IsGoogleSearchHostname(base::StringPiece host);
   static bool IsGoogleSearchResultUrl(const GURL& url);
-  static bool IsGoogleRedirectorUrl(const GURL& url);
   static bool IsGoogleSearchRedirectorUrl(const GURL& url);
   bool ShouldLogMetrics(const GURL& url);
 
@@ -69,7 +68,8 @@
   bool previously_committed_url_is_search_results_ = false;
   bool previously_committed_url_is_search_redirector_ = false;
   bool navigation_initiated_via_link_ = false;
-  bool provisional_url_is_search_results_or_google_redirector_ = false;
+  bool provisional_url_has_search_hostname_ = false;
+  bool provisional_url_is_non_http_or_https_ = false;
 
   static bool IsUrlFromGWS(const GURL& url);
 
diff --git a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc
index a9a0ab2..6bf40fa 100644
--- a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc
@@ -575,30 +575,6 @@
   }
 }
 
-TEST_F(FromGWSPageLoadMetricsLoggerTest, IsGoogleRedirectorUrl) {
-  struct {
-    bool expected_result;
-    const char* url;
-  } test_cases[] = {
-      {true, "https://www.google.com/url?"},
-      {true, "https://www.google.com/url?a=b"},
-      {true, "https://www.google.com/url?source=web"},
-      {true, "https://www.google.com/url?a=b&source=web&c=d"},
-      {true, "https://www.google.co.uk/url?source=web"},
-      {false, "https://www.google.com/?"},
-      {false, "https://www.google.com/?url"},
-      {false, "https://www.example.com/url?source=web"},
-      {false, "https://google.com/url?"},
-      {false, "https://google.com/url?"},
-  };
-  for (const auto& test : test_cases) {
-    EXPECT_EQ(
-        test.expected_result,
-        FromGWSPageLoadMetricsLogger::IsGoogleRedirectorUrl(GURL(test.url)))
-        << "for URL: " << test.url;
-  }
-}
-
 TEST_F(FromGWSPageLoadMetricsLoggerTest, IsGoogleSearchRedirectorUrl) {
   struct {
     bool expected_result;
@@ -606,9 +582,17 @@
   } test_cases[] = {
       {true, "https://www.google.com/url?source=web"},
       {true, "https://www.google.com/url?source=web#foo"},
+      {true, "https://www.google.com/searchurl/r.html#foo"},
+      {true, "https://www.google.com/url?a=b&source=web&c=d"},
+      {false, "https://www.google.com/?"},
+      {false, "https://www.google.com/?url"},
+      {false, "https://www.example.com/url?source=web"},
+      {false, "https://google.com/url?"},
       {false, "https://www.google.com/?source=web"},
       {false, "https://www.google.com/source=web"},
       {false, "https://www.example.com/url?source=web"},
+      {false, "https://www.google.com/url?"},
+      {false, "https://www.google.com/url?a=b"},
   };
   for (const auto& test : test_cases) {
     EXPECT_EQ(test.expected_result,
@@ -705,37 +689,69 @@
 
 TEST_F(FromGWSPageLoadMetricsLoggerTest, NavigationNotInitiatedViaLink) {
   FromGWSPageLoadMetricsLogger logger;
-  logger.SetPreviouslyCommittedUrl(
-      GURL("https://www.google.com/search?q=test"));
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
   logger.set_navigation_initiated_via_link(false);
   ASSERT_FALSE(logger.ShouldLogMetrics(GURL(kExampleUrl)));
 }
 
-TEST_F(FromGWSPageLoadMetricsLoggerTest,
-       ProvisionalFromGWSNotInitiatedViaLink) {
+TEST_F(FromGWSPageLoadMetricsLoggerTest, ProvisionalNonHttpOrHttpsScheme) {
   FromGWSPageLoadMetricsLogger logger;
-  logger.SetProvisionalUrl(
-      GURL("https://www.google.com/search?q=test"));
-  logger.set_navigation_initiated_via_link(false);
-  ASSERT_FALSE(logger.ShouldLogMetrics(GURL(kExampleUrl)));
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
+  logger.SetProvisionalUrl(GURL("intent://foo"));
+  ASSERT_FALSE(logger.ShouldLogMetrics(GURL::EmptyGURL()));
 }
 
-TEST_F(FromGWSPageLoadMetricsLoggerTest,
-       ProvisionalNotFromGWSNotInitiatedViaLink) {
+TEST_F(FromGWSPageLoadMetricsLoggerTest, ProvisionalFromGWS) {
   FromGWSPageLoadMetricsLogger logger;
-  logger.SetProvisionalUrl(GURL("https://example.test/"));
-  logger.set_navigation_initiated_via_link(false);
-  ASSERT_FALSE(logger.ShouldLogMetrics(GURL(kExampleUrl)));
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
+  logger.SetProvisionalUrl(GURL(kGoogleSearchResultsUrl));
+  ASSERT_FALSE(logger.ShouldLogMetrics(GURL::EmptyGURL()));
+}
+
+TEST_F(FromGWSPageLoadMetricsLoggerTest, ProvisionalNotFromGWS) {
+  FromGWSPageLoadMetricsLogger logger;
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
+  logger.SetProvisionalUrl(GURL(kExampleUrl));
+  ASSERT_TRUE(logger.ShouldLogMetrics(GURL::EmptyGURL()));
+}
+
+TEST_F(FromGWSPageLoadMetricsLoggerTest, ProvisionalIntent) {
+  FromGWSPageLoadMetricsLogger logger;
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
+  logger.SetProvisionalUrl(GURL("intent://en.m.wikipedia.org/wiki/Test"));
+  ASSERT_FALSE(logger.ShouldLogMetrics(GURL::EmptyGURL()));
+}
+
+TEST_F(FromGWSPageLoadMetricsLoggerTest, ProvisionalIgnoredAfterCommit1) {
+  FromGWSPageLoadMetricsLogger logger;
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
+  logger.SetProvisionalUrl(GURL(kExampleUrl));
+  logger.set_navigation_initiated_via_link(true);
+  ASSERT_FALSE(logger.ShouldLogMetrics(GURL(kGoogleSearchResultsUrl)));
+}
+
+TEST_F(FromGWSPageLoadMetricsLoggerTest, ProvisionalIgnoredAfterCommit2) {
+  FromGWSPageLoadMetricsLogger logger;
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
+  logger.SetProvisionalUrl(GURL(kGoogleSearchResultsUrl));
+  logger.set_navigation_initiated_via_link(true);
+  ASSERT_TRUE(logger.ShouldLogMetrics(GURL(kExampleUrl)));
 }
 
 TEST_F(FromGWSPageLoadMetricsLoggerTest, NavigationFromSearch) {
   FromGWSPageLoadMetricsLogger logger;
-  logger.SetPreviouslyCommittedUrl(
-      GURL("https://www.google.com/search?q=test"));
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
   logger.set_navigation_initiated_via_link(true);
   ASSERT_TRUE(logger.ShouldLogMetrics(GURL(kExampleUrl)));
 }
 
+TEST_F(FromGWSPageLoadMetricsLoggerTest, NavigationToSearchHostname) {
+  FromGWSPageLoadMetricsLogger logger;
+  logger.SetPreviouslyCommittedUrl(GURL(kGoogleSearchResultsUrl));
+  logger.set_navigation_initiated_via_link(true);
+  ASSERT_FALSE(logger.ShouldLogMetrics(GURL("https://www.google.com/about/")));
+}
+
 TEST_F(FromGWSPageLoadMetricsLoggerTest, NavigationFromSearchRedirector) {
   FromGWSPageLoadMetricsLogger logger;
   logger.SetPreviouslyCommittedUrl(
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc
index eea06a4..bad0233 100644
--- a/chrome/browser/permissions/permission_manager.cc
+++ b/chrome/browser/permissions/permission_manager.cc
@@ -32,10 +32,6 @@
 #include "chrome/browser/media/protected_media_identifier_permission_context.h"
 #endif
 
-#if !defined(OS_ANDROID)
-#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
-#endif
-
 #if BUILDFLAG(ANDROID_JAVA_UI)
 #include "chrome/browser/geolocation/geolocation_permission_context_android.h"
 #else
@@ -296,7 +292,6 @@
     const PermissionType permission = permissions[i];
 
     if (IsConstantPermission(permission) ||
-        IsPermissionBubbleManagerMissing(web_contents) ||
         !GetPermissionContext(permission)) {
       OnPermissionsRequestResponseStatus(request_id, i,
           GetPermissionStatus(permission, requesting_origin, embedding_origin));
@@ -351,10 +346,6 @@
   content::WebContents* web_contents = tab_util::GetWebContentsByFrameID(
       pending_request->render_process_id(), pending_request->render_frame_id());
   DCHECK(web_contents);
-  if (IsPermissionBubbleManagerMissing(web_contents)) {
-    pending_requests_.Remove(request_id);
-    return;
-  }
 
   const PermissionRequestID request(pending_request->render_process_id(),
                                     pending_request->render_frame_id(),
@@ -444,13 +435,6 @@
         ->RemoveObserver(this);
 }
 
-bool PermissionManager::IsPermissionBubbleManagerMissing(
-    content::WebContents* web_contents) {
-  // TODO(felt): Remove this method entirely. Leaving it to make a minimal
-  // last-minute merge to 46. See crbug.com/457091 and crbug.com/534631.
-  return false;
-}
-
 void PermissionManager::OnContentSettingChanged(
     const ContentSettingsPattern& primary_pattern,
     const ContentSettingsPattern& secondary_pattern,
diff --git a/chrome/browser/permissions/permission_manager.h b/chrome/browser/permissions/permission_manager.h
index b160fa26..3e77314 100644
--- a/chrome/browser/permissions/permission_manager.h
+++ b/chrome/browser/permissions/permission_manager.h
@@ -95,10 +95,6 @@
       int permission_id,
       blink::mojom::PermissionStatus status);
 
-  // Not all WebContents are able to display permission requests. If the PBM
-  // is required but missing for |web_contents|, don't pass along the request.
-  bool IsPermissionBubbleManagerMissing(content::WebContents* web_contents);
-
   // content_settings::Observer implementation.
   void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
                                const ContentSettingsPattern& secondary_pattern,
diff --git a/chrome/browser/plugins/plugin_power_saver_browsertest.cc b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
index b517e54..75626b0 100644
--- a/chrome/browser/plugins/plugin_power_saver_browsertest.cc
+++ b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
@@ -33,9 +33,9 @@
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/window_open_disposition.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/geometry/point.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/switches.h"
 
 namespace {
@@ -291,7 +291,7 @@
     if (PixelTestsEnabled()) {
       gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight));
       gfx::Rect screen_bounds =
-          gfx::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+          display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
       ASSERT_GT(screen_bounds.width(), kBrowserWidth);
       ASSERT_GT(screen_bounds.height(), kBrowserHeight);
       browser()->window()->SetBounds(bounds);
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 93c99e4..737c397 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -14,7 +14,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
-#include "base/profiler/scoped_tracker.h"
 #include "base/sequenced_task_runner.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 5a82008..f6f2233 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -80,7 +80,6 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/resource_context.h"
 #include "net/base/keygen_handler.h"
-#include "net/base/network_quality_estimator.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert/multi_log_ct_verifier.h"
 #include "net/cookies/canonical_cookie.h"
@@ -88,6 +87,7 @@
 #include "net/http/http_transaction_factory.h"
 #include "net/http/http_util.h"
 #include "net/http/transport_security_persister.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_config_service_fixed.h"
 #include "net/proxy/proxy_script_fetcher_impl.h"
 #include "net/proxy/proxy_service.h"
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index e1227d88..fb2d6aed 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -68,9 +68,6 @@
 
 namespace {
 
-const char kNewProfileManagementExperimentInternalName[] =
-    "enable-new-profile-management";
-
 #if defined(ENABLE_EXTENSIONS)
 void BlockExtensions(Profile* profile) {
   ExtensionService* extension_service =
@@ -231,15 +228,6 @@
   callback.Run(system_profile, page);
 }
 
-// Updates Chrome services that require notification when
-// the new_profile_management's status changes.
-void UpdateServicesWithNewProfileManagementFlag(Profile* profile,
-                                                bool new_flag_status) {
-  AccountReconcilor* account_reconcilor =
-      AccountReconcilorFactory::GetForProfile(profile);
-  account_reconcilor->OnNewProfileManagementFlagChanged(new_flag_status);
-}
-
 }  // namespace
 
 namespace profiles {
@@ -444,50 +432,6 @@
                     profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
 }
 
-void EnableNewProfileManagementPreview(Profile* profile) {
-#if defined(OS_ANDROID)
-  NOTREACHED();
-#else
-  // TODO(rogerta): instead of setting experiment flags and command line
-  // args, we should set a profile preference.
-  const flags_ui::FeatureEntry entry = {
-      kNewProfileManagementExperimentInternalName,
-      0,  // string id for title of experiment
-      0,  // string id for description of experiment
-      0,  // supported platforms
-      flags_ui::FeatureEntry::ENABLE_DISABLE_VALUE,
-      switches::kEnableNewProfileManagement,
-      "",  // not used with ENABLE_DISABLE_VALUE type
-      switches::kDisableNewProfileManagement,
-      "",       // not used with ENABLE_DISABLE_VALUE type
-      nullptr,  // not used with ENABLE_DISABLE_VALUE type
-      nullptr,  // not used with ENABLE_DISABLE_VALUE type
-      3};
-  flags_ui::PrefServiceFlagsStorage flags_storage(
-      g_browser_process->local_state());
-  about_flags::SetFeatureEntryEnabled(&flags_storage, entry.NameForChoice(1),
-                                      true);
-
-  switches::EnableNewProfileManagementForTesting(
-      base::CommandLine::ForCurrentProcess());
-  UserManager::Show(base::FilePath(),
-                    profiles::USER_MANAGER_TUTORIAL_OVERVIEW,
-                    profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
-  UpdateServicesWithNewProfileManagementFlag(profile, true);
-#endif
-}
-
-void DisableNewProfileManagementPreview(Profile* profile) {
-  flags_ui::PrefServiceFlagsStorage flags_storage(
-      g_browser_process->local_state());
-  about_flags::SetFeatureEntryEnabled(
-      &flags_storage,
-      kNewProfileManagementExperimentInternalName,
-      false);
-  chrome::AttemptRestart();
-  UpdateServicesWithNewProfileManagementFlag(profile, false);
-}
-
 void BubbleViewModeFromAvatarBubbleMode(
     BrowserWindow::AvatarBubbleMode mode,
     BubbleViewMode* bubble_view_mode,
diff --git a/chrome/browser/profiles/profile_window.h b/chrome/browser/profiles/profile_window.h
index 75590af0..3245a91 100644
--- a/chrome/browser/profiles/profile_window.h
+++ b/chrome/browser/profiles/profile_window.h
@@ -111,12 +111,6 @@
 // the tutorial.
 void ShowUserManagerMaybeWithTutorial(Profile* profile);
 
-// Enables new profile management preview and shows the user manager tutorial.
-void EnableNewProfileManagementPreview(Profile* profile);
-
-// Disables new profile management preview and attempts to relaunch Chrome.
-void DisableNewProfileManagementPreview(Profile* profile);
-
 // Converts from modes in the avatar menu to modes understood by
 // ProfileChooserView.
 void BubbleViewModeFromAvatarBubbleMode(
diff --git a/chrome/browser/renderer_context_menu/open_with_menu_factory_ash.cc b/chrome/browser/renderer_context_menu/open_with_menu_factory_ash.cc
index 1e2886c..7aabb8a7 100644
--- a/chrome/browser/renderer_context_menu/open_with_menu_factory_ash.cc
+++ b/chrome/browser/renderer_context_menu/open_with_menu_factory_ash.cc
@@ -136,6 +136,8 @@
             l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_OPEN_WITH_APP,
                                        base::UTF8ToUTF16(it->second.name));
         proxy_->UpdateMenuItem(command_id, true, false, label);
+        if (!it->second.icon.IsEmpty())
+          proxy_->UpdateMenuIcon(command_id, it->second.icon);
       }
     }
   }
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.js b/chrome/browser/resources/local_ntp/most_visited_single.js
index 5a7350ac7..a17d7795 100644
--- a/chrome/browser/resources/local_ntp/most_visited_single.js
+++ b/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -67,6 +67,19 @@
  */
 var NUM_TITLE_LINES = 1;
 
+/**
+ * Type of the impression provider for a generic client-provided suggestion.
+ * @type {string}
+ * @const
+ */
+var CLIENT_PROVIDER_NAME = 'client';
+
+/**
+ * Type of the impression provider for a generic server-provided suggestion.
+ * @type {string}
+ * @const
+ */
+var SERVER_PROVIDER_NAME = 'server';
 
 /**
  * The origin of this request.
@@ -110,6 +123,27 @@
   chrome.embeddedSearch.newTabPage.logEvent(eventType);
 };
 
+/**
+ * Log impression of a most visited tile on the NTP.
+ * @param {number} tileIndex position of the tile, >= 0 and < NUMBER_OF_TILES
+ * @param {string} provider specifies the UMA histogram to be reported
+ *     (NewTabPage.SuggestionsImpression.{provider})
+ */
+function logMostVisitedImpression(tileIndex, provider) {
+  chrome.embeddedSearch.newTabPage.logMostVisitedImpression(tileIndex,
+                                                            provider);
+}
+
+/**
+ * Log click on a most visited tile on the NTP.
+ * @param {number} tileIndex position of the tile, >= 0 and < NUMBER_OF_TILES
+ * @param {string} provider specifies the UMA histogram to be reported
+ *     (NewTabPage.SuggestionsImpression.{provider})
+ */
+function logMostVisitedNavigation(tileIndex, provider) {
+  chrome.embeddedSearch.newTabPage.logMostVisitedNavigation(tileIndex,
+                                                            provider);
+}
 
 /**
  * Down counts the DOM elements that we are waiting for the page to load.
@@ -284,22 +318,35 @@
  * @param {object} args Data for the tile to be rendered.
  */
 var addTile = function(args) {
-  if (args.rid) {
+  if (isFinite(args.rid)) {
+    // If a valid number passed in |args.rid|: a local chrome suggestion.
     var data = chrome.embeddedSearch.searchBox.getMostVisitedItemData(args.rid);
+    if (!data)
+      return;
+
     data.tid = data.rid;
+    data.provider = CLIENT_PROVIDER_NAME;
     if (!data.faviconUrl) {
       data.faviconUrl = 'chrome-search://favicon/size/16@' +
           window.devicePixelRatio + 'x/' + data.renderViewId + '/' + data.tid;
     }
+    logEvent(LOG_TYPE.NTP_CLIENT_SIDE_SUGGESTION);
     tiles.appendChild(renderTile(data));
-  } else if (args.id) {
+  } else if (args.url) {
+    // If a URL is passed: a server-side suggestion.
+    args.provider = args.provider || SERVER_PROVIDER_NAME;
+    // check sanity of the arguments
+    if (/^javascript:/i.test(args.url) ||
+        /^javascript:/i.test(args.thumbnailUrl) ||
+        !/^[a-z0-9]{0,8}$/i.test(args.provider))
+      return;
+    logEvent(LOG_TYPE.NTP_SERVER_SIDE_SUGGESTION);
     tiles.appendChild(renderTile(args));
-  } else {
+  } else {  // an empty tile
     tiles.appendChild(renderTile(null));
   }
 };
 
-
 /**
  * Called when the user decided to add a tile to the blacklist.
  * It sets of the animation for the blacklist and sends the blacklisted id
@@ -343,6 +390,11 @@
   }
 
   logEvent(LOG_TYPE.NTP_TILE);
+  // The tile will be appended to tiles.
+  var position = tiles.children.length;
+  if (data.provider) {
+    logMostVisitedImpression(position, data.provider);
+  }
 
   tile.className = 'mv-tile';
   tile.setAttribute('data-tid', data.tid);
@@ -367,10 +419,15 @@
       navigator.sendBeacon(data.pingUrl);
     });
   }
-  // For local suggestions, we use navigateContentWindow instead of the default
-  // action, since it includes support for file:// urls.
-  if (data.rid) {
-    tile.addEventListener('click', function(ev) {
+
+  tile.addEventListener('click', function(ev) {
+    if (data.provider) {
+      logMostVisitedNavigation(position, data.provider);
+    }
+
+    // For local suggestions, we use navigateContentWindow instead of the
+    // default action, since it includes support for file:// urls.
+    if (data.rid) {
       ev.preventDefault();
       var disp = chrome.embeddedSearch.newTabPage.getDispositionFromClick(
         ev.button == 1,  // MIDDLE BUTTON
@@ -378,8 +435,8 @@
 
       window.chrome.embeddedSearch.newTabPage.navigateContentWindow(data.rid,
                                                                     disp);
-    });
-  }
+    }
+  });
 
   tile.addEventListener('keydown', function(event) {
     if (event.keyCode == 46 /* DELETE */ ||
@@ -392,58 +449,31 @@
       event.preventDefault();
       this.click();
     } else if (event.keyCode >= 37 && event.keyCode <= 40 /* ARROWS */) {
-      var tiles = document.querySelectorAll('#mv-tiles .mv-tile');
-      var nextTile = null;
-      // Use the location of the tile to find the next one in the
-      // appropriate direction.
-      // For LEFT and UP we keep iterating until we find the last element
-      // that fulfills the conditions.
-      // For RIGHT and DOWN we accept the first element that works.
-      if (event.keyCode == 37 /* LEFT */) {
-        for (var i = 0; i < tiles.length; i++) {
-          var tile = tiles[i];
-          if (tile.offsetTop == this.offsetTop &&
-              tile.offsetLeft < this.offsetLeft) {
-            if (!nextTile || tile.offsetLeft > nextTile.offsetLeft) {
-              nextTile = tile;
-            }
-          }
-        }
-      }
-      if (event.keyCode == 38 /* UP */) {
-        for (var i = 0; i < tiles.length; i++) {
-          var tile = tiles[i];
-          if (tile.offsetTop < this.offsetTop &&
-              tile.offsetLeft == this.offsetLeft) {
-            if (!nextTile || tile.offsetTop > nextTile.offsetTop) {
-              nextTile = tile;
-            }
-          }
-        }
-      }
-      if (event.keyCode == 39 /* RIGHT */) {
-        for (var i = 0; i < tiles.length; i++) {
-          var tile = tiles[i];
-          if (tile.offsetTop == this.offsetTop &&
-              tile.offsetLeft > this.offsetLeft) {
-            if (!nextTile || tile.offsetLeft < nextTile.offsetLeft) {
-              nextTile = tile;
-            }
-          }
-        }
-      }
-      if (event.keyCode == 40 /* DOWN */) {
-        for (var i = 0; i < tiles.length; i++) {
-          var tile = tiles[i];
-          if (tile.offsetTop > this.offsetTop &&
-              tile.offsetLeft == this.offsetLeft) {
-            if (!nextTile || tile.offsetTop < nextTile.offsetTop) {
-              nextTile = tile;
-            }
-          }
-        }
-      }
+      // specify the direction of movement
+      var inArrowDirection = function(origin, target) {
+        return (event.keyCode == 37 /* LEFT */ &&
+                origin.offsetTop == target.offsetTop &&
+                origin.offsetLeft > target.offsetLeft) ||
+                (event.keyCode == 38 /* UP */ &&
+                origin.offsetTop > target.offsetTop &&
+                origin.offsetLeft == target.offsetLeft) ||
+                (event.keyCode == 39 /* RIGHT */ &&
+                origin.offsetTop == target.offsetTop &&
+                origin.offsetLeft < target.offsetLeft) ||
+                (event.keyCode == 40 /* DOWN */ &&
+                origin.offsetTop < target.offsetTop &&
+                origin.offsetLeft == target.offsetLeft);
+      };
 
+      var nonEmptyTiles = document.querySelectorAll('#mv-tiles .mv-tile');
+      var nextTile = null;
+      // Find the closest tile in the appropriate direction.
+      for (var i = 0; i < nonEmptyTiles.length; i++) {
+        if (inArrowDirection(this, nonEmptyTiles[i]) &&
+            (!nextTile || inArrowDirection(nonEmptyTiles[i], nextTile))) {
+          nextTile = nonEmptyTiles[i];
+        }
+      }
       if (nextTile) {
         nextTile.focus();
       }
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
index 0c373dd..e14ec95 100644
--- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
+++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.html
@@ -213,7 +213,7 @@
           if="[[computeIssueBannerShown_(currentView_, issue)]]">
         <issue-banner id="issue-banner" issue="[[issue]]"
             class$="[[computeIssueBannerClass_(issue)]]"
-            on-issue-action-tap="showSinkList_">
+            on-issue-action-click="showSinkList_">
         </issue-banner>
       </template>
     </div>
diff --git a/chrome/browser/resources/sync_confirmation/sync_confirmation.css b/chrome/browser/resources/sync_confirmation/sync_confirmation.css
index 7789779..459849a 100644
--- a/chrome/browser/resources/sync_confirmation/sync_confirmation.css
+++ b/chrome/browser/resources/sync_confirmation/sync_confirmation.css
@@ -111,14 +111,8 @@
   padding: 8px 16px;
 }
 
-#confirmButton {
-  background-color: rgb(66, 133, 244);
-  color: white;
-}
-
 #undoButton {
   -webkit-margin-start: 8px;
-  color: #5A5A5A;
 }
 
 #illustration {
diff --git a/chrome/browser/resources/sync_confirmation/sync_confirmation.html b/chrome/browser/resources/sync_confirmation/sync_confirmation.html
index 8111fa4..34ddf7e 100644
--- a/chrome/browser/resources/sync_confirmation/sync_confirmation.html
+++ b/chrome/browser/resources/sync_confirmation/sync_confirmation.html
@@ -4,6 +4,7 @@
     <meta charset="utf-8">
     <link rel="import" href="chrome://resources/html/polymer.html">
     <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+    <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
     <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
     <link rel="stylesheet" href="sync_confirmation.css"></link>
     <style is="custom-style">
@@ -12,12 +13,38 @@
         text-decoration: none;
       }
 
-      .action-container {
+      #confirmButton {
+        --paper-button: {
+          background: var(--google-blue-500);
+          color: white;
+        };
+        --paper-button-flat-keyboard-focus: {
+          background: rgb(58, 117, 215);
+          font-weight: 500;
+        };
+      }
+
+      #undoButton {
+        --paper-button: {
+          color: var(--paper-grey-600);
+        };
+        --paper-button-flat-keyboard-focus: {
+          background: rgba(0, 0, 0, .12);
+          font-weight: 500;
+        };
+      }
+
 <if expr="is_macosx or is_linux">
+      .action-container {
         flex-flow: row-reverse;
         justify-content: flex-start;
-</if>
       }
+
+      #undoButton {
+        -webkit-margin-end: 8px;
+        -webkit-margin-start: 0;
+      }
+</if>
     </style>
   </head>
   <body>
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
index ecd5aea..a2fe1ad 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -33,6 +34,7 @@
 #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h"
 #include "chrome/browser/safe_browsing/incident_reporting/state_store.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/safe_browsing/csd.pb.h"
 #include "components/prefs/pref_service.h"
@@ -146,6 +148,15 @@
   return false;
 }
 
+// Returns the shutdown behavior for the task runners of the incident reporting
+// service. Current metrics suggest that CONTINUE_ON_SHUTDOWN will reduce the
+// number of browser hangs on shutdown.
+base::SequencedWorkerPool::WorkerShutdown GetShutdownBehavior() {
+  return base::FeatureList::IsEnabled(features::kBrowserHangFixesExperiment)
+             ? base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
+             : base::SequencedWorkerPool::SKIP_ON_SHUTDOWN;
+}
+
 }  // namespace
 
 struct IncidentReportingService::ProfileContext {
@@ -338,8 +349,7 @@
       collect_environment_data_fn_(&CollectEnvironmentData),
       environment_collection_task_runner_(
           content::BrowserThread::GetBlockingPool()
-              ->GetTaskRunnerWithShutdownBehavior(
-                  base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
+              ->GetTaskRunnerWithShutdownBehavior(GetShutdownBehavior())),
       environment_collection_pending_(),
       collation_timeout_pending_(),
       collation_timer_(FROM_HERE,
@@ -349,13 +359,11 @@
       delayed_analysis_callbacks_(
           base::TimeDelta::FromMilliseconds(kDefaultCallbackIntervalMs),
           content::BrowserThread::GetBlockingPool()
-              ->GetTaskRunnerWithShutdownBehavior(
-                  base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
+              ->GetTaskRunnerWithShutdownBehavior(GetShutdownBehavior())),
       extended_reporting_only_delayed_analysis_callbacks_(
           base::TimeDelta::FromMilliseconds(kDefaultCallbackIntervalMs),
           content::BrowserThread::GetBlockingPool()
-              ->GetTaskRunnerWithShutdownBehavior(
-                  base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
+              ->GetTaskRunnerWithShutdownBehavior(GetShutdownBehavior())),
       download_metadata_manager_(content::BrowserThread::GetBlockingPool()),
       receiver_weak_ptr_factory_(this),
       weak_ptr_factory_(this) {
@@ -463,8 +471,7 @@
       collect_environment_data_fn_(&CollectEnvironmentData),
       environment_collection_task_runner_(
           content::BrowserThread::GetBlockingPool()
-              ->GetTaskRunnerWithShutdownBehavior(
-                  base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
+              ->GetTaskRunnerWithShutdownBehavior(GetShutdownBehavior())),
       environment_collection_pending_(),
       collation_timeout_pending_(),
       collation_timer_(FROM_HERE,
@@ -497,8 +504,7 @@
     collect_environment_data_fn_ = &CollectEnvironmentData;
     environment_collection_task_runner_ =
         content::BrowserThread::GetBlockingPool()
-            ->GetTaskRunnerWithShutdownBehavior(
-                base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+            ->GetTaskRunnerWithShutdownBehavior(GetShutdownBehavior());
   }
 }
 
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index c3efbe79..09fd094 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -511,11 +511,13 @@
 
   GURL effective_url(url);
 
-  // Replace the scheme with "chrome-search:".
+  // Replace the scheme with "chrome-search:", and clear the port, since
+  // chrome-search is a scheme without port.
   url::Replacements<char> replacements;
   std::string search_scheme(chrome::kChromeSearchScheme);
   replacements.SetScheme(search_scheme.data(),
                          url::Component(0, search_scheme.length()));
+  replacements.ClearPort();
 
   // If this is the URL for a server-provided NTP, replace the host with
   // "remote-ntp".
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index 3d96e1e..baa19152 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -185,9 +185,11 @@
     {"https://foo.com/instant?strk=0", false,  ""},
     {"https://foo.com/url?strk",       false,  ""},
     {"https://foo.com/alt?strk",       false,  ""},
+    {"https://foo.com:80/instant",     false,  "HTTPS with port"},
     {"http://foo.com/instant",         false,  "Non-HTTPS"},
     {"http://foo.com/instant?strk",    false,  "Non-HTTPS"},
     {"http://foo.com/instant?strk=1",  false,  "Non-HTTPS"},
+    {"http://foo.com:443/instant",     false,  "Non-HTTPS"},
     {"https://foo.com/instant",        false,  "No search terms replacement"},
     {"https://foo.com/?strk",          false,  "Non-exact path"},
   };
@@ -594,7 +596,6 @@
 }
 
 
-
 TEST_F(SearchTest, ShouldShowGoogleLocalNTP_Default) {
   EXPECT_TRUE(ShouldShowGoogleLocalNTP());
 }
@@ -700,6 +701,40 @@
   }
 }
 
+// Regression test for https://crbug.com/605720: Set up a search provider backed
+// by localhost on a specific port, like browsertests do.  The chrome-search://
+// URLs generated in this mode should not have ports.
+TEST_F(SearchTest, SearchProviderWithPort) {
+  TemplateURLService* template_url_service =
+      TemplateURLServiceFactory::GetForProfile(profile());
+  TemplateURLData data;
+  data.SetShortName(base::ASCIIToUTF16("localhost"));
+  data.SetURL("https://[::1]:1993/url?bar={searchTerms}");
+  data.instant_url =
+      "https://[::1]:1993/instant?"
+      "{google:forceInstantResults}foo=foo#foo=foo&strk";
+  data.new_tab_url = "https://[::1]:1993/newtab?strk";
+  data.alternate_urls.push_back("https://[::1]:1993/alt#quux={searchTerms}");
+  data.search_terms_replacement_key = "strk";
+
+  TemplateURL* template_url = new TemplateURL(data);
+  template_url_service->Add(template_url); // Takes ownership of |template_url|.
+  template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
+
+  EXPECT_TRUE(ShouldAssignURLToInstantRenderer(
+      GURL("https://[::1]:1993/newtab?lala"), profile()));
+  EXPECT_FALSE(ShouldAssignURLToInstantRenderer(
+      GURL("https://[::1]:1992/newtab?lala"), profile()));
+  EXPECT_EQ(GURL("chrome-search://remote-ntp/newtab?lala"),
+            GetEffectiveURLForInstant(GURL("https://[::1]:1993/newtab?lala"),
+                                      profile()));
+  EXPECT_EQ(GURL("chrome-search://[::1]/instant?strk"),
+            GetEffectiveURLForInstant(GURL("https://[::1]:1993/instant?strk"),
+                                      profile()));
+  EXPECT_FALSE(ShouldAssignURLToInstantRenderer(
+      GURL("https://[::1]:1993/unregistered-path?strk"), profile()));
+}
+
 class SearchURLTest : public SearchTest {
  protected:
   void SetSearchProvider(bool set_ntp_url, bool insecure_ntp_url) override {
diff --git a/chrome/browser/search/suggestions/image_fetcher_impl.cc b/chrome/browser/search/suggestions/image_fetcher_impl.cc
index d3176c27..86c18a8 100644
--- a/chrome/browser/search/suggestions/image_fetcher_impl.cc
+++ b/chrome/browser/search/suggestions/image_fetcher_impl.cc
@@ -28,7 +28,8 @@
 
 ImageFetcherImpl::ImageRequest::~ImageRequest() { delete fetcher; }
 
-void ImageFetcherImpl::SetImageFetcherDelegate(ImageFetcherDelegate* delegate) {
+void ImageFetcherImpl::SetImageFetcherDelegate(
+    image_fetcher::ImageFetcherDelegate* delegate) {
   DCHECK(delegate);
   delegate_ = delegate;
 }
diff --git a/chrome/browser/search/suggestions/image_fetcher_impl.h b/chrome/browser/search/suggestions/image_fetcher_impl.h
index f27ebaf1..74c9112cb 100644
--- a/chrome/browser/search/suggestions/image_fetcher_impl.h
+++ b/chrome/browser/search/suggestions/image_fetcher_impl.h
@@ -12,7 +12,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
-#include "components/suggestions/image_fetcher.h"
+#include "components/image_fetcher/image_fetcher.h"
 #include "ui/gfx/image/image_skia.h"
 #include "url/gurl.h"
 
@@ -24,13 +24,14 @@
 
 // A class used to fetch server images. It can be called from any thread and the
 // callback will be called on the thread which initiated the fetch.
-class ImageFetcherImpl : public ImageFetcher,
+class ImageFetcherImpl : public image_fetcher::ImageFetcher,
                          public chrome::BitmapFetcherDelegate {
  public:
   explicit ImageFetcherImpl(net::URLRequestContextGetter* url_request_context);
   ~ImageFetcherImpl() override;
 
-  void SetImageFetcherDelegate(ImageFetcherDelegate* delegate) override;
+  void SetImageFetcherDelegate(
+      image_fetcher::ImageFetcherDelegate* delegate) override;
 
   void StartOrQueueNetworkRequest(
       const GURL& url,
@@ -74,7 +75,7 @@
   // url, fetcher, pending callbacks).
   ImageRequestMap pending_net_requests_;
 
-  ImageFetcherDelegate* delegate_;
+  image_fetcher::ImageFetcherDelegate* delegate_;
 
   net::URLRequestContextGetter* url_request_context_;
 
diff --git a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
index 04e9b3fb..c78ed727 100644
--- a/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
+++ b/chrome/browser/search/suggestions/image_fetcher_impl_browsertest.cc
@@ -13,13 +13,16 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
-#include "components/suggestions/image_fetcher_delegate.h"
+#include "components/image_fetcher/image_fetcher_delegate.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 class SkBitmap;
 
+using image_fetcher::ImageFetcher;
+using image_fetcher::ImageFetcherDelegate;
+
 namespace suggestions {
 
 namespace {
diff --git a/chrome/browser/search/suggestions/suggestions_service_factory.cc b/chrome/browser/search/suggestions/suggestions_service_factory.cc
index 34db255..c4e5679 100644
--- a/chrome/browser/search/suggestions/suggestions_service_factory.cc
+++ b/chrome/browser/search/suggestions/suggestions_service_factory.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "components/browser_sync/browser/profile_sync_service.h"
+#include "components/image_fetcher/image_fetcher.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/leveldb_proto/proto_database.h"
 #include "components/leveldb_proto/proto_database_impl.h"
@@ -22,7 +23,6 @@
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/suggestions/blacklist_store.h"
-#include "components/suggestions/image_fetcher.h"
 #include "components/suggestions/image_manager.h"
 #include "components/suggestions/proto/suggestions.pb.h"
 #include "components/suggestions/suggestions_service.h"
diff --git a/chrome/browser/search/thumbnail_source.h b/chrome/browser/search/thumbnail_source.h
index 9e645c5..5e17f46 100644
--- a/chrome/browser/search/thumbnail_source.h
+++ b/chrome/browser/search/thumbnail_source.h
@@ -21,12 +21,12 @@
 class RefCountedMemory;
 }
 
-namespace thumbnails {
-class ThumbnailService;
+namespace image_fetcher {
+class ImageFetcher;
 }
 
-namespace suggestions {
-class ImageFetcher;
+namespace thumbnails {
+class ThumbnailService;
 }
 
 // ThumbnailSource is the gateway between network-level chrome: requests for
@@ -71,7 +71,7 @@
   scoped_refptr<thumbnails::ThumbnailService> thumbnail_service_;
 
   // ImageFetcher.
-  std::unique_ptr<suggestions::ImageFetcher> image_fetcher_;
+  std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
 
   // Indicate that, when a URL for which we don't have a thumbnail is requested
   // from this source, then Chrome should capture a thumbnail next time it
diff --git a/chrome/browser/signin/signin_error_notifier_ash_unittest.cc b/chrome/browser/signin/signin_error_notifier_ash_unittest.cc
index 322195a..bd0fada 100644
--- a/chrome/browser/signin/signin_error_notifier_ash_unittest.cc
+++ b/chrome/browser/signin/signin_error_notifier_ash_unittest.cc
@@ -31,7 +31,7 @@
 #if defined(OS_WIN)
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "ui/aura/test/test_screen.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #endif
 
 namespace ash {
@@ -67,7 +67,7 @@
     // Set up screen for Windows.
 #if defined(OS_WIN)
     test_screen_.reset(aura::TestScreen::Create(gfx::Size()));
-    gfx::Screen::SetScreenInstance(test_screen_.get());
+    display::Screen::SetScreenInstance(test_screen_.get());
 #endif
 
     error_controller_ = SigninErrorControllerFactory::GetForProfile(
@@ -78,7 +78,7 @@
 
   void TearDown() override {
 #if defined(OS_WIN)
-    gfx::Screen::SetScreenInstance(nullptr);
+    display::Screen::SetScreenInstance(nullptr);
     test_screen_.reset();
 #endif
     profile_manager_.reset();
@@ -97,7 +97,7 @@
   }
 
 #if defined(OS_WIN)
-  std::unique_ptr<gfx::Screen> test_screen_;
+  std::unique_ptr<display::Screen> test_screen_;
 #endif
   std::unique_ptr<TestingProfileManager> profile_manager_;
   std::unique_ptr<TestingProfile> profile_;
diff --git a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
index ddd0ee0..da5a683 100644
--- a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
+++ b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
@@ -31,7 +31,7 @@
 #if defined(OS_WIN)
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "ui/aura/test/test_screen.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #endif
 
 using ::testing::NiceMock;
@@ -89,7 +89,7 @@
     // adding desktop widgets (i.e., message center notifications).
 #if defined(OS_WIN)
     test_screen_.reset(aura::TestScreen::Create(gfx::Size()));
-    gfx::Screen::SetScreenInstance(test_screen_.get());
+    display::Screen::SetScreenInstance(test_screen_.get());
 #endif
 
     AshTestBase::SetUp();
@@ -123,7 +123,7 @@
     AshTestBase::TearDown();
 
 #if defined(OS_WIN)
-    gfx::Screen::SetScreenInstance(nullptr);
+    display::Screen::SetScreenInstance(nullptr);
     test_screen_.reset();
 #endif
 
@@ -159,7 +159,7 @@
   }
 
 #if defined(OS_WIN)
-  std::unique_ptr<gfx::Screen> test_screen_;
+  std::unique_ptr<display::Screen> test_screen_;
 #endif
   std::unique_ptr<TestingProfileManager> profile_manager_;
   std::unique_ptr<SyncErrorController> error_controller_;
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 61301e2..daf8a17 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -37,7 +37,6 @@
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_operations.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/resources/grit/ui_resources.h"
 
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc
index 9bcb6419..031e255 100644
--- a/chrome/browser/themes/theme_properties.cc
+++ b/chrome/browser/themes/theme_properties.cc
@@ -26,15 +26,15 @@
 // Default colors.
 #if defined(OS_MACOSX)
 // Used for theme fallback colors.
-const SkColor kDefaultColorFrame[] = {
-    SkColorSetRGB(224, 224, 224), SkColorSetRGB(204, 204, 204)};
-const SkColor kDefaultColorFrameInactive[] = {
-    SkColorSetRGB(246, 246, 246), SkColorSetRGB(246, 246, 246)};
+const SkColor kDefaultColorFrame[] = {SkColorSetRGB(0xE0, 0xE0, 0xE0),
+                                      SkColorSetRGB(0xCC, 0xCC, 0xCC)};
+const SkColor kDefaultColorFrameInactive[] = {SkColorSetRGB(0xF6, 0xF6, 0xF6),
+                                              SkColorSetRGB(0xF6, 0xF6, 0xF6)};
 #else
-const SkColor kDefaultColorFrame[] = {
-    SkColorSetRGB(0xC3, 0xC3, 0xC4), SkColorSetRGB(204, 204, 204)};
-const SkColor kDefaultColorFrameInactive[] = {
-    SkColorSetRGB(0xCD, 0xCD, 0xCE), SkColorSetRGB(220, 220, 220)};
+const SkColor kDefaultColorFrame[] = {SkColorSetRGB(0xC3, 0xC3, 0xC4),
+                                      SkColorSetRGB(0xCC, 0xCC, 0xCC)};
+const SkColor kDefaultColorFrameInactive[] = {SkColorSetRGB(0xCD, 0xCD, 0xCE),
+                                              SkColorSetRGB(0xDC, 0xDC, 0xDC)};
 #endif
 
 // These colors are the same between CrOS and !CrOS for MD, so this ifdef can be
@@ -46,26 +46,26 @@
     SkColorSetRGB(0xAA, 0xAA, 0xAE), SkColorSetRGB(0x38, 0x3B, 0x3D)};
 #elif defined(OS_MACOSX)
 const SkColor kDefaultColorFrameIncognito[] = {
-    SkColorSetRGB(255, 0, 0), SkColorSetARGB(230, 20, 22, 24)};
+    gfx::kPlaceholderColor, SkColorSetARGB(0xE6, 0x14, 0x16, 0x18)};
 const SkColor kDefaultColorFrameIncognitoInactive[] = {
-    SkColorSetRGB(255, 0, 0), SkColorSetRGB(30, 30, 30)};
+    gfx::kPlaceholderColor, SkColorSetRGB(0x1E, 0x1E, 0x1E)};
 #else
-const SkColor kDefaultColorFrameIncognito[] = {SkColorSetRGB(83, 106, 139),
+const SkColor kDefaultColorFrameIncognito[] = {SkColorSetRGB(0x53, 0x6A, 0x8B),
                                                SkColorSetRGB(0x28, 0x2B, 0x2D)};
 const SkColor kDefaultColorFrameIncognitoInactive[] = {
-    SkColorSetRGB(126, 139, 156), SkColorSetRGB(0x38, 0x3B, 0x3D)};
+    SkColorSetRGB(0x7E, 0x8B, 0x9C), SkColorSetRGB(0x38, 0x3B, 0x3D)};
 #endif
 
 #if defined(OS_MACOSX)
-const SkColor kDefaultColorToolbar[] = {
-    SkColorSetRGB(230, 230, 230), SkColorSetRGB(242, 242, 242)};
+const SkColor kDefaultColorToolbar[] = {SkColorSetRGB(0xE6, 0xE6, 0xE6),
+                                        SkColorSetRGB(0xF2, 0xF2, 0xF2)};
 const SkColor kDefaultColorToolbarIncognito[] = {
-    SkColorSetRGB(230, 230, 230), SkColorSetRGB(0x50, 0x50, 0x50)};
+    SkColorSetRGB(0xE6, 0xE6, 0xE6), SkColorSetRGB(0x50, 0x50, 0x50)};
 #else
-const SkColor kDefaultColorToolbar[] = {
-    SkColorSetRGB(223, 223, 223), SkColorSetRGB(242, 242, 242)};
+const SkColor kDefaultColorToolbar[] = {SkColorSetRGB(0xDF, 0xDF, 0xDF),
+                                        SkColorSetRGB(0xF2, 0xF2, 0xF2)};
 const SkColor kDefaultColorToolbarIncognito[] = {
-    SkColorSetRGB(223, 223, 223), SkColorSetRGB(0x50, 0x50, 0x50)};
+    SkColorSetRGB(0xDF, 0xDF, 0xDF), SkColorSetRGB(0x50, 0x50, 0x50)};
 #endif  // OS_MACOSX
 const SkColor kDefaultDetachedBookmarkBarBackground[] = {
     SkColorSetRGB(0xF1, 0xF1, 0xF1), SK_ColorWHITE};
@@ -83,9 +83,9 @@
     kDefaultColorBackgroundTabText[0], SK_ColorWHITE};
 #else
 const SkColor kDefaultColorBackgroundTabText[] = {
-    SkColorSetRGB(64, 64, 64), SK_ColorBLACK };
+    SkColorSetRGB(0x40, 0x40, 0x40), SK_ColorBLACK};
 const SkColor kDefaultColorBackgroundTabTextIncognito[] = {
-    SkColorSetRGB(64, 64, 64), SK_ColorWHITE };
+    SkColorSetRGB(0x40, 0x40, 0x40), SK_ColorWHITE};
 #endif  // OS_MACOSX
 
 constexpr SkColor kDefaultColorBookmarkText = SK_ColorBLACK;
@@ -97,19 +97,18 @@
     color_utils::GetSysSkColor(COLOR_WINDOW);
 const SkColor kDefaultColorNTPText =
     color_utils::GetSysSkColor(COLOR_WINDOWTEXT);
-const SkColor kDefaultColorNTPLink =
-    color_utils::GetSysSkColor(COLOR_HOTLIGHT);
+const SkColor kDefaultColorNTPLink = color_utils::GetSysSkColor(COLOR_HOTLIGHT);
 #else
 // TODO(beng): source from theme provider.
 constexpr SkColor kDefaultColorNTPBackground = SK_ColorWHITE;
 constexpr SkColor kDefaultColorNTPText = SK_ColorBLACK;
-const SkColor kDefaultColorNTPLink = SkColorSetRGB(6, 55, 116);
+const SkColor kDefaultColorNTPLink = SkColorSetRGB(0x06, 0x37, 0x74);
 #endif  // OS_WIN
 
-const SkColor kDefaultColorNTPHeader = SkColorSetRGB(150, 150, 150);
-const SkColor kDefaultColorNTPSection = SkColorSetRGB(229, 229, 229);
+const SkColor kDefaultColorNTPHeader = SkColorSetRGB(0x96, 0x96, 0x96);
+const SkColor kDefaultColorNTPSection = SkColorSetRGB(0xE5, 0xE5, 0xE5);
 constexpr SkColor kDefaultColorNTPSectionText = SK_ColorBLACK;
-const SkColor kDefaultColorNTPSectionLink = SkColorSetRGB(6, 55, 116);
+const SkColor kDefaultColorNTPSectionLink = SkColorSetRGB(0x06, 0x37, 0x74);
 constexpr SkColor kDefaultColorButtonBackground = SK_ColorTRANSPARENT;
 
 // Default tints.
@@ -127,35 +126,37 @@
 
 constexpr SkColor kDefaultColorControlBackground = SK_ColorWHITE;
 const SkColor kDefaultDetachedBookmarkBarSeparator[] = {
-    SkColorSetRGB(170, 170, 171), SkColorSetRGB(182, 180, 182)};
+    SkColorSetRGB(0xAA, 0xAA, 0xAB), SkColorSetRGB(0xB6, 0xB4, 0xB6)};
 const SkColor kDefaultDetachedBookmarkBarSeparatorIncognito[] = {
-    SkColorSetRGB(170, 170, 171), SkColorSetRGB(0x28, 0x28, 0x28)};
+    SkColorSetRGB(0xAA, 0xAA, 0xAB), SkColorSetRGB(0x28, 0x28, 0x28)};
 const SkColor kDefaultToolbarTopSeparator = SkColorSetA(SK_ColorBLACK, 0x40);
 
 #if defined(OS_MACOSX)
 const SkColor kDefaultColorFrameVibrancyOverlay[] = {
-    SkColorSetARGB(25, 0, 0, 0), SkColorSetARGB(230, 20, 22, 24)};
+    SkColorSetA(SK_ColorBLACK, 0x19), SkColorSetARGB(0xE6, 0x14, 0x16, 0x18)};
 const SkColor kDefaultColorToolbarInactive[] = {
-    SkColorSetRGB(255, 0, 0), SkColorSetRGB(246, 246, 246)};
+    gfx::kPlaceholderColor, SkColorSetRGB(0xF6, 0xF6, 0xF6)};
 const SkColor kDefaultColorToolbarInactiveIncognito[] = {
-    SkColorSetRGB(255, 0, 0), SkColorSetRGB(45, 45, 45)};
+    gfx::kPlaceholderColor, SkColorSetRGB(0x2D, 0x2D, 0x2D)};
 const SkColor kDefaultColorTabBackgroundInactive[] = {
-    SkColorSetRGB(255, 0, 0), SkColorSetRGB(236, 236, 236)};
+    gfx::kPlaceholderColor, SkColorSetRGB(0xEC, 0xEC, 0xEC)};
 const SkColor kDefaultColorTabBackgroundInactiveIncognito[] = {
-    SkColorSetRGB(255, 0, 0), SkColorSetRGB(40, 40, 40)};
-const SkColor kDefaultColorToolbarButtonStroke = SkColorSetARGB(75, 81, 81, 81);
+    gfx::kPlaceholderColor, SkColorSetRGB(0x28, 0x28, 0x28)};
+const SkColor kDefaultColorToolbarButtonStroke =
+    SkColorSetARGB(0x4B, 0x51, 0x51, 0x51);
 const SkColor kDefaultColorToolbarButtonStrokeInactive =
-    SkColorSetARGB(75, 99, 99, 99);
-const SkColor kDefaultColorToolbarBezel = SkColorSetRGB(204, 204, 204);
-const SkColor kDefaultColorToolbarStroke[] = {
-    SkColorSetRGB(103, 103, 103), SkColorSetARGB(76, 0, 0, 0)};
-const SkColor kDefaultColorToolbarStrokeInactive = SkColorSetRGB(163, 163, 163);
+    SkColorSetARGB(0x4B, 0x63, 0x63, 0x63);
+const SkColor kDefaultColorToolbarBezel = SkColorSetRGB(0xCC, 0xCC, 0xCC);
+const SkColor kDefaultColorToolbarStroke[] = {SkColorSetRGB(0x67, 0x67, 0x67),
+                                              SkColorSetA(SK_ColorBLACK, 0x4C)};
+const SkColor kDefaultColorToolbarStrokeInactive =
+    SkColorSetRGB(0xA3, 0xA3, 0xA3);
 const SkColor kDefaultColorToolbarIncognitoStroke[] = {
-    SkColorSetRGB(103, 103, 103), SkColorSetARGB(63, 0, 0, 0)};
+    SkColorSetRGB(0x67, 0x67, 0x67), SkColorSetA(SK_ColorBLACK, 0x3F)};
 const SkColor kDefaultColorToolbarStrokeTheme =
-    SkColorSetARGB(102, 255, 255, 255);
+    SkColorSetA(SK_ColorWHITE, 0x66);
 const SkColor kDefaultColorToolbarStrokeThemeInactive =
-    SkColorSetARGB(102, 76, 76, 76);
+    SkColorSetARGB(0x66, 0x4C, 0x4C, 0x4C);
 #endif  // OS_MACOSX
 // ----------------------------------------------------------------------------
 
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop.cc b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
index c47554c4..2a1a135 100644
--- a/chrome/browser/thumbnails/simple_thumbnail_crop.cc
+++ b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
@@ -13,7 +13,6 @@
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/scrollbar_size.h"
 #include "ui/gfx/skbitmap_operations.h"
 
diff --git a/chrome/browser/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/thumbnails/thumbnail_tab_helper.cc
index 93f6f42d..fb7f04b 100644
--- a/chrome/browser/thumbnails/thumbnail_tab_helper.cc
+++ b/chrome/browser/thumbnails/thumbnail_tab_helper.cc
@@ -20,7 +20,6 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/geometry/size_conversions.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/scrollbar_size.h"
 #include "ui/gfx/skbitmap_operations.h"
 
diff --git a/chrome/browser/ui/app_list/app_list_positioner.cc b/chrome/browser/ui/app_list/app_list_positioner.cc
index d41a66ff..6ba2488b 100644
--- a/chrome/browser/ui/app_list/app_list_positioner.cc
+++ b/chrome/browser/ui/app_list/app_list_positioner.cc
@@ -10,7 +10,7 @@
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 
-AppListPositioner::AppListPositioner(const gfx::Display& display,
+AppListPositioner::AppListPositioner(const display::Display& display,
                                      const gfx::Size& window_size,
                                      int min_distance_from_edge)
     : display_(display),
diff --git a/chrome/browser/ui/app_list/app_list_positioner.h b/chrome/browser/ui/app_list/app_list_positioner.h
index 8e8c787..52a0a08e 100644
--- a/chrome/browser/ui/app_list/app_list_positioner.h
+++ b/chrome/browser/ui/app_list/app_list_positioner.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_UI_APP_LIST_APP_LIST_POSITIONER_H_
 #define CHROME_BROWSER_UI_APP_LIST_APP_LIST_POSITIONER_H_
 
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace gfx {
@@ -42,7 +42,7 @@
   // |window_size| is the size of the App List.
   // |min_distance_from_edge| is the minimum distance, in pixels, to position
   // the app list from the shelf or edge of screen.
-  AppListPositioner(const gfx::Display& display,
+  AppListPositioner(const display::Display& display,
                     const gfx::Size& window_size,
                     int min_distance_from_edge);
 
@@ -103,7 +103,7 @@
   // the work area. Returns the updated anchor point.
   gfx::Point ClampAnchorPoint(gfx::Point anchor) const;
 
-  gfx::Display display_;
+  display::Display display_;
 
   // Size of the App List.
   gfx::Size window_size_;
diff --git a/chrome/browser/ui/app_list/app_list_positioner_unittest.cc b/chrome/browser/ui/app_list/app_list_positioner_unittest.cc
index 60e4a339..24fce11 100644
--- a/chrome/browser/ui/app_list/app_list_positioner_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_positioner_unittest.cc
@@ -115,7 +115,7 @@
   }
 
  private:
-  gfx::Display display_;
+  display::Display display_;
   std::unique_ptr<AppListPositioner> positioner_;
   gfx::Point cursor_;
 };
diff --git a/chrome/browser/ui/app_list/app_list_service_mac.h b/chrome/browser/ui/app_list/app_list_service_mac.h
index 2fa1d46..79b1527 100644
--- a/chrome/browser/ui/app_list/app_list_service_mac.h
+++ b/chrome/browser/ui/app_list/app_list_service_mac.h
@@ -21,6 +21,10 @@
 class Point;
 }
 
+namespace display {
+using Display = gfx::Display;
+}
+
 // AppListServiceMac manages global resources needed for the app list to
 // operate, and controls when and how the app list is opened and closed.
 class AppListServiceMac : public AppListServiceImpl,
@@ -37,7 +41,7 @@
   // from. Coordinates are for the bottom-left coordinate of the window, in
   // AppKit space (Y positive is up).
   static void FindAnchorPoint(const gfx::Size& window_size,
-                              const gfx::Display& display,
+                              const display::Display& display,
                               int primary_display_height,
                               bool cursor_is_visible,
                               const gfx::Point& cursor,
diff --git a/chrome/browser/ui/app_list/app_list_shower_views.cc b/chrome/browser/ui/app_list/app_list_shower_views.cc
index 20f5acba..1e0acfd 100644
--- a/chrome/browser/ui/app_list/app_list_shower_views.cc
+++ b/chrome/browser/ui/app_list/app_list_shower_views.cc
@@ -15,8 +15,8 @@
 #include "chrome/browser/ui/app_list/app_list_shower_delegate.h"
 #include "chrome/browser/ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/views/app_list_view.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/point.h"
-#include "ui/gfx/screen.h"
 
 AppListShower::AppListShower(AppListShowerDelegate* delegate)
     : delegate_(delegate),
@@ -119,7 +119,7 @@
     view = new app_list::AppListView(delegate_->GetViewDelegateForCreate());
   }
 
-  gfx::Point cursor = gfx::Screen::GetScreen()->GetCursorScreenPoint();
+  gfx::Point cursor = display::Screen::GetScreen()->GetCursorScreenPoint();
   view->InitAsBubbleAtFixedLocation(NULL,
                                     0,
                                     cursor,
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
index a8747cc..ffb2be3 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -10,8 +10,8 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "components/arc/arc_bridge_service.h"
 #include "ui/aura/window.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 
 namespace arc {
 
@@ -82,7 +82,7 @@
     // area. We can therefore ignore the provided left / top offsets.
     aura::Window* root = ash::Shell::GetPrimaryRootWindow();
     gfx::Rect work_area =
-        gfx::Screen::GetScreen()->GetDisplayNearestWindow(root).work_area();
+        display::Screen::GetScreen()->GetDisplayNearestWindow(root).work_area();
 
     // For what Android is concerned, the title bar starts at -TITLE_BAR_HEIGHT.
     // as such we deduct the title bar height simply from the height, but leave
diff --git a/chrome/browser/ui/ash/chrome_launcher_prefs.cc b/chrome/browser/ui/ash/chrome_launcher_prefs.cc
index 555487d..facb328 100644
--- a/chrome/browser/ui/ash/chrome_launcher_prefs.cc
+++ b/chrome/browser/ui/ash/chrome_launcher_prefs.cc
@@ -17,7 +17,7 @@
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace ash {
 
@@ -235,7 +235,7 @@
     return;
 
   SetPerDisplayPref(prefs, display_id, prefs::kShelfAutoHideBehavior, value);
-  if (display_id == gfx::Screen::GetScreen()->GetPrimaryDisplay().id()) {
+  if (display_id == display::Screen::GetScreen()->GetPrimaryDisplay().id()) {
     // See comment in |kShelfAlignment| about why we have two prefs here.
     prefs->SetString(prefs::kShelfAutoHideBehaviorLocal, value);
     prefs->SetString(prefs::kShelfAutoHideBehavior, value);
@@ -261,7 +261,7 @@
     return;
 
   SetPerDisplayPref(prefs, display_id, prefs::kShelfAlignment, value);
-  if (display_id == gfx::Screen::GetScreen()->GetPrimaryDisplay().id()) {
+  if (display_id == display::Screen::GetScreen()->GetPrimaryDisplay().id()) {
     // See comment in |kShelfAlignment| as to why we consider two prefs.
     prefs->SetString(prefs::kShelfAlignmentLocal, value);
     prefs->SetString(prefs::kShelfAlignment, value);
diff --git a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
index 69c7bfed..ea0b7bd9 100644
--- a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
+++ b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
@@ -28,7 +28,7 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/wm/public/activation_client.h"
 
 // This class monitors the WebContent of the all tab and notifies a navigation
@@ -128,7 +128,7 @@
           aura::client::GetActivationClient(*iter));
       observed_root_windows_.Add(static_cast<aura::Window*>(*iter));
     }
-    gfx::Screen::GetScreen()->AddObserver(this);
+    display::Screen::GetScreen()->AddObserver(this);
   }
 
   browser_tab_strip_tracker_.Init(
@@ -139,7 +139,7 @@
   // This check needs for win7_aura. Without this, all tests in
   // ChromeLauncherController will fail in win7_aura.
   if (ash::Shell::HasInstance())
-    gfx::Screen::GetScreen()->RemoveObserver(this);
+    display::Screen::GetScreen()->RemoveObserver(this);
 
   chrome::SettingsWindowManager::GetInstance()->RemoveObserver(
       settings_window_observer_.get());
@@ -230,7 +230,7 @@
   UpdateBrowserItemState();
 }
 
-void BrowserStatusMonitor::OnDisplayAdded(const gfx::Display& new_display) {
+void BrowserStatusMonitor::OnDisplayAdded(const display::Display& new_display) {
   // Add a new RootWindow and its ActivationClient to observed list.
   aura::Window* root_window = ash::Shell::GetInstance()
                                   ->window_tree_host_manager()
@@ -244,14 +244,15 @@
   }
 }
 
-void BrowserStatusMonitor::OnDisplayRemoved(const gfx::Display& old_display) {
+void BrowserStatusMonitor::OnDisplayRemoved(
+    const display::Display& old_display) {
   // When this is called, RootWindow of |old_display| is already removed.
   // Instead, we can remove RootWindow and its ActivationClient in the
   // OnWindowRemoved().
   // Do nothing here.
 }
 
-void BrowserStatusMonitor::OnDisplayMetricsChanged(const gfx::Display&,
+void BrowserStatusMonitor::OnDisplayMetricsChanged(const display::Display&,
                                                    uint32_t) {
   // Do nothing here.
 }
diff --git a/chrome/browser/ui/ash/launcher/browser_status_monitor.h b/chrome/browser/ui/ash/launcher/browser_status_monitor.h
index 3aa85253..5116b56 100644
--- a/chrome/browser/ui/ash/launcher/browser_status_monitor.h
+++ b/chrome/browser/ui/ash/launcher/browser_status_monitor.h
@@ -20,7 +20,7 @@
 #include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "ui/aura/window_observer.h"
-#include "ui/gfx/display_observer.h"
+#include "ui/display/display_observer.h"
 #include "ui/wm/public/activation_change_observer.h"
 
 namespace aura {
@@ -40,7 +40,7 @@
                              public aura::WindowObserver,
                              public BrowserTabStripTrackerDelegate,
                              public chrome::BrowserListObserver,
-                             public gfx::DisplayObserver,
+                             public display::DisplayObserver,
                              public TabStripModelObserver {
  public:
   explicit BrowserStatusMonitor(ChromeLauncherController* launcher_controller);
@@ -76,10 +76,10 @@
   void OnBrowserAdded(Browser* browser) override;
   void OnBrowserRemoved(Browser* browser) override;
 
-  // gfx::DisplayObserver overrides:
-  void OnDisplayAdded(const gfx::Display& new_display) override;
-  void OnDisplayRemoved(const gfx::Display& old_display) override;
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  // display::DisplayObserver overrides:
+  void OnDisplayAdded(const display::Display& new_display) override;
+  void OnDisplayRemoved(const display::Display& old_display) override;
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t metrics) override;
 
   // TabStripModelObserver overrides:
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index dc5f45bc..546ac11 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -125,8 +125,8 @@
 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) {
   aura::Window* root_window =
       shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
-  gfx::Display display =
-      gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
   DCHECK(display.is_valid());
   return display.id();
 }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
index 057118d..b2fe61f9 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -1764,8 +1764,9 @@
   // Open the app list menu and check that the drag and drop host was set.
   gfx::Rect app_list_bounds =
       test.shelf_view()->GetAppListButtonView()->GetBoundsInScreen();
-  gfx::Display display =
-      gfx::Screen::GetScreen()->GetDisplayNearestWindow(secondary_root_window);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(
+          secondary_root_window);
   const gfx::Point& origin = display.bounds().origin();
   app_list_bounds.Offset(-origin.x(), -origin.y());
 
diff --git a/chrome/browser/ui/ash/launcher/chrome_mash_shelf_controller.cc b/chrome/browser/ui/ash/launcher/chrome_mash_shelf_controller.cc
index 64f664b..c212264 100644
--- a/chrome/browser/ui/ash/launcher/chrome_mash_shelf_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_mash_shelf_controller.cc
@@ -11,7 +11,7 @@
 #include "services/shell/public/cpp/connector.h"
 #include "skia/public/type_converters.h"
 #include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 class ChromeShelfItemDelegate : public mash::shelf::mojom::ShelfItemDelegate {
  public:
@@ -64,7 +64,7 @@
 
   // Set shelf alignment and auto-hide behavior from preferences.
   Profile* profile = ProfileManager::GetActiveUserProfile();
-  int64_t display_id = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   shelf_controller_->SetAlignment(static_cast<mash::shelf::mojom::Alignment>(
       ash::GetShelfAlignmentPref(profile->GetPrefs(), display_id)));
   shelf_controller_->SetAutoHideBehavior(
@@ -94,15 +94,16 @@
 
 void ChromeMashShelfController::OnAlignmentChanged(
     mash::shelf::mojom::Alignment alignment) {
-  ash::SetShelfAlignmentPref(ProfileManager::GetActiveUserProfile()->GetPrefs(),
-                             gfx::Screen::GetScreen()->GetPrimaryDisplay().id(),
-                             static_cast<ash::wm::ShelfAlignment>(alignment));
+  ash::SetShelfAlignmentPref(
+      ProfileManager::GetActiveUserProfile()->GetPrefs(),
+      display::Screen::GetScreen()->GetPrimaryDisplay().id(),
+      static_cast<ash::wm::ShelfAlignment>(alignment));
 }
 
 void ChromeMashShelfController::OnAutoHideBehaviorChanged(
     mash::shelf::mojom::AutoHideBehavior auto_hide) {
   ash::SetShelfAutoHideBehaviorPref(
       ProfileManager::GetActiveUserProfile()->GetPrefs(),
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().id(),
+      display::Screen::GetScreen()->GetPrimaryDisplay().id(),
       static_cast<ash::ShelfAutoHideBehavior>(auto_hide));
 }
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
index 6a8c8e5..c728eed 100644
--- a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
+++ b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
@@ -143,7 +143,7 @@
     return true;
   gfx::Rect bounds = window->GetBoundsInRootWindow();
   gfx::Rect work_area =
-      gfx::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
+      display::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
   bounds.Intersect(work_area);
   return work_area == bounds;
 }
diff --git a/chrome/browser/ui/ash/window_positioner_unittest.cc b/chrome/browser/ui/ash/window_positioner_unittest.cc
index 0dab8c3..7688c891 100644
--- a/chrome/browser/ui/ash/window_positioner_unittest.cc
+++ b/chrome/browser/ui/ash/window_positioner_unittest.cc
@@ -21,7 +21,7 @@
 #include "ui/aura/env.h"
 #include "ui/aura/test/test_windows.h"
 #include "ui/aura/window_event_dispatcher.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace ash {
 namespace test {
@@ -101,7 +101,7 @@
 
 TEST_F(WindowPositionerTest, cascading) {
   const gfx::Rect work_area =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().work_area();
+      display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
 
   // First see that the window will cascade down when there is no space.
   window()->SetBounds(work_area);
@@ -162,7 +162,7 @@
 
 TEST_F(WindowPositionerTest, filling) {
   const gfx::Rect work_area =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().work_area();
+      display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
   gfx::Rect popup_position(0, 0, 256, 128);
   // Leave space on the left and the right and see if we fill top to bottom.
   window()->SetBounds(gfx::Rect(work_area.x() + popup_position.width(),
@@ -217,7 +217,7 @@
 
 TEST_F(WindowPositionerTest, biggerThenBorder) {
   const gfx::Rect work_area =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().work_area();
+      display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
 
   gfx::Rect pop_position(0, 0, work_area.width(), work_area.height());
 
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
index e788642..4980ba82 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
@@ -39,6 +39,7 @@
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/test_personal_data_manager.h"
 #include "components/autofill/core/browser/validation.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
@@ -828,12 +829,12 @@
 // Ensure that expired cards trigger invalid suggestions.
 IN_PROC_BROWSER_TEST_F(AutofillDialogControllerTest, ExpiredCard) {
   CreditCard verified_card(test::GetCreditCard());
-  verified_card.set_origin("Chrome settings");
+  verified_card.set_origin(kSettingsOrigin);
   ASSERT_TRUE(verified_card.IsVerified());
   controller()->GetTestingManager()->AddTestingCreditCard(&verified_card);
 
   CreditCard expired_card(test::GetCreditCard());
-  expired_card.set_origin("Chrome settings");
+  expired_card.set_origin(kSettingsOrigin);
   expired_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2007"));
   ASSERT_TRUE(expired_card.IsVerified());
   ASSERT_FALSE(
@@ -995,7 +996,7 @@
   // Set up an expired card.
   CreditCard card;
   test::SetCreditCardInfo(&card, "Roy Demeo", "4111111111111111", "8", "2013");
-  card.set_origin("Chrome settings");
+  card.set_origin(kSettingsOrigin);
   ASSERT_TRUE(card.IsVerified());
 
   // Add the card and check that there's a menu for that section.
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
index 24e2b5a..dadef1e4 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
@@ -40,6 +40,7 @@
 #include "components/autofill/core/browser/country_names.h"
 #include "components/autofill/core/browser/test_personal_data_manager.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/form_data.h"
@@ -103,7 +104,6 @@
       "shipping country",
       "shipping tel",
     };
-const char kSettingsOrigin[] = "Chrome settings";
 const char kTestCCNumberAmex[] = "376200000000002";
 const char kTestCCNumberVisa[] = "4111111111111111";
 const char kTestCCNumberMaster[] = "5555555555554444";
@@ -1724,7 +1724,7 @@
   CreditCard visa_card(test::GetVerifiedCreditCard());
   CreditCard amex_card(test::GetVerifiedCreditCard2());
 
-  CreditCard master_card(base::GenerateGUID(), "chrome settings");
+  CreditCard master_card(base::GenerateGUID(), kSettingsOrigin);
   test::SetCreditCardInfo(
       &master_card, "Mr Foo", "5105105105105100", "07", "2099");
 
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
index de805b6..f606678 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -26,7 +26,6 @@
 #include "content/public/browser/web_contents.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/text_utils.h"
 
diff --git a/chrome/browser/ui/autofill/popup_view_common.cc b/chrome/browser/ui/autofill/popup_view_common.cc
index a342aac..c51de2b 100644
--- a/chrome/browser/ui/autofill/popup_view_common.cc
+++ b/chrome/browser/ui/autofill/popup_view_common.cc
@@ -7,21 +7,22 @@
 #include <algorithm>
 #include <utility>
 
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/vector2d.h"
-#include "ui/gfx/screen.h"
 
 namespace autofill {
 
 namespace {
 
-std::pair<int, int> CalculatePopupXAndWidth(const gfx::Display& left_display,
-                                            const gfx::Display& right_display,
-                                            int popup_required_width,
-                                            const gfx::Rect element_bounds,
-                                            bool is_rtl) {
+std::pair<int, int> CalculatePopupXAndWidth(
+    const display::Display& left_display,
+    const display::Display& right_display,
+    int popup_required_width,
+    const gfx::Rect& element_bounds,
+    bool is_rtl) {
   int leftmost_display_x = left_display.bounds().x();
   int rightmost_display_x =
       right_display.GetSizeInPixel().width() + right_display.bounds().x();
@@ -58,10 +59,11 @@
 
 // Calculates the height of the popup and the y position of it. These values
 // will stay on the screen.
-std::pair<int, int> CalculatePopupYAndHeight(const gfx::Display& top_display,
-                                             const gfx::Display& bottom_display,
-                                             int popup_required_height,
-                                             const gfx::Rect element_bounds) {
+std::pair<int, int> CalculatePopupYAndHeight(
+    const display::Display& top_display,
+    const display::Display& bottom_display,
+    int popup_required_height,
+    const gfx::Rect& element_bounds) {
   int topmost_display_y = top_display.bounds().y();
   int bottommost_display_y =
       bottom_display.GetSizeInPixel().height() + bottom_display.bounds().y();
@@ -110,9 +112,9 @@
       element_bounds.origin() +
       gfx::Vector2d(desired_width, element_bounds.height() + desired_height);
 
-  gfx::Display top_left_display =
+  display::Display top_left_display =
       GetDisplayNearestPoint(top_left_corner_of_popup, container_view);
-  gfx::Display bottom_right_display =
+  display::Display bottom_right_display =
       GetDisplayNearestPoint(bottom_right_corner_of_popup, container_view);
 
   std::pair<int, int> popup_x_and_width =
@@ -125,10 +127,10 @@
                    popup_x_and_width.second, popup_y_and_height.second);
 }
 
-gfx::Display PopupViewCommon::GetDisplayNearestPoint(
+display::Display PopupViewCommon::GetDisplayNearestPoint(
     const gfx::Point& point,
     gfx::NativeView container_view) {
-  return gfx::Screen::GetScreen()->GetDisplayNearestPoint(point);
+  return display::Screen::GetScreen()->GetDisplayNearestPoint(point);
 }
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/popup_view_common.h b/chrome/browser/ui/autofill/popup_view_common.h
index 42b2369..f885a18 100644
--- a/chrome/browser/ui/autofill/popup_view_common.h
+++ b/chrome/browser/ui/autofill/popup_view_common.h
@@ -14,6 +14,10 @@
 class Rect;
 }
 
+namespace display {
+using Display = gfx::Display;
+}
+
 namespace autofill {
 
 // Provides utility functions for popup-style views.
@@ -31,8 +35,9 @@
  protected:
   // A helper function to get the display closest to the given point (virtual
   // for testing).
-  virtual gfx::Display GetDisplayNearestPoint(const gfx::Point& point,
-                                              gfx::NativeView container_view);
+  virtual display::Display GetDisplayNearestPoint(
+      const gfx::Point& point,
+      gfx::NativeView container_view);
 };
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/popup_view_common_unittest.cc b/chrome/browser/ui/autofill/popup_view_common_unittest.cc
index a71c25f..003d37d 100644
--- a/chrome/browser/ui/autofill/popup_view_common_unittest.cc
+++ b/chrome/browser/ui/autofill/popup_view_common_unittest.cc
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/browser/web_contents.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace autofill {
@@ -21,16 +21,17 @@
 // Test class which overrides specific behavior for testing.
 class TestPopupViewCommon : public PopupViewCommon {
  public:
-  explicit TestPopupViewCommon(const gfx::Display& display)
+  explicit TestPopupViewCommon(const display::Display& display)
       : display_(display) {}
 
-  gfx::Display GetDisplayNearestPoint(const gfx::Point& point,
-                                      gfx::NativeView container_view) override {
+  display::Display GetDisplayNearestPoint(
+      const gfx::Point& point,
+      gfx::NativeView container_view) override {
     return display_;
   }
 
  private:
-  gfx::Display display_;
+  display::Display display_;
 };
 
 }  // namespace
@@ -49,8 +50,8 @@
   int desired_height = 16;
 
   // Set up the visible screen space.
-  gfx::Display display(0,
-                       gfx::Rect(0, 0, 2 * desired_width, 2 * desired_height));
+  display::Display display(
+      0, gfx::Rect(0, 0, 2 * desired_width, 2 * desired_height));
   TestPopupViewCommon view_common(display);
 
   struct {
diff --git a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
index 3a624e5..93e5ec0 100644
--- a/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
+++ b/chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.mm
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/i18n/number_formatting.h"
 #include "base/message_loop/message_loop.h"
-#include "base/profiler/scoped_tracker.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h
index 3b2fff9..ddc16bd 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h
@@ -40,7 +40,9 @@
   FRIEND_TEST_ALL_PREFIXES(PermissionBubbleBrowserTest,
                            HasLocationBarByDefault);
   FRIEND_TEST_ALL_PREFIXES(PermissionBubbleBrowserTest,
-                           FullscreenHasLocationBar);
+                           BrowserFullscreenHasLocationBar);
+  FRIEND_TEST_ALL_PREFIXES(PermissionBubbleBrowserTest,
+                           TabFullscreenHasLocationBar);
   FRIEND_TEST_ALL_PREFIXES(PermissionBubbleBrowserTest, AppHasNoLocationBar);
   FRIEND_TEST_ALL_PREFIXES(PermissionBubbleKioskBrowserTest,
                            KioskHasNoLocationBar);
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa_browser_test.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa_browser_test.mm
index ba507dd..663b3f2 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa_browser_test.mm
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa_browser_test.mm
@@ -3,36 +3,79 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_window.h"
-#import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#include "chrome/browser/ui/browser_commands_mac.h"
 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h"
 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h"
+#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/website_settings/permission_bubble_browser_test_util.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
 #import "testing/gtest_mac.h"
-#import "ui/base/cocoa/fullscreen_window_manager.h"
+#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
 
 IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest, HasLocationBarByDefault) {
   PermissionBubbleCocoa bubble(browser());
   bubble.SetDelegate(test_delegate());
   bubble.Show(requests(), accept_states());
-  EXPECT_TRUE([bubble.bubbleController_ hasLocationBar]);
+  EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
   bubble.Hide();
 }
 
-IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest, FullscreenHasLocationBar) {
+IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest,
+                       BrowserFullscreenHasLocationBar) {
+  ui::test::ScopedFakeNSWindowFullscreen faker;
+
   PermissionBubbleCocoa bubble(browser());
   bubble.SetDelegate(test_delegate());
   bubble.Show(requests(), accept_states());
+  EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
 
-  NSWindow* window = browser()->window()->GetNativeWindow();
-  base::scoped_nsobject<FullscreenWindowManager> manager(
-      [[FullscreenWindowManager alloc] initWithWindow:window
-                                        desiredScreen:[NSScreen mainScreen]]);
-  EXPECT_TRUE([bubble.bubbleController_ hasLocationBar]);
-  [manager enterFullscreenMode];
-  EXPECT_TRUE([bubble.bubbleController_ hasLocationBar]);
-  [manager exitFullscreenMode];
-  EXPECT_TRUE([bubble.bubbleController_ hasLocationBar]);
+  FullscreenController* controller =
+      browser()->exclusive_access_manager()->fullscreen_controller();
+  controller->ToggleBrowserFullscreenMode();
+  faker.FinishTransition();
+
+  // The location bar should be visible if the toolbar is set to be visible in
+  // fullscreen mode.
+  PrefService* prefs = browser()->profile()->GetPrefs();
+  bool show_toolbar = prefs->GetBoolean(prefs::kShowFullscreenToolbar);
+  EXPECT_EQ(show_toolbar, [bubble.bubbleController_ hasVisibleLocationBar]);
+
+  // Toggle the value of the preference.
+  chrome::ToggleFullscreenToolbar(browser());
+  EXPECT_EQ(!show_toolbar, [bubble.bubbleController_ hasVisibleLocationBar]);
+
+  // Put the setting back the way it started.
+  chrome::ToggleFullscreenToolbar(browser());
+  controller->ToggleBrowserFullscreenMode();
+  faker.FinishTransition();
+
+  EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
+  bubble.Hide();
+}
+
+IN_PROC_BROWSER_TEST_F(PermissionBubbleBrowserTest,
+                       TabFullscreenHasLocationBar) {
+  ui::test::ScopedFakeNSWindowFullscreen faker;
+
+  PermissionBubbleCocoa bubble(browser());
+  bubble.SetDelegate(test_delegate());
+  bubble.Show(requests(), accept_states());
+  EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
+
+  FullscreenController* controller =
+      browser()->exclusive_access_manager()->fullscreen_controller();
+  controller->EnterFullscreenModeForTab(
+      browser()->tab_strip_model()->GetActiveWebContents(), GURL());
+  faker.FinishTransition();
+
+  EXPECT_FALSE([bubble.bubbleController_ hasVisibleLocationBar]);
+  controller->ExitFullscreenModeForTab(
+      browser()->tab_strip_model()->GetActiveWebContents());
+  faker.FinishTransition();
+
+  EXPECT_TRUE([bubble.bubbleController_ hasVisibleLocationBar]);
   bubble.Hide();
 }
 
@@ -41,7 +84,7 @@
   PermissionBubbleCocoa bubble(app_browser);
   bubble.SetDelegate(test_delegate());
   bubble.Show(requests(), accept_states());
-  EXPECT_FALSE([bubble.bubbleController_ hasLocationBar]);
+  EXPECT_FALSE([bubble.bubbleController_ hasVisibleLocationBar]);
   bubble.Hide();
 }
 
@@ -52,6 +95,6 @@
   PermissionBubbleCocoa bubble(browser());
   bubble.SetDelegate(test_delegate());
   bubble.Show(requests(), accept_states());
-  EXPECT_FALSE([bubble.bubbleController_ hasLocationBar]);
+  EXPECT_FALSE([bubble.bubbleController_ hasVisibleLocationBar]);
   bubble.Hide();
 }
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h
index 8d57f85..483db63c 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h
@@ -49,8 +49,8 @@
 // Should only be used outside this class for tests.
 - (NSPoint)getExpectedAnchorPoint;
 
-// Returns true of the browser has support for the location bar.
+// Returns true if the browser has a visible location bar.
 // Should only be used outside this class for tests.
-- (bool)hasLocationBar;
+- (bool)hasVisibleLocationBar;
 
 @end
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
index 0bcc1bd..ed03b08 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
@@ -25,10 +25,15 @@
 #include "chrome/browser/ui/cocoa/website_settings/permission_selector_button.h"
 #include "chrome/browser/ui/cocoa/website_settings/split_block_button.h"
 #include "chrome/browser/ui/cocoa/website_settings/website_settings_utils_cocoa.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
+#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
 #include "chrome/browser/ui/website_settings/permission_bubble_view.h"
 #include "chrome/browser/ui/website_settings/permission_menu_model.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/prefs/pref_service.h"
 #include "components/url_formatter/elide_url.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/user_metrics.h"
@@ -447,7 +452,7 @@
 
 - (NSPoint)getExpectedAnchorPoint {
   NSPoint anchor;
-  if ([self hasLocationBar]) {
+  if ([self hasVisibleLocationBar]) {
     LocationBarViewMac* location_bar =
         [[[self getExpectedParentWindow] windowController] locationBarBridge];
     anchor = location_bar->GetPageInfoBubblePoint();
@@ -461,12 +466,31 @@
                                             anchor);
 }
 
-- (bool)hasLocationBar {
-  return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
+- (bool)hasVisibleLocationBar {
+  if (!browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR))
+    return false;
+
+  if (!browser_->exclusive_access_manager()->context()->IsFullscreen())
+    return true;
+
+  // If the browser is in browser-initiated full screen, a preference can cause
+  // the toolbar to be hidden.
+  if (browser_->exclusive_access_manager()
+          ->fullscreen_controller()
+          ->IsFullscreenForBrowser()) {
+    PrefService* prefs = browser_->profile()->GetPrefs();
+    bool show_toolbar = prefs->GetBoolean(prefs::kShowFullscreenToolbar);
+    return show_toolbar;
+  }
+
+  // Otherwise this is fullscreen without a toolbar, so there is no visible
+  // location bar.
+  return false;
 }
 
 - (info_bubble::BubbleArrowLocation)getExpectedArrowLocation {
-  return [self hasLocationBar] ? info_bubble::kTopLeft : info_bubble::kNoArrow;
+  return [self hasVisibleLocationBar] ? info_bubble::kTopLeft
+                                      : info_bubble::kNoArrow;
 }
 
 - (NSWindow*)getExpectedParentWindow {
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm
index 004dcd1..cea377c 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller_unittest.mm
@@ -48,14 +48,14 @@
 @end
 
 @implementation MockBubbleYesLocationBar
-- (bool)hasLocationBar { return true; }
+- (bool)hasVisibleLocationBar { return true; }
 @end
 
 @interface MockBubbleNoLocationBar : NSObject
 @end
 
 @implementation MockBubbleNoLocationBar
-- (bool)hasLocationBar { return false; }
+- (bool)hasVisibleLocationBar { return false; }
 @end
 
 namespace {
@@ -352,9 +352,8 @@
 
 TEST_F(PermissionBubbleControllerTest, AnchorPositionWithLocationBar) {
   base::mac::ScopedObjCClassSwizzler locationSwizzle(
-      [PermissionBubbleController class],
-      [MockBubbleYesLocationBar class],
-      @selector(hasLocationBar));
+      [PermissionBubbleController class], [MockBubbleYesLocationBar class],
+      @selector(hasVisibleLocationBar));
 
   NSPoint anchor = [controller_ getExpectedAnchorPoint];
 
@@ -370,9 +369,8 @@
 
 TEST_F(PermissionBubbleControllerTest, AnchorPositionWithoutLocationBar) {
   base::mac::ScopedObjCClassSwizzler locationSwizzle(
-      [PermissionBubbleController class],
-      [MockBubbleNoLocationBar class],
-      @selector(hasLocationBar));
+      [PermissionBubbleController class], [MockBubbleNoLocationBar class],
+      @selector(hasVisibleLocationBar));
 
   NSPoint anchor = [controller_ getExpectedAnchorPoint];
 
@@ -389,18 +387,16 @@
   NSPoint withLocationBar;
   {
     base::mac::ScopedObjCClassSwizzler locationSwizzle(
-        [PermissionBubbleController class],
-        [MockBubbleYesLocationBar class],
-        @selector(hasLocationBar));
+        [PermissionBubbleController class], [MockBubbleYesLocationBar class],
+        @selector(hasVisibleLocationBar));
     withLocationBar = [controller_ getExpectedAnchorPoint];
   }
 
   NSPoint withoutLocationBar;
   {
     base::mac::ScopedObjCClassSwizzler locationSwizzle(
-        [PermissionBubbleController class],
-        [MockBubbleNoLocationBar class],
-        @selector(hasLocationBar));
+        [PermissionBubbleController class], [MockBubbleNoLocationBar class],
+        @selector(hasVisibleLocationBar));
     withoutLocationBar = [controller_ getExpectedAnchorPoint];
   }
 
diff --git a/chrome/browser/ui/ime/ime_window.cc b/chrome/browser/ui/ime/ime_window.cc
index 5f45f42..3fd264a4 100644
--- a/chrome/browser/ui/ime/ime_window.cc
+++ b/chrome/browser/ui/ime/ime_window.cc
@@ -17,8 +17,8 @@
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/manifest_handlers/icons_handler.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/image/image.h"
-#include "ui/gfx/screen.h"
 
 namespace {
 
@@ -99,7 +99,7 @@
     return;
 
   gfx::Rect screen_bounds =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
   gfx::Rect window_bounds = native_window_->GetBounds();
   int screen_width = screen_bounds.width();
   int screen_height = screen_bounds.height();
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
index f563334..433fc9d4 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -41,8 +41,8 @@
 #include "third_party/skia/include/core/SkShader.h"
 #include "ui/base/material_design/material_design_controller.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/display/display.h"
 #include "ui/gfx/canvas.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image.h"
@@ -1382,8 +1382,8 @@
 }
 
 float Gtk2UI::GetDeviceScaleFactor() const {
-  if (gfx::Display::HasForceDeviceScaleFactor())
-    return gfx::Display::GetForcedDeviceScaleFactor();
+  if (display::Display::HasForceDeviceScaleFactor())
+    return display::Display::GetForcedDeviceScaleFactor();
   const int kCSSDefaultDPI = 96;
   const float scale = GetDPI() / kCSSDefaultDPI;
 
diff --git a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
index 412c37e..6dc1ae7 100644
--- a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
+++ b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
@@ -23,6 +23,7 @@
         '../../../../ui/aura/aura.gyp:aura',
         '../../../../ui/base/ime/ui_base_ime.gyp:ui_base_ime',
         '../../../../ui/base/ui_base.gyp:ui_base',
+        '../../../../ui/base/x/ui_base_x.gyp:ui_base_x',
         '../../../../ui/events/events.gyp:events',
         '../../../../ui/events/events.gyp:events_base',
         '../../../../ui/events/keycodes/events_keycodes.gyp:keycodes_x11',
diff --git a/chrome/browser/ui/panels/display_settings_provider.cc b/chrome/browser/ui/panels/display_settings_provider.cc
index 039d6ce..1f5f064 100644
--- a/chrome/browser/ui/panels/display_settings_provider.cc
+++ b/chrome/browser/ui/panels/display_settings_provider.cc
@@ -8,7 +8,7 @@
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "chrome/browser/fullscreen.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace {
 // The polling interval to check any display settings change, like full-screen
@@ -66,16 +66,16 @@
 
 // TODO(scottmg): This should be moved to ui/.
 gfx::Rect DisplaySettingsProvider::GetPrimaryDisplayArea() const {
-  return gfx::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+  return display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
 }
 
 gfx::Rect DisplaySettingsProvider::GetPrimaryWorkArea() const {
 #if defined(OS_MACOSX)
   // On OSX, panels should be dropped all the way to the bottom edge of the
   // screen (and overlap Dock). And we also want to exclude the system menu
-  // area. Note that the rect returned from gfx::Screen util functions is in
+  // area. Note that the rect returned from display::Screen util functions is in
   // platform-independent screen coordinates with (0, 0) as the top-left corner.
-  gfx::Display display = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+  display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
   gfx::Rect display_area = display.bounds();
   gfx::Rect work_area = display.work_area();
   int system_menu_height = work_area.y() - display_area.y();
@@ -85,19 +85,19 @@
   }
   return display_area;
 #else
-  return gfx::Screen::GetScreen()->GetPrimaryDisplay().work_area();
+  return display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
 #endif
 }
 
 gfx::Rect DisplaySettingsProvider::GetDisplayAreaMatching(
     const gfx::Rect& bounds) const {
-  return gfx::Screen::GetScreen()->GetDisplayMatching(bounds).bounds();
+  return display::Screen::GetScreen()->GetDisplayMatching(bounds).bounds();
 }
 
 gfx::Rect DisplaySettingsProvider::GetWorkAreaMatching(
     const gfx::Rect& bounds) const {
-  gfx::Screen* screen = gfx::Screen::GetScreen();
-  gfx::Display display = screen->GetDisplayMatching(bounds);
+  display::Screen* screen = display::Screen::GetScreen();
+  display::Display display = screen->GetDisplayMatching(bounds);
   if (display.bounds() == screen->GetPrimaryDisplay().bounds())
     return GetPrimaryWorkArea();
   return display.work_area();
diff --git a/chrome/browser/ui/panels/panel_browsertest.cc b/chrome/browser/ui/panels/panel_browsertest.cc
index 4257883..66125ec 100644
--- a/chrome/browser/ui/panels/panel_browsertest.cc
+++ b/chrome/browser/ui/panels/panel_browsertest.cc
@@ -49,7 +49,6 @@
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/keycodes/dom/dom_code.h"
-#include "ui/gfx/screen.h"
 
 using content::WebContents;
 
diff --git a/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc b/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc
index dab6dccb..f898c179 100644
--- a/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc
+++ b/chrome/browser/ui/panels/panel_mouse_watcher_timer.cc
@@ -6,7 +6,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 // A timer based implementation of PanelMouseWatcher.  Currently used for Gtk
 // and Mac panels implementations.
@@ -66,7 +66,7 @@
 }
 
 gfx::Point PanelMouseWatcherTimer::GetMousePosition() const {
-  return gfx::Screen::GetScreen()->GetCursorScreenPoint();
+  return display::Screen::GetScreen()->GetCursorScreenPoint();
 }
 
 void PanelMouseWatcherTimer::DoWork() {
diff --git a/chrome/browser/ui/passwords/password_manager_presenter.cc b/chrome/browser/ui/passwords/password_manager_presenter.cc
index 3c8a512..aa72308 100644
--- a/chrome/browser/ui/passwords/password_manager_presenter.cc
+++ b/chrome/browser/ui/passwords/password_manager_presenter.cc
@@ -76,11 +76,11 @@
 // Creates key for sorting password or password exception entries.
 // The key is eTLD+1 followed by subdomains
 // (e.g. secure.accounts.example.com => example.com.accounts.secure).
-// If |username_and_password_in_key == true|, username and password is appended
-// to the key. The entry type code (non-Android, Android w/ or w/o affiliated
-// web realm) is also appended to the key.
+// If |entry_type == SAVED|, username, password and federation are appended to
+// the key. The entry type code (non-Android, Android w/ or w/o affiliated web
+// realm) is also appended to the key.
 std::string CreateSortKey(const autofill::PasswordForm& form,
-                          bool username_and_password_in_key) {
+                          PasswordEntryType entry_type) {
   bool is_android_uri = false;
   bool is_clickable = false;
   GURL link_url;
@@ -102,10 +102,12 @@
       site_name + SplitByDotAndReverse(StringPiece(
                       &origin[0], origin.length() - site_name.length()));
 
-  if (username_and_password_in_key) {
+  if (entry_type == PasswordEntryType::SAVED) {
     key = key + kSortKeyPartsSeparator +
           base::UTF16ToUTF8(form.username_value) + kSortKeyPartsSeparator +
           base::UTF16ToUTF8(form.password_value);
+    if (!form.federation_origin.unique())
+      key = key + kSortKeyPartsSeparator + form.federation_origin.host();
   }
 
   // Since Android and non-Android entries shouldn't be merged into one entry,
@@ -120,9 +122,8 @@
 void RemoveDuplicates(const autofill::PasswordForm& form,
                       DuplicatesMap* duplicates,
                       PasswordStore* store,
-                      bool username_and_password_in_key) {
-  std::string key =
-      CreateSortKey(form, username_and_password_in_key);
+                      PasswordEntryType entry_type) {
+  std::string key = CreateSortKey(form, entry_type);
   std::pair<DuplicatesMap::iterator, DuplicatesMap::iterator> dups =
       duplicates->equal_range(key);
   for (DuplicatesMap::iterator it = dups.first; it != dups.second; ++it)
@@ -190,8 +191,8 @@
   if (!store)
     return;
 
-  RemoveDuplicates(*password_list_[index], &password_duplicates_,
-                   store, true);
+  RemoveDuplicates(*password_list_[index], &password_duplicates_, store,
+                   PasswordEntryType::SAVED);
   store->RemoveLogin(*password_list_[index]);
   content::RecordAction(
       base::UserMetricsAction("PasswordManager_RemoveSavedPassword"));
@@ -209,7 +210,8 @@
   if (!store)
     return;
   RemoveDuplicates(*password_exception_list_[index],
-                   &password_exception_duplicates_, store, false);
+                   &password_exception_duplicates_, store,
+                   PasswordEntryType::BLACKLISTED);
   store->RemoveLogin(*password_exception_list_[index]);
   content::RecordAction(
       base::UserMetricsAction("PasswordManager_RemovePasswordException"));
@@ -299,13 +301,13 @@
 void PasswordManagerPresenter::SortEntriesAndHideDuplicates(
     std::vector<std::unique_ptr<autofill::PasswordForm>>* list,
     DuplicatesMap* duplicates,
-    bool username_and_password_in_key) {
+    PasswordEntryType entry_type) {
   std::vector<std::pair<std::string, std::unique_ptr<autofill::PasswordForm>>>
       pairs;
   pairs.reserve(list->size());
   for (auto& form : *list) {
-    pairs.push_back(std::make_pair(
-        CreateSortKey(*form, username_and_password_in_key), std::move(form)));
+    pairs.push_back(
+        std::make_pair(CreateSortKey(*form, entry_type), std::move(form)));
   }
 
   std::sort(
@@ -375,7 +377,7 @@
       password_manager_util::ConvertScopedVector(std::move(results));
   page_->SortEntriesAndHideDuplicates(&page_->password_list_,
                                       &page_->password_duplicates_,
-                                      true /* use username and password */);
+                                      PasswordEntryType::SAVED);
   page_->SetPasswordList();
 }
 
@@ -399,7 +401,7 @@
   page_->password_exception_list_ =
       password_manager_util::ConvertScopedVector(std::move(results));
   page_->SortEntriesAndHideDuplicates(&page_->password_exception_list_,
-      &page_->password_exception_duplicates_,
-      false /* don't use username and password*/);
+                                      &page_->password_exception_duplicates_,
+                                      PasswordEntryType::BLACKLISTED);
   page_->SetPasswordExceptionList();
 }
diff --git a/chrome/browser/ui/passwords/password_manager_presenter.h b/chrome/browser/ui/passwords/password_manager_presenter.h
index fd2ac72..293adb0 100644
--- a/chrome/browser/ui/passwords/password_manager_presenter.h
+++ b/chrome/browser/ui/passwords/password_manager_presenter.h
@@ -27,6 +27,8 @@
 using DuplicatesMap =
     std::multimap<std::string, std::unique_ptr<autofill::PasswordForm>>;
 
+enum class PasswordEntryType { SAVED, BLACKLISTED };
+
 class PasswordUIView;
 
 class Profile;
@@ -83,14 +85,14 @@
 
   // Sort entries of |list| based on sort key. The key is the concatenation of
   // origin, entry type (non-Android credential, Android w/ affiliated web realm
-  // or Android w/o affiliated web realm). If |username_and_password_in_key|,
-  // username and password are also included in sort key. If there are several
-  // forms with the same key, all such forms but the first one are
+  // or Android w/o affiliated web realm). If |entry_type == SAVED|,
+  // username, password and federation are also included in sort key. If there
+  // are several forms with the same key, all such forms but the first one are
   // stored in |duplicates| instead of |list|.
   void SortEntriesAndHideDuplicates(
       std::vector<std::unique_ptr<autofill::PasswordForm>>* list,
       DuplicatesMap* duplicates,
-      bool username_and_password_in_key);
+      PasswordEntryType entry_type);
 
   // Returns the password store associated with the currently active profile.
   password_manager::PasswordStore* GetPasswordStore();
diff --git a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
index d0855f84..f813769 100644
--- a/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
+++ b/chrome/browser/ui/passwords/password_manager_presenter_unittest.cc
@@ -30,6 +30,7 @@
   const char* const username;
   const char* const password;
   const char* const affiliated_web_realm;
+  const char* const federation;
   const int expected_position;
 };
 
@@ -90,7 +91,7 @@
   MockPasswordUIView* GetUIController() { return mock_controller_.get(); }
   void SortAndCheckPositions(const SortEntry test_entries[],
                              size_t number_of_entries,
-                             bool username_and_password_in_key);
+                             PasswordEntryType entry_type);
 
  private:
   content::TestBrowserThreadBundle thread_bundle_;
@@ -129,7 +130,7 @@
 void PasswordManagerPresenterTest::SortAndCheckPositions(
     const SortEntry test_entries[],
     size_t number_of_entries,
-    bool username_and_password_in_key) {
+    PasswordEntryType entry_type) {
   std::vector<std::unique_ptr<autofill::PasswordForm>> list;
   size_t expected_number_of_unique_entries = 0;
   for (size_t i = 0; i < number_of_entries; i++) {
@@ -137,9 +138,11 @@
     std::unique_ptr<autofill::PasswordForm> form(new autofill::PasswordForm());
     form->signon_realm = entry.origin;
     form->origin = GURL(base::ASCIIToUTF16(entry.origin));
-    if (username_and_password_in_key) {
+    if (entry_type == PasswordEntryType::SAVED) {
       form->username_value = base::ASCIIToUTF16(entry.username);
       form->password_value = base::ASCIIToUTF16(entry.password);
+      if (entry.federation != nullptr)
+        form->federation_origin = url::Origin(GURL(entry.federation));
     }
     if (entry.affiliated_web_realm)
       form->affiliated_web_realm = entry.affiliated_web_realm;
@@ -150,7 +153,7 @@
 
   DuplicatesMap duplicates;
   mock_controller_->GetPasswordManagerPresenter()->SortEntriesAndHideDuplicates(
-      &list, &duplicates, username_and_password_in_key);
+      &list, &duplicates, entry_type);
 
   ASSERT_EQ(expected_number_of_unique_entries, list.size());
   ASSERT_EQ(number_of_entries - expected_number_of_unique_entries,
@@ -162,11 +165,14 @@
                    << entry.expected_position);
       EXPECT_EQ(GURL(base::ASCIIToUTF16(entry.origin)),
                 list[entry.expected_position]->origin);
-      if (username_and_password_in_key) {
+      if (entry_type == PasswordEntryType::SAVED) {
         EXPECT_EQ(base::ASCIIToUTF16(entry.username),
                   list[entry.expected_position]->username_value);
         EXPECT_EQ(base::ASCIIToUTF16(entry.password),
                   list[entry.expected_position]->password_value);
+        if (entry.federation != nullptr)
+          EXPECT_EQ(url::Origin(GURL(entry.federation)),
+                    list[entry.expected_position]->federation_origin);
       }
     }
   }
@@ -221,63 +227,82 @@
 
 TEST_F(PasswordManagerPresenterTest, Sorting_DifferentOrigins) {
   const SortEntry test_cases[] = {
-      {"http://example-b.com", "user_a", "pwd", nullptr, 2},
-      {"http://example-a.com", "user_a1", "pwd", nullptr, 0},
-      {"http://example-a.com", "user_a2", "pwd", nullptr, 1},
-      {"http://example-c.com", "user_a", "pwd", nullptr, 3}};
-  SortAndCheckPositions(test_cases, arraysize(test_cases), true);
+      {"http://example-b.com", "user_a", "pwd", nullptr, nullptr, 2},
+      {"http://example-a.com", "user_a1", "pwd", nullptr, nullptr, 0},
+      {"http://example-a.com", "user_a2", "pwd", nullptr, nullptr, 1},
+      {"http://example-c.com", "user_a", "pwd", nullptr, nullptr, 3}};
+  SortAndCheckPositions(test_cases, arraysize(test_cases),
+                        PasswordEntryType::SAVED);
 }
 
 TEST_F(PasswordManagerPresenterTest, Sorting_DifferentUsernames) {
   const SortEntry test_cases[] = {
-      {"http://example.com", "user_a", "pwd", nullptr, 0},
-      {"http://example.com", "user_c", "pwd", nullptr, 2},
-      {"http://example.com", "user_b", "pwd", nullptr, 1}};
-  SortAndCheckPositions(test_cases, arraysize(test_cases), true);
+      {"http://example.com", "user_a", "pwd", nullptr, nullptr, 0},
+      {"http://example.com", "user_c", "pwd", nullptr, nullptr, 2},
+      {"http://example.com", "user_b", "pwd", nullptr, nullptr, 1}};
+  SortAndCheckPositions(test_cases, arraysize(test_cases),
+                        PasswordEntryType::SAVED);
 }
 
 TEST_F(PasswordManagerPresenterTest, Sorting_DifferentPasswords) {
   const SortEntry test_cases[] = {
-      {"http://example.com", "user_a", "1", nullptr, 0},
-      {"http://example.com", "user_a", "2", nullptr, 1},
-      {"http://example.com", "user_a", "3", nullptr, 2}};
-  SortAndCheckPositions(test_cases, arraysize(test_cases), true);
+      {"http://example.com", "user_a", "1", nullptr, nullptr, 0},
+      {"http://example.com", "user_a", "2", nullptr, nullptr, 1},
+      {"http://example.com", "user_a", "3", nullptr, nullptr, 2}};
+  SortAndCheckPositions(test_cases, arraysize(test_cases),
+                        PasswordEntryType::SAVED);
 }
 
 TEST_F(PasswordManagerPresenterTest, Sorting_HideDuplicates) {
   const SortEntry test_cases[] = {
-      {"http://example.com", "user_a", "pwd", nullptr, 0},
+      {"http://example.com", "user_a", "pwd", nullptr, nullptr, 0},
       // Different username.
-      {"http://example.com", "user_b", "pwd", nullptr, 2},
+      {"http://example.com", "user_b", "pwd", nullptr, nullptr, 2},
       // Different password.
-      {"http://example.com", "user_a", "secret", nullptr, 1},
+      {"http://example.com", "user_a", "secret", nullptr, nullptr, 1},
       // Different origin.
-      {"http://sub1.example.com", "user_a", "pwd", nullptr, 3},
-      {"http://example.com", "user_a", "pwd", nullptr, -1}  // Hide it.
+      {"http://sub1.example.com", "user_a", "pwd", nullptr, nullptr, 3},
+      {"http://example.com", "user_a", "pwd", nullptr, nullptr, -1}  // Hide it.
   };
-  SortAndCheckPositions(test_cases, arraysize(test_cases), true);
+  SortAndCheckPositions(test_cases, arraysize(test_cases),
+                        PasswordEntryType::SAVED);
 }
 
-TEST_F(PasswordManagerPresenterTest, Sorting_DontUseUsernameAndPasswordInKey) {
+TEST_F(PasswordManagerPresenterTest, Sorting_PasswordExceptions) {
   const SortEntry test_cases[] = {
-      {"http://example-b.com", nullptr, nullptr, nullptr, 1},
-      {"http://example-a.com", nullptr, nullptr, nullptr, 0},
-      {"http://example-a.com", nullptr, nullptr, nullptr, -1},  // Hide it.
-      {"http://example-c.com", nullptr, nullptr, nullptr, 2}};
-  SortAndCheckPositions(test_cases, arraysize(test_cases), false);
+      {"http://example-b.com", nullptr, nullptr, nullptr, nullptr, 1},
+      {"http://example-a.com", nullptr, nullptr, nullptr, nullptr, 0},
+      {"http://example-a.com", nullptr, nullptr, nullptr, nullptr,
+       -1},  // Hide it.
+      {"http://example-c.com", nullptr, nullptr, nullptr, nullptr, 2}};
+  SortAndCheckPositions(test_cases, arraysize(test_cases),
+                        PasswordEntryType::BLACKLISTED);
 }
 
 TEST_F(PasswordManagerPresenterTest, Sorting_AndroidCredentials) {
   const SortEntry test_cases[] = {
-      {"https://alpha.com", "user", "secret", nullptr, 0},
-      {"android://hash@com.alpha", "user", "secret", "https://alpha.com", 1},
-      {"android://hash@com.alpha", "user", "secret", "https://alpha.com", -1},
-      {"android://hash@com.alpha", "user", "secret", nullptr, 2},
-
+      {"https://alpha.com", "user", "secret", nullptr, nullptr, 0},
+      {"android://hash@com.alpha", "user", "secret", "https://alpha.com",
+       nullptr, 1},
+      {"android://hash@com.alpha", "user", "secret", "https://alpha.com",
+       nullptr, -1},
+      {"android://hash@com.alpha", "user", "secret", nullptr, nullptr, 2},
       {"android://hash@com.betta.android", "user", "secret",
-       "https://betta.com", 3},
-      {"android://hash@com.betta.android", "user", "secret", nullptr, 4}};
-  SortAndCheckPositions(test_cases, arraysize(test_cases), true);
+       "https://betta.com", nullptr, 3},
+      {"android://hash@com.betta.android", "user", "secret", nullptr, nullptr,
+       4}};
+  SortAndCheckPositions(test_cases, arraysize(test_cases),
+                        PasswordEntryType::SAVED);
+}
+
+TEST_F(PasswordManagerPresenterTest, Sorting_Federations) {
+  const SortEntry test_cases[] = {
+      {"https://example.com", "user", "secret", nullptr, nullptr, 0},
+      {"https://example.com", "user", "secret", nullptr, "https://fed1.com", 1},
+      {"https://example.com", "user", "secret", nullptr, "https://fed2.com",
+       2}};
+  SortAndCheckPositions(test_cases, arraysize(test_cases),
+                        PasswordEntryType::SAVED);
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_linux.cc b/chrome/browser/ui/views/app_list/linux/app_list_linux.cc
index 07b707d..8333480 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_linux.cc
+++ b/chrome/browser/ui/views/app_list/linux/app_list_linux.cc
@@ -7,13 +7,13 @@
 #include "build/build_config.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/views/app_list_view.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/widget/widget.h"
 
 // static
 AppListPositioner::ScreenEdge AppListLinux::ShelfLocationInDisplay(
-    const gfx::Display& display) {
+    const display::Display& display) {
   // On Linux, it is difficult to find the shelf (due to the large variety of
   // desktop environments). The shelf can usually be found on the edge where the
   // display edge and work area do not match up, but there can be more than one
@@ -52,7 +52,7 @@
 
 // static
 gfx::Point AppListLinux::FindAnchorPoint(const gfx::Size& view_size,
-                                         const gfx::Display& display,
+                                         const display::Display& display,
                                          const gfx::Point& cursor,
                                          AppListPositioner::ScreenEdge edge,
                                          bool center_window) {
@@ -84,9 +84,9 @@
 
 // static
 void AppListLinux::MoveNearCursor(app_list::AppListView* view) {
-  gfx::Screen* screen = gfx::Screen::GetScreen();
+  display::Screen* screen = display::Screen::GetScreen();
   gfx::Point cursor = screen->GetCursorScreenPoint();
-  gfx::Display display = screen->GetDisplayNearestPoint(cursor);
+  display::Display display = screen->GetDisplayNearestPoint(cursor);
 
   view->SetBubbleArrow(views::BubbleBorder::FLOAT);
 
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_linux.h b/chrome/browser/ui/views/app_list/linux/app_list_linux.h
index 1640b539..091c11e 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_linux.h
+++ b/chrome/browser/ui/views/app_list/linux/app_list_linux.h
@@ -17,6 +17,10 @@
 class Size;
 }  // namespace gfx
 
+namespace display {
+using Display = gfx::Display;
+}
+
 // Responsible for positioning an AppListView on Linux.
 // TODO(tapted): Shouldn't be a class - move the static member functions out.
 class AppListLinux {
@@ -25,7 +29,7 @@
   // the edge of the surface where the user normally launches apps from (so, for
   // example, on Gnome Classic, this is the applications menu, not the taskbar).
   static AppListPositioner::ScreenEdge ShelfLocationInDisplay(
-      const gfx::Display& display);
+      const display::Display& display);
 
   // Finds the position for a window to anchor it to the shelf. This chooses the
   // most appropriate position for the window based on whether the shelf exists,
@@ -33,7 +37,7 @@
   // coordinates for the center of the window. If |shelf_rect| is empty, assumes
   // there is no shelf on the given display.
   static gfx::Point FindAnchorPoint(const gfx::Size& view_size,
-                                    const gfx::Display& display,
+                                    const display::Display& display,
                                     const gfx::Point& cursor,
                                     AppListPositioner::ScreenEdge edge,
                                     bool center_window);
diff --git a/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc b/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc
index f3675ba..e381ec49 100644
--- a/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc
+++ b/chrome/browser/ui/views/app_list/linux/app_list_linux_unittest.cc
@@ -7,7 +7,7 @@
 #include "base/logging.h"
 #include "chrome/browser/ui/app_list/app_list_positioner.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
@@ -119,7 +119,7 @@
   }
 
  private:
-  gfx::Display display_;
+  display::Display display_;
   gfx::Point cursor_;
   bool center_window_;
 };
diff --git a/chrome/browser/ui/views/app_list/win/app_list_win.cc b/chrome/browser/ui/views/app_list/win/app_list_win.cc
index 462b627..4b08c48 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_win.cc
+++ b/chrome/browser/ui/views/app_list/win/app_list_win.cc
@@ -7,7 +7,7 @@
 #include "chrome/browser/ui/app_list/app_list_positioner.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/views/app_list_view.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/widget/widget.h"
 
 namespace {
@@ -44,7 +44,7 @@
 
 // static
 gfx::Point AppListWin::FindAnchorPoint(const gfx::Size& view_size,
-                                       const gfx::Display& display,
+                                       const display::Display& display,
                                        const gfx::Point& cursor,
                                        const gfx::Rect& taskbar_rect,
                                        bool center_window) {
@@ -79,9 +79,9 @@
 
 // static
 void AppListWin::MoveNearCursor(app_list::AppListView* view) {
-  gfx::Screen* screen = gfx::Screen::GetScreen();
+  display::Screen* screen = display::Screen::GetScreen();
   gfx::Point cursor = screen->GetCursorScreenPoint();
-  gfx::Display display = screen->GetDisplayNearestPoint(cursor);
+  display::Display display = screen->GetDisplayNearestPoint(cursor);
 
   view->SetBubbleArrow(views::BubbleBorder::FLOAT);
   gfx::Rect taskbar_rect;
diff --git a/chrome/browser/ui/views/app_list/win/app_list_win.h b/chrome/browser/ui/views/app_list/win/app_list_win.h
index 95b9903..5d530645 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_win.h
+++ b/chrome/browser/ui/views/app_list/win/app_list_win.h
@@ -16,6 +16,10 @@
 class Size;
 }
 
+namespace display {
+using Display = gfx::Display;
+}
+
 // Responsible for positioning an AppListView on Windows.
 // TODO(tapted): Shouldn't be a class - move the static member functions out.
 class AppListWin {
@@ -26,7 +30,7 @@
   // intended coordinates for the center of the window. If |taskbar_rect| is
   // empty, assumes there is no taskbar on the given display.
   static gfx::Point FindAnchorPoint(const gfx::Size& view_size,
-                                    const gfx::Display& display,
+                                    const display::Display& display,
                                     const gfx::Point& cursor,
                                     const gfx::Rect& taskbar_rect,
                                     bool center_window);
diff --git a/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc b/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc
index 00b18b7..2fd1932 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc
+++ b/chrome/browser/ui/views/app_list/win/app_list_win_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/ui/app_list/app_list_positioner.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
@@ -113,7 +113,7 @@
   }
 
  private:
-  gfx::Display display_;
+  display::Display display_;
   gfx::Point cursor_;
   gfx::Rect taskbar_rect_;
   bool center_window_;
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
index a14bb9d..655ba93 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.cc
@@ -117,16 +117,10 @@
 }
 
 void AppInfoHeaderPanel::OnAppImageLoaded(const gfx::Image& image) {
-  const SkBitmap* bitmap;
-  if (image.IsEmpty()) {
-    bitmap = &extensions::util::GetDefaultAppIcon()
-                  .GetRepresentation(gfx::ImageSkia::GetMaxSupportedScale())
-                  .sk_bitmap();
-  } else {
-    bitmap = image.ToSkBitmap();
-  }
-
-  app_icon_->SetImage(gfx::ImageSkia::CreateFrom1xBitmap(*bitmap));
+  if (image.IsEmpty())
+    app_icon_->SetImage(extensions::util::GetDefaultAppIcon());
+  else
+    app_icon_->SetImage(image.AsImageSkia());
 }
 
 void AppInfoHeaderPanel::ShowAppInWebStore() {
diff --git a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
index 430c294f..b1f8fd5 100644
--- a/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
+++ b/chrome/browser/ui/views/ash/chrome_browser_main_extra_parts_ash.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ui/views/ash/tab_scrubber.h"
 #include "chrome/common/chrome_switches.h"
 #include "ui/aura/env.h"
-#include "ui/gfx/screen.h"
 #include "ui/keyboard/content/keyboard.h"
 #include "ui/keyboard/keyboard_controller.h"
 
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
index 3a38f6c..a99bf1c4 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -143,7 +143,7 @@
 
   // Returns the tooltip text for the specified url and title. The returned
   // text is clipped to fit within the bounds of the monitor. |context| is
-  // used to determine which gfx::Screen is used to retrieve bounds.
+  // used to determine which display::Screen is used to retrieve bounds.
   //
   // Note that we adjust the direction of both the URL and the title based on
   // the locale so that pure LTR strings are displayed properly in RTL locales.
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
index 3206b65..ee236a4 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -9,7 +9,7 @@
 #include "components/constrained_window/constrained_window_views.h"
 
 #if defined(USE_AURA)
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/widget/desktop_aura/desktop_screen.h"
 #include "ui/wm/core/wm_state.h"
 #endif
@@ -36,6 +36,6 @@
 
 void ChromeBrowserMainExtraPartsViews::PreCreateThreads() {
 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
-  gfx::Screen::SetScreenInstance(views::CreateDesktopScreen());
+  display::Screen::SetScreenInstance(views::CreateDesktopScreen());
 #endif
 }
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 97484cc..b7ebc93 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
@@ -22,7 +22,7 @@
 #include "ui/base/ime/input_method_initializer.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/ui_base_switches.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/native_theme/native_theme_aura.h"
 #include "ui/native_theme/native_theme_dark_aura.h"
 #include "ui/views/linux_ui/linux_ui.h"
@@ -87,7 +87,7 @@
   // on unconditionally.
   views::LinuxUI::instance()->MaterialDesignControllerReady();
   views::LinuxUI::instance()->UpdateDeviceScaleFactor(
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
+      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
 }
 
 void ChromeBrowserMainExtraPartsViewsLinux::PreProfileInit() {
diff --git a/chrome/browser/ui/views/chrome_views_delegate.cc b/chrome/browser/ui/views/chrome_views_delegate.cc
index 2c9a6a9..f58dbd24 100644
--- a/chrome/browser/ui/views/chrome_views_delegate.cc
+++ b/chrome/browser/ui/views/chrome_views_delegate.cc
@@ -23,8 +23,8 @@
 #include "grit/chrome_unscaled_resources.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/ui_base_switches.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/controls/menu/menu_controller.h"
 #include "ui/views/widget/native_widget.h"
 #include "ui/views/widget/widget.h"
@@ -207,7 +207,7 @@
   window_preferences->SetBoolean("maximized",
                                  show_state == ui::SHOW_STATE_MAXIMIZED);
   window_preferences->SetBoolean("docked", show_state == ui::SHOW_STATE_DOCKED);
-  gfx::Rect work_area(gfx::Screen::GetScreen()
+  gfx::Rect work_area(display::Screen::GetScreen()
                           ->GetDisplayNearestWindow(window->GetNativeView())
                           .work_area());
   window_preferences->SetInteger("work_area_left", work_area.x());
@@ -248,7 +248,8 @@
   // On Ash environment, a window won't span across displays.  Adjust
   // the bounds to fit the work area.
   gfx::NativeView window = widget->GetNativeView();
-  gfx::Display display = gfx::Screen::GetScreen()->GetDisplayMatching(*bounds);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayMatching(*bounds);
   bounds->AdjustToFit(display.work_area());
   ash::wm::GetWindowState(window)->set_minimum_visibility(true);
 #endif
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
index 240e398..5c29216 100644
--- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc
+++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
@@ -25,7 +25,6 @@
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/animation/slide_animation.h"
 #include "ui/gfx/canvas.h"
-#include "ui/gfx/screen.h"
 #include "ui/native_theme/native_theme.h"
 #include "ui/strings/grit/ui_strings.h"
 #include "ui/views/bubble/bubble_border.h"
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.cc b/chrome/browser/ui/views/extensions/extension_dialog.cc
index edd0933..cf189bd3 100644
--- a/chrome/browser/ui/views/extensions/extension_dialog.cc
+++ b/chrome/browser/ui/views/extensions/extension_dialog.cc
@@ -18,7 +18,7 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/base_window.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/background.h"
 #include "ui/views/widget/widget.h"
 #include "url/gurl.h"
@@ -110,7 +110,7 @@
   // Ensure the top left and top right of the window are on screen, with
   // priority given to the top left.
   gfx::Rect screen_rect =
-      gfx::Screen::GetScreen()->GetDisplayNearestPoint(center).bounds();
+      display::Screen::GetScreen()->GetDisplayNearestPoint(center).bounds();
   gfx::Rect bounds_rect = gfx::Rect(x, y, width, height);
   bounds_rect.AdjustToFit(screen_rect);
   window->SetBounds(bounds_rect);
diff --git a/chrome/browser/ui/views/frame/browser_frame.cc b/chrome/browser/ui/views/frame/browser_frame.cc
index 32d0e94..77c573dd 100644
--- a/chrome/browser/ui/views/frame/browser_frame.cc
+++ b/chrome/browser/ui/views/frame/browser_frame.cc
@@ -26,7 +26,6 @@
 #include "ui/base/hit_test.h"
 #include "ui/events/event_handler.h"
 #include "ui/gfx/font_list.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/controls/menu/menu_runner.h"
 #include "ui/views/widget/native_widget.h"
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
index b9a9eb5..358ab57 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -12,7 +12,6 @@
 #include "ash/frame/frame_border_hit_test_controller.h"
 #include "ash/frame/header_painter_util.h"
 #include "ash/shell.h"
-#include "base/profiler/scoped_tracker.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/extensions/extension_util.h"
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc
index 8a83ec1..c5da9cc9 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc
@@ -6,7 +6,6 @@
 
 #include <algorithm>
 
-#include "base/profiler/scoped_tracker.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/profiles/profiles_state.h"
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index cd0ae9f..3ec6cdef 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -138,12 +138,12 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/theme_provider.h"
 #include "ui/content_accelerators/accelerator_util.h"
+#include "ui/display/screen.h"
 #include "ui/events/event_utils.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/scoped_canvas.h"
-#include "ui/gfx/screen.h"
 #include "ui/strings/grit/ui_strings.h"
 #include "ui/views/controls/button/menu_button.h"
 #include "ui/views/controls/textfield/textfield.h"
@@ -2625,7 +2625,7 @@
 }
 
 gfx::Point BrowserView::GetCursorPointInParent() const {
-  gfx::Point cursor_pos = gfx::Screen::GetScreen()->GetCursorScreenPoint();
+  gfx::Point cursor_pos = display::Screen::GetScreen()->GetCursorScreenPoint();
   views::View::ConvertPointFromScreen(GetWidget()->GetRootView(), &cursor_pos);
   return cursor_pos;
 }
diff --git a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
index f084a6b..1444b31c 100644
--- a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
@@ -15,7 +15,7 @@
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #endif
 
 using views::FocusManager;
@@ -81,7 +81,7 @@
   window->SetBounds(original_bounds);
   window->Show();
   // Dock the browser window using |kShowStateKey| property.
-  gfx::Rect work_area = gfx::Screen::GetScreen()
+  gfx::Rect work_area = display::Screen::GetScreen()
                             ->GetDisplayNearestPoint(window->bounds().origin())
                             .work_area();
   window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_DOCKED);
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
index ae4b53f..239af25 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/compiler_specific.h"
-#include "base/profiler/scoped_tracker.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profiles_state.h"
diff --git a/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc b/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc
index 8cdde9c4..1648a941 100644
--- a/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc
+++ b/chrome/browser/ui/views/link_disambiguation/link_disambiguation_popup.cc
@@ -6,14 +6,14 @@
 
 #include "base/macros.h"
 #include "ui/aura/client/screen_position_client.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/events/event.h"
 #include "ui/events/event_processor.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/gesture_event_details.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/bubble/bubble_dialog_delegate.h"
 #include "ui/views/controls/image_view.h"
 
@@ -182,8 +182,8 @@
       target_screen.y() - (zoomed_bitmap.height() / 2),
       zoomed_bitmap.width(),
       zoomed_bitmap.height());
-  const gfx::Display display =
-      gfx::Screen::GetScreen()->GetDisplayNearestWindow(content);
+  const display::Display display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(content);
   window_bounds.AdjustToFit(display.work_area());
   view_->GetWidget()->SetBounds(window_bounds);
   view_->GetWidget()->Show();
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray.cc b/chrome/browser/ui/views/message_center/web_notification_tray.cc
index 69f90d431..eb184ef 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/views/message_center/web_notification_tray.h"
 
 #include "chrome/browser/browser_process.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/message_center/message_center_tray.h"
 #include "ui/message_center/message_center_tray_delegate.h"
 #include "ui/message_center/views/desktop_popup_alignment_delegate.h"
@@ -38,7 +38,7 @@
 }
 
 bool WebNotificationTray::ShowPopups() {
-  alignment_delegate_->StartObserving(gfx::Screen::GetScreen());
+  alignment_delegate_->StartObserving(display::Screen::GetScreen());
   popup_collection_->DoUpdateIfPossible();
   return true;
 }
diff --git a/chrome/browser/ui/views/panels/panel_frame_view.cc b/chrome/browser/ui/views/panels/panel_frame_view.cc
index 0960003..3c7b41b8 100644
--- a/chrome/browser/ui/views/panels/panel_frame_view.cc
+++ b/chrome/browser/ui/views/panels/panel_frame_view.cc
@@ -15,10 +15,10 @@
 #include "ui/base/hit_test.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/path.h"
-#include "ui/gfx/screen.h"
 #include "ui/resources/grit/ui_resources.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/label.h"
@@ -592,7 +592,7 @@
   // Converting the mouse location to screen coordinates returns an incorrect
   // location while the panel is moving. See crbug.com/353393 for more details.
   // TODO(pkotwicz): Fix conversion to screen coordinates
-  gfx::Screen* screen = gfx::Screen::GetScreen();
+  display::Screen* screen = display::Screen::GetScreen();
   gfx::Point mouse_location = screen->GetCursorScreenPoint();
 #else
   // |event.location| is in the view's coordinate system. Convert it to the
diff --git a/chrome/browser/ui/views/panels/panel_view.cc b/chrome/browser/ui/views/panels/panel_view.cc
index 6644904..078088fb 100644
--- a/chrome/browser/ui/views/panels/panel_view.cc
+++ b/chrome/browser/ui/views/panels/panel_view.cc
@@ -26,9 +26,9 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/content_accelerators/accelerator_util.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/path.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/widget/widget.h"
@@ -1012,7 +1012,7 @@
 #if defined(OS_WIN)
   if (focused_ && panel_->IsMinimized() &&
       panel_->collection()->type() == PanelCollection::DOCKED &&
-      gfx::Screen::GetScreen()->GetWindowUnderCursor() !=
+      display::Screen::GetScreen()->GetWindowUnderCursor() !=
           widget->GetNativeWindow()) {
     panel_->Restore();
   }
diff --git a/chrome/browser/ui/views/profiles/user_manager_view.cc b/chrome/browser/ui/views/profiles/user_manager_view.cc
index c182c75..c18b9d7 100644
--- a/chrome/browser/ui/views/profiles/user_manager_view.cc
+++ b/chrome/browser/ui/views/profiles/user_manager_view.cc
@@ -30,7 +30,7 @@
 #include "content/public/browser/web_contents.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/view.h"
@@ -305,7 +305,7 @@
       gfx::NativeView native_view =
           views::Widget::GetWidgetForNativeWindow(
               browser->window()->GetNativeWindow())->GetNativeView();
-      bounds = gfx::Screen::GetScreen()
+      bounds = display::Screen::GetScreen()
                    ->GetDisplayNearestWindow(native_view)
                    .work_area();
       bounds.ClampToCenteredSize(gfx::Size(UserManager::kWindowWidth,
diff --git a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
index 6befddb..11fca47 100644
--- a/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
+++ b/chrome/browser/ui/views/screen_capture_notification_ui_views.cc
@@ -13,7 +13,7 @@
 #include "ui/base/hit_test.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/bubble/bubble_border.h"
 #include "ui/views/bubble/bubble_frame_view.h"
 #include "ui/views/controls/button/blue_button.h"
@@ -195,7 +195,7 @@
   set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
       GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
 
-  gfx::Screen* screen = gfx::Screen::GetScreen();
+  display::Screen* screen = display::Screen::GetScreen();
   // TODO(sergeyu): Move the notification to the display being captured when
   // per-display screen capture is supported.
   gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc
index 24504b1..3c9a14e 100644
--- a/chrome/browser/ui/views/status_bubble_views.cc
+++ b/chrome/browser/ui/views/status_bubble_views.cc
@@ -21,13 +21,13 @@
 #include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkRRect.h"
 #include "ui/base/theme_provider.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/animation/animation_delegate.h"
 #include "ui/gfx/animation/linear_animation.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/gfx/text_elider.h"
 #include "ui/gfx/text_utils.h"
@@ -807,8 +807,9 @@
     // Check if the bubble sticks out from the monitor or will obscure
     // download shelf.
     gfx::NativeView window = base_view_->GetWidget()->GetNativeView();
-    gfx::Rect monitor_rect =
-        gfx::Screen::GetScreen()->GetDisplayNearestWindow(window).work_area();
+    gfx::Rect monitor_rect = display::Screen::GetScreen()
+                                 ->GetDisplayNearestWindow(window)
+                                 .work_area();
     const int bubble_bottom_y = top_left.y() + position_.y() + size_.height();
 
     if (bubble_bottom_y + offset > monitor_rect.height() ||
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.cc b/chrome/browser/ui/views/status_icons/status_tray_win.cc
index 7cfb2854..72f389f 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_win.cc
@@ -19,7 +19,7 @@
 #include "chrome/browser/ui/views/status_icons/status_icon_win.h"
 #include "chrome/browser/ui/views/status_icons/status_tray_state_changer_win.h"
 #include "chrome/common/chrome_constants.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/win/hwnd_util.h"
 
 static const UINT kStatusIconMessage = WM_APP + 1;
@@ -194,7 +194,8 @@
       case WM_CONTEXTMENU:
         // Walk our icons, find which one was clicked on, and invoke its
         // HandleClickEvent() method.
-        gfx::Point cursor_pos(gfx::Screen::GetScreen()->GetCursorScreenPoint());
+        gfx::Point cursor_pos(
+            display::Screen::GetScreen()->GetCursorScreenPoint());
         win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN);
         return TRUE;
     }
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
index 3e53a1e..074495d 100644
--- a/chrome/browser/ui/views/tabs/tab.cc
+++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -11,7 +11,6 @@
 #include "base/command_line.h"
 #include "base/debug/alias.h"
 #include "base/macros.h"
-#include "base/profiler/scoped_tracker.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/themes/theme_properties.h"
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 3c84789..6439c44 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -29,10 +29,10 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_function_dispatcher.h"
+#include "ui/display/screen.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/gestures/gesture_recognizer.h"
 #include "ui/gfx/geometry/point_conversions.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/event_monitor.h"
 #include "ui/views/focus/view_storage.h"
 #include "ui/views/widget/root_view.h"
@@ -457,7 +457,7 @@
   // If the cursor is outside the monitor area, move it inside. For example,
   // dropping a tab onto the task bar on Windows produces this situation.
   gfx::Rect work_area =
-      gfx::Screen::GetScreen()->GetDisplayNearestPoint(origin).work_area();
+      display::Screen::GetScreen()->GetDisplayNearestPoint(origin).work_area();
   gfx::Point create_point(origin);
   if (!work_area.IsEmpty()) {
     if (create_point.x() < work_area.x())
@@ -1638,7 +1638,7 @@
   views::View::ConvertPointToWidget(source, &center);
   gfx::Rect new_bounds(source->GetWidget()->GetRestoredBounds());
 
-  gfx::Rect work_area = gfx::Screen::GetScreen()
+  gfx::Rect work_area = display::Screen::GetScreen()
                             ->GetDisplayNearestPoint(last_point_in_screen_)
                             .work_area();
   if (new_bounds.size().width() >= work_area.size().width() &&
@@ -1771,7 +1771,7 @@
   }
 #endif
 
-  return gfx::Screen::GetScreen()->GetCursorScreenPoint();
+  return display::Screen::GetScreen()->GetCursorScreenPoint();
 }
 
 gfx::Vector2d TabDragController::GetWindowOffset(
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index fb85ed5..2f4b35e 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -37,7 +37,7 @@
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/test/ui_controls.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 
@@ -183,7 +183,7 @@
 
   // Resize the two windows so they're right next to each other.
   gfx::Rect work_area =
-      gfx::Screen::GetScreen()
+      display::Screen::GetScreen()
           ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow())
           .work_area();
   gfx::Size half_size =
@@ -865,7 +865,7 @@
                        MAYBE_DetachFromFullsizeWindow) {
   // Resize the browser window so that it is as big as the work area.
   gfx::Rect work_area =
-      gfx::Screen::GetScreen()
+      display::Screen::GetScreen()
           ->GetDisplayNearestWindow(browser()->window()->GetNativeWindow())
           .work_area();
   browser()->window()->SetBounds(work_area);
@@ -1831,7 +1831,7 @@
   aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
   ASSERT_EQ(2u, roots.size());
   aura::Window* second_root = roots[1];
-  gfx::Rect work_area = gfx::Screen::GetScreen()
+  gfx::Rect work_area = display::Screen::GetScreen()
                             ->GetDisplayNearestWindow(second_root)
                             .work_area();
   browser2->window()->SetBounds(work_area);
@@ -1882,7 +1882,7 @@
   aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
   ASSERT_EQ(2u, roots.size());
   aura::Window* second_root = roots[1];
-  gfx::Rect work_area = gfx::Screen::GetScreen()
+  gfx::Rect work_area = display::Screen::GetScreen()
                             ->GetDisplayNearestWindow(second_root)
                             .work_area();
   browser()->window()->SetBounds(work_area);
@@ -1943,7 +1943,7 @@
   ASSERT_EQ(2u, roots.size());
   aura::Window* first_root = roots[0];
   aura::Window* second_root = roots[1];
-  gfx::Rect work_area = gfx::Screen::GetScreen()
+  gfx::Rect work_area = display::Screen::GetScreen()
                             ->GetDisplayNearestWindow(second_root)
                             .work_area();
   work_area.Inset(20, 20, 20, 60);
@@ -2013,7 +2013,7 @@
   aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
   ASSERT_EQ(2u, roots.size());
   aura::Window* second_root = roots[1];
-  gfx::Rect work_area = gfx::Screen::GetScreen()
+  gfx::Rect work_area = display::Screen::GetScreen()
                             ->GetDisplayNearestWindow(second_root)
                             .work_area();
   browser2->window()->SetBounds(work_area);
@@ -2260,7 +2260,7 @@
   // Move the second browser to the second display.
   aura::Window::Windows roots = ash::Shell::GetAllRootWindows();
   ASSERT_EQ(2u, roots.size());
-  gfx::Point final_destination = gfx::Screen::GetScreen()
+  gfx::Point final_destination = display::Screen::GetScreen()
                                      ->GetDisplayNearestWindow(roots[1])
                                      .work_area()
                                      .CenterPoint();
@@ -2300,13 +2300,14 @@
   EXPECT_EQ("0 1", IDString(browser()->tab_strip_model()));
   EXPECT_EQ(roots[0], browser()->window()->GetNativeWindow()->GetRootWindow());
 
-  gfx::Rect work_area =
-      gfx::Screen::GetScreen()->GetDisplayNearestWindow(roots[1]).work_area();
+  gfx::Rect work_area = display::Screen::GetScreen()
+                            ->GetDisplayNearestWindow(roots[1])
+                            .work_area();
   browser()->window()->SetBounds(work_area);
   EXPECT_EQ(roots[1], browser()->window()->GetNativeWindow()->GetRootWindow());
 
   // Move the second browser to the display.
-  gfx::Point final_destination = gfx::Screen::GetScreen()
+  gfx::Point final_destination = display::Screen::GetScreen()
                                      ->GetDisplayNearestWindow(roots[0])
                                      .work_area()
                                      .CenterPoint();
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index e540f84..1303b262 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -49,17 +49,17 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/compositor/compositing_recorder.h"
 #include "ui/compositor/paint_recorder.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/animation/animation_container.h"
 #include "ui/gfx/animation/throb_animation.h"
 #include "ui/gfx/canvas.h"
-#include "ui/gfx/display.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_operations.h"
 #include "ui/gfx/path.h"
 #include "ui/gfx/scoped_canvas.h"
-#include "ui/gfx/screen.h"
 #include "ui/gfx/skia_util.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/masked_targeter_delegate.h"
@@ -2365,8 +2365,8 @@
                         drop_indicator_height);
 
   // If the rect doesn't fit on the monitor, push the arrow to the bottom.
-  gfx::Screen* screen = gfx::Screen::GetScreen();
-  gfx::Display display = screen->GetDisplayMatching(drop_bounds);
+  display::Screen* screen = display::Screen::GetScreen();
+  display::Display display = screen->GetDisplayMatching(drop_bounds);
   *is_beneath = !display.bounds().Contains(drop_bounds);
   if (*is_beneath)
     drop_bounds.Offset(0, drop_bounds.height() + height());
diff --git a/chrome/browser/ui/views/tabs/window_finder_win.cc b/chrome/browser/ui/views/tabs/window_finder_win.cc
index 09839a68..29517ef 100644
--- a/chrome/browser/ui/views/tabs/window_finder_win.cc
+++ b/chrome/browser/ui/views/tabs/window_finder_win.cc
@@ -11,7 +11,6 @@
 #include "base/win/windows_version.h"
 #include "ui/aura/window.h"
 #include "ui/display/win/screen_win.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
 #include "ui/views/win/hwnd_util.h"
 
diff --git a/chrome/browser/ui/views/tabs/window_finder_x11.cc b/chrome/browser/ui/views/tabs/window_finder_x11.cc
index c96e03c..1401d9d 100644
--- a/chrome/browser/ui/views/tabs/window_finder_x11.cc
+++ b/chrome/browser/ui/views/tabs/window_finder_x11.cc
@@ -4,14 +4,16 @@
 
 #include "chrome/browser/ui/views/tabs/window_finder.h"
 
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/point_conversions.h"
-#include "ui/gfx/screen.h"
 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
 
 namespace {
 
 float GetDeviceScaleFactor() {
-  return gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+  return display::Screen::GetScreen()
+      ->GetPrimaryDisplay()
+      .device_scale_factor();
 }
 
 gfx::Point DIPToPixelPoint(const gfx::Point& dip_point) {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc
index d910b372..6ae0e07c 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -19,8 +19,8 @@
 #include "ui/base/material_design/material_design_controller.h"
 #include "ui/base/models/menu_model.h"
 #include "ui/base/theme_provider.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/strings/grit/ui_strings.h"
 #include "ui/views/animation/button_ink_drop_delegate.h"
 #include "ui/views/controls/button/label_button_border.h"
@@ -201,15 +201,15 @@
   // Use the left bound of the display on which
   // the menu button exists.
   gfx::NativeView view = GetWidget()->GetNativeView();
-  gfx::Display display =
-      gfx::Screen::GetScreen()->GetDisplayNearestWindow(view);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(view);
   int left_bound = display.bounds().x();
 #else
   // The window might be positioned over the edge between two screens. We'll
   // want to position the dropdown on the screen the mouse cursor is on.
-  gfx::Screen* screen = gfx::Screen::GetScreen();
-  gfx::Display display = screen->GetDisplayNearestPoint(
-      screen->GetCursorScreenPoint());
+  display::Screen* screen = display::Screen::GetScreen();
+  display::Display display =
+      screen->GetDisplayNearestPoint(screen->GetCursorScreenPoint());
   int left_bound = display.bounds().x();
 #endif
   if (menu_position.x() < left_bound)
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
index 743a6ebf..d71d4986 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -30,9 +30,9 @@
 #include "google_apis/google_api_keys.h"
 #include "grit/components_strings.h"
 #include "ui/chromeos/accessibility_types.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/screen.h"
 #include "ui/keyboard/keyboard_controller.h"
 
 namespace {
@@ -403,7 +403,8 @@
 }
 
 void CoreOobeHandler::UpdateClientAreaSize() {
-  const gfx::Size& size = gfx::Screen::GetScreen()->GetPrimaryDisplay().size();
+  const gfx::Size& size =
+      display::Screen::GetScreen()->GetPrimaryDisplay().size();
   SetClientAreaSize(size.width(), size.height());
 }
 
diff --git a/chrome/browser/ui/webui/options/autofill_options_handler.cc b/chrome/browser/ui/webui/options/autofill_options_handler.cc
index b387f8b4..33d02ca 100644
--- a/chrome/browser/ui/webui/options/autofill_options_handler.cc
+++ b/chrome/browser/ui/webui/options/autofill_options_handler.cc
@@ -54,8 +54,6 @@
 
 namespace {
 
-const char kSettingsOrigin[] = "Chrome settings";
-
 static const char kFullNameField[] = "fullName";
 static const char kCompanyNameField[] = "companyName";
 static const char kAddressLineField[] = "addrLines";
@@ -474,7 +472,7 @@
     return;
   }
 
-  AutofillProfile profile(guid, kSettingsOrigin);
+  AutofillProfile profile(guid, autofill::kSettingsOrigin);
 
   base::string16 full_name;
   if (args->GetString(arg_counter++, &full_name)) {
@@ -558,7 +556,7 @@
     return;
   }
 
-  CreditCard credit_card(guid, kSettingsOrigin);
+  CreditCard credit_card(guid, autofill::kSettingsOrigin);
 
   base::string16 value;
   if (args->GetString(1, &value))
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index 8563731..155362eb 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -1091,8 +1091,9 @@
   if (arc::ArcBridgeService::GetEnabled(
           base::CommandLine::ForCurrentProcess()) &&
       !arc::ArcAuthService::IsOptInVerificationDisabled() &&
-      !profile->IsLegacySupervised() &&
-      user->HasGaiaAccount()) {
+      !profile->IsLegacySupervised() && user->HasGaiaAccount() &&
+      !user_manager::UserManager::Get()
+           ->IsCurrentUserCryptohomeDataEphemeral()) {
     web_ui()->CallJavascriptFunction("BrowserOptions.showAndroidAppsSection");
   }
   OnSystemTimezoneAutomaticDetectionPolicyChanged();
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
index 29b6fc8..18dc1d0d 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
@@ -28,12 +28,12 @@
 #include "content/public/browser/web_ui.h"
 #include "grit/ash_strings.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/display/display.h"
 #include "ui/display/manager/display_layout.h"
 #include "ui/display/manager/display_layout_builder.h"
-#include "ui/gfx/display.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size_conversions.h"
-#include "ui/gfx/screen.h"
 
 namespace chromeos {
 namespace options {
@@ -50,10 +50,10 @@
 int64_t GetDisplayIdFromValue(const base::Value* arg) {
   std::string id_value;
   if (!arg->GetAsString(&id_value))
-    return gfx::Display::kInvalidDisplayID;
-  int64_t display_id = gfx::Display::kInvalidDisplayID;
+    return display::Display::kInvalidDisplayID;
+  int64_t display_id = display::Display::kInvalidDisplayID;
   if (!base::StringToInt64(id_value, &display_id))
-    return gfx::Display::kInvalidDisplayID;
+    return display::Display::kInvalidDisplayID;
   return display_id;
 }
 
@@ -61,10 +61,10 @@
   const base::Value* arg;
   if (!args->Get(0, &arg)) {
     LOG(ERROR) << "No display id arg";
-    return gfx::Display::kInvalidDisplayID;
+    return display::Display::kInvalidDisplayID;
   }
   int64_t display_id = GetDisplayIdFromValue(arg);
-  if (display_id == gfx::Display::kInvalidDisplayID)
+  if (display_id == display::Display::kInvalidDisplayID)
     LOG(ERROR) << "Invalid display id: " << *arg;
   return display_id;
 }
@@ -73,7 +73,7 @@
                                    const std::string& key) {
   const base::Value* arg;
   if (!dictionary->Get(key, &arg))
-    return gfx::Display::kInvalidDisplayID;
+    return display::Display::kInvalidDisplayID;
   return GetDisplayIdFromValue(arg);
 }
 
@@ -146,8 +146,8 @@
 
 base::DictionaryValue* ConvertDisplayModeToValue(int64_t display_id,
                                                  const ash::DisplayMode& mode) {
-  bool is_internal = gfx::Display::HasInternalDisplay() &&
-                     gfx::Display::InternalDisplayId() == display_id;
+  bool is_internal = display::Display::HasInternalDisplay() &&
+                     display::Display::InternalDisplayId() == display_id;
   base::DictionaryValue* result = new base::DictionaryValue();
   gfx::Size size_dip = mode.GetSizeInDIP(is_internal);
   result->SetInteger("width", size_dip.width());
@@ -290,7 +290,7 @@
 void DisplayOptionsHandler::SendAllDisplayInfo() {
   ash::DisplayManager* display_manager = GetDisplayManager();
 
-  std::vector<gfx::Display> displays;
+  std::vector<display::Display> displays;
   for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i)
     displays.push_back(display_manager->GetDisplayAt(i));
 
@@ -303,9 +303,9 @@
     display_mode = ash::DisplayManager::EXTENDED;
   base::FundamentalValue mode(static_cast<int>(display_mode));
 
-  int64_t primary_id = gfx::Screen::GetScreen()->GetPrimaryDisplay().id();
+  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
   std::unique_ptr<base::ListValue> js_displays(new base::ListValue);
-  for (const gfx::Display& display : displays) {
+  for (const display::Display& display : displays) {
     const ash::DisplayInfo& display_info =
         display_manager->GetDisplayInfo(display.id());
     base::DictionaryValue* js_display = new base::DictionaryValue();
@@ -343,7 +343,7 @@
       const display::DisplayPlacement placement =
           display_manager->GetCurrentDisplayLayout().FindPlacementById(
               display.id());
-      if (placement.display_id != gfx::Display::kInvalidDisplayID) {
+      if (placement.display_id != display::Display::kInvalidDisplayID) {
         js_display->SetString(
             "parentId", base::Int64ToString(placement.parent_display_id));
         js_display->SetInteger("layoutType", placement.position);
@@ -394,7 +394,7 @@
 void DisplayOptionsHandler::HandleSetPrimary(const base::ListValue* args) {
   DCHECK(!args->empty());
   int64_t display_id = GetDisplayIdFromArgs(args);
-  if (display_id == gfx::Display::kInvalidDisplayID)
+  if (display_id == display::Display::kInvalidDisplayID)
     return;
 
   content::RecordAction(base::UserMetricsAction("Options_DisplaySetPrimary"));
@@ -421,11 +421,11 @@
     }
 
     int64_t parent_id = GetDisplayIdFromDictionary(dictionary, "parentId");
-    if (parent_id == gfx::Display::kInvalidDisplayID)
+    if (parent_id == display::Display::kInvalidDisplayID)
       continue;  // No placement for root (primary) display.
 
     int64_t display_id = GetDisplayIdFromDictionary(dictionary, "id");
-    if (display_id == gfx::Display::kInvalidDisplayID) {
+    if (display_id == display::Display::kInvalidDisplayID) {
       LOG(ERROR) << "Invalud display id in layout dictionary: " << *dictionary;
       continue;
     }
@@ -455,7 +455,7 @@
   DCHECK(!args->empty());
 
   int64_t display_id = GetDisplayIdFromArgs(args);
-  if (display_id == gfx::Display::kInvalidDisplayID)
+  if (display_id == display::Display::kInvalidDisplayID)
     return;
 
   const base::DictionaryValue* mode_data = nullptr;
@@ -478,7 +478,7 @@
                << " Mode: " << *mode_data;
     return;
   }
-  if (gfx::Display::IsInternalDisplayId(display_id))
+  if (display::Display::IsInternalDisplayId(display_id))
     return;
   // For external displays, show a notification confirming the resolution
   // change.
@@ -492,7 +492,7 @@
   DCHECK(!args->empty());
 
   int64_t display_id = GetDisplayIdFromArgs(args);
-  if (display_id == gfx::Display::kInvalidDisplayID)
+  if (display_id == display::Display::kInvalidDisplayID)
     return;
 
   int rotation_value = 0;
@@ -500,27 +500,27 @@
     LOG(ERROR) << "Can't parse rotation: " << args;
     return;
   }
-  gfx::Display::Rotation new_rotation = gfx::Display::ROTATE_0;
+  display::Display::Rotation new_rotation = display::Display::ROTATE_0;
   if (rotation_value == 90)
-    new_rotation = gfx::Display::ROTATE_90;
+    new_rotation = display::Display::ROTATE_90;
   else if (rotation_value == 180)
-    new_rotation = gfx::Display::ROTATE_180;
+    new_rotation = display::Display::ROTATE_180;
   else if (rotation_value == 270)
-    new_rotation = gfx::Display::ROTATE_270;
+    new_rotation = display::Display::ROTATE_270;
   else if (rotation_value != 0)
     LOG(ERROR) << "Invalid rotation: " << rotation_value << " Falls back to 0";
 
   content::RecordAction(
       base::UserMetricsAction("Options_DisplaySetOrientation"));
   GetDisplayConfigurationController()->SetDisplayRotation(
-      display_id, new_rotation, gfx::Display::ROTATION_SOURCE_USER,
+      display_id, new_rotation, display::Display::ROTATION_SOURCE_USER,
       true /* user_action */);
 }
 
 void DisplayOptionsHandler::HandleSetColorProfile(const base::ListValue* args) {
   DCHECK(!args->empty());
   int64_t display_id = GetDisplayIdFromArgs(args);
-  if (display_id == gfx::Display::kInvalidDisplayID)
+  if (display_id == display::Display::kInvalidDisplayID)
     return;
 
   std::string profile_value;
diff --git a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.cc
index dfc67814..8924c11 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.cc
@@ -17,8 +17,8 @@
 #include "chrome/grit/generated_resources.h"
 #include "content/public/browser/web_ui.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 
 namespace chromeos {
 namespace options {
@@ -31,11 +31,11 @@
 }
 
 DisplayOverscanHandler::DisplayOverscanHandler() {
-  gfx::Screen::GetScreen()->AddObserver(this);
+  display::Screen::GetScreen()->AddObserver(this);
 }
 
 DisplayOverscanHandler::~DisplayOverscanHandler() {
-  gfx::Screen::GetScreen()->RemoveObserver(this);
+  display::Screen::GetScreen()->RemoveObserver(this);
 }
 
 void DisplayOverscanHandler::GetLocalizedValues(
@@ -81,7 +81,8 @@
                  base::Unretained(this)));
 }
 
-void DisplayOverscanHandler::OnDisplayAdded(const gfx::Display& new_display) {
+void DisplayOverscanHandler::OnDisplayAdded(
+    const display::Display& new_display) {
   if (!overscan_calibrator_)
     return;
 
@@ -89,7 +90,8 @@
       "options.DisplayOverscan.onOverscanCanceled");
 }
 
-void DisplayOverscanHandler::OnDisplayRemoved(const gfx::Display& old_display) {
+void DisplayOverscanHandler::OnDisplayRemoved(
+    const display::Display& old_display) {
   if (!overscan_calibrator_)
     return;
 
@@ -97,12 +99,11 @@
       "options.DisplayOverscan.onOverscanCanceled");
 }
 
-void DisplayOverscanHandler::OnDisplayMetricsChanged(const gfx::Display&,
-                                                     uint32_t) {
-}
+void DisplayOverscanHandler::OnDisplayMetricsChanged(const display::Display&,
+                                                     uint32_t) {}
 
 void DisplayOverscanHandler::HandleStart(const base::ListValue* args) {
-  int64_t display_id = gfx::Display::kInvalidDisplayID;
+  int64_t display_id = display::Display::kInvalidDisplayID;
   std::string id_value;
   if (!args->GetString(0, &id_value)) {
     LOG(ERROR) << "Can't find ID";
@@ -110,12 +111,12 @@
   }
 
   if (!base::StringToInt64(id_value, &display_id) ||
-      display_id == gfx::Display::kInvalidDisplayID) {
+      display_id == display::Display::kInvalidDisplayID) {
     LOG(ERROR) << "Invalid parameter: " << id_value;
     return;
   }
 
-  const gfx::Display& display =
+  const display::Display& display =
       ash::Shell::GetInstance()->display_manager()->GetDisplayForId(display_id);
   DCHECK(display.is_valid());
   if (!display.is_valid())
diff --git a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h b/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h
index a851b38..d46e5275 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h
+++ b/chrome/browser/ui/webui/options/chromeos/display_overscan_handler.h
@@ -11,7 +11,7 @@
 
 #include "base/macros.h"
 #include "chrome/browser/ui/webui/options/options_ui.h"
-#include "ui/gfx/display_observer.h"
+#include "ui/display/display_observer.h"
 
 namespace base {
 class DictionaryValue;
@@ -25,7 +25,7 @@
 
 // Display options overlay page UI handler.
 class DisplayOverscanHandler : public ::options::OptionsPageUIHandler,
-                               public gfx::DisplayObserver {
+                               public display::DisplayObserver {
  public:
   DisplayOverscanHandler();
   ~DisplayOverscanHandler() override;
@@ -36,10 +36,10 @@
   // WebUIMessageHandler implementation.
   void RegisterMessages() override;
 
-  // gfx::DisplayObserver implementation.
-  void OnDisplayAdded(const gfx::Display& new_display) override;
-  void OnDisplayRemoved(const gfx::Display& old_display) override;
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  // display::DisplayObserver implementation.
+  void OnDisplayAdded(const display::Display& new_display) override;
+  void OnDisplayRemoved(const display::Display& old_display) override;
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t metrics) override;
 
  private:
diff --git a/chrome/browser/ui/window_sizer/window_sizer.cc b/chrome/browser/ui/window_sizer/window_sizer.cc
index e1f9793..999ebd28 100644
--- a/chrome/browser/ui/window_sizer/window_sizer.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer.cc
@@ -19,7 +19,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "components/prefs/pref_service.h"
 #include "ui/base/ui_base_switches.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 #if defined(USE_ASH)
 #include "ash/shell.h"
@@ -151,8 +151,8 @@
   DefaultTargetDisplayProvider() {}
   ~DefaultTargetDisplayProvider() override {}
 
-  gfx::Display GetTargetDisplay(const gfx::Screen* screen,
-                                const gfx::Rect& bounds) const override {
+  display::Display GetTargetDisplay(const display::Screen* screen,
+                                    const gfx::Rect& bounds) const override {
 #if defined(USE_ASH)
     // Use the target display on ash.
     if (chrome::ShouldOpenAshOnStartup()) {
@@ -180,13 +180,13 @@
     const Browser* browser)
     : state_provider_(std::move(state_provider)),
       target_display_provider_(std::move(target_display_provider)),
-      screen_(gfx::Screen::GetScreen()),
+      screen_(display::Screen::GetScreen()),
       browser_(browser) {}
 
 WindowSizer::WindowSizer(
     std::unique_ptr<StateProvider> state_provider,
     std::unique_ptr<TargetDisplayProvider> target_display_provider,
-    gfx::Screen* screen,
+    display::Screen* screen,
     const Browser* browser)
     : state_provider_(std::move(state_provider)),
       target_display_provider_(std::move(target_display_provider)),
@@ -292,7 +292,7 @@
   return true;
 }
 
-void WindowSizer::GetDefaultWindowBounds(const gfx::Display& display,
+void WindowSizer::GetDefaultWindowBounds(const display::Display& display,
                                          gfx::Rect* default_bounds) const {
   DCHECK(default_bounds);
 #if defined(USE_ASH)
@@ -333,7 +333,7 @@
 }
 
 void WindowSizer::AdjustBoundsToBeVisibleOnDisplay(
-    const gfx::Display& display,
+    const display::Display& display,
     const gfx::Rect& saved_work_area,
     gfx::Rect* bounds) const {
   DCHECK(bounds);
@@ -403,7 +403,7 @@
 #endif  // defined(OS_MACOSX)
 }
 
-gfx::Display WindowSizer::GetTargetDisplay(const gfx::Rect& bounds) const {
+display::Display WindowSizer::GetTargetDisplay(const gfx::Rect& bounds) const {
   return target_display_provider_->GetTargetDisplay(screen_, bounds);
 }
 
diff --git a/chrome/browser/ui/window_sizer/window_sizer.h b/chrome/browser/ui/window_sizer/window_sizer.h
index a2898353..49a3193b 100644
--- a/chrome/browser/ui/window_sizer/window_sizer.h
+++ b/chrome/browser/ui/window_sizer/window_sizer.h
@@ -18,6 +18,11 @@
 class Screen;
 }
 
+namespace display {
+using Display = gfx::Display;
+using Screen = gfx::Screen;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // WindowSizer
 //
@@ -35,7 +40,7 @@
   class TargetDisplayProvider;
 
   // WindowSizer owns |state_provider| and |target_display_provider|,
-  // and will use the platforms's gfx::Screen.
+  // and will use the platforms's display::Screen.
   WindowSizer(std::unique_ptr<StateProvider> state_provider,
               std::unique_ptr<TargetDisplayProvider> target_display_provider,
               const Browser* browser);
@@ -44,7 +49,7 @@
   // and will use the supplied |screen|. Used only for testing.
   WindowSizer(std::unique_ptr<StateProvider> state_provider,
               std::unique_ptr<TargetDisplayProvider> target_display_provider,
-              gfx::Screen* screen,
+              display::Screen* screen,
               const Browser* browser);
 
   virtual ~WindowSizer();
@@ -78,8 +83,9 @@
   class TargetDisplayProvider {
     public:
       virtual ~TargetDisplayProvider() {}
-      virtual gfx::Display GetTargetDisplay(const gfx::Screen* screen,
-                                            const gfx::Rect& bounds) const = 0;
+      virtual display::Display GetTargetDisplay(
+          const display::Screen* screen,
+          const gfx::Rect& bounds) const = 0;
   };
 
   // Determines the position and size for a window as it is created as well
@@ -137,7 +143,7 @@
   // |display| if there is no last window and no saved window
   // placement in prefs. This function determines the default size
   // based on monitor size, etc.
-  void GetDefaultWindowBounds(const gfx::Display& display,
+  void GetDefaultWindowBounds(const display::Display& display,
                               gfx::Rect* default_bounds) const;
 
   // Adjusts |bounds| to be visible on-screen, biased toward the work area of
@@ -148,15 +154,14 @@
   // monitor configuration has changed. If it has, bounds are repositioned and
   // resized if necessary to make them completely contained in the current work
   // area.
-  void AdjustBoundsToBeVisibleOnDisplay(
-      const gfx::Display& display,
-      const gfx::Rect& saved_work_area,
-      gfx::Rect* bounds) const;
+  void AdjustBoundsToBeVisibleOnDisplay(const display::Display& display,
+                                        const gfx::Rect& saved_work_area,
+                                        gfx::Rect* bounds) const;
 
   // Determine the target display for a new window based on
   // |bounds|. On ash environment, this returns the display containing
   // ash's the target root window.
-  gfx::Display GetTargetDisplay(const gfx::Rect& bounds) const;
+  display::Display GetTargetDisplay(const gfx::Rect& bounds) const;
 
 #if defined(USE_ASH)
   // Ash specific logic for window placement. Returns true if |bounds| and
@@ -183,7 +188,7 @@
   // Providers for persistent storage and monitor metrics.
   std::unique_ptr<StateProvider> state_provider_;
   std::unique_ptr<TargetDisplayProvider> target_display_provider_;
-  gfx::Screen* screen_;  // not owned.
+  display::Screen* screen_;  // not owned.
 
   // Note that this browser handle might be NULL.
   const Browser* browser_;
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash.cc b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
index 953804a..75322ff 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 bool WindowSizer::GetBrowserBoundsAsh(gfx::Rect* bounds,
                                       ui::WindowShowState* show_state) const {
@@ -51,7 +51,7 @@
   }
 
   if (browser_->is_type_tabbed() && *show_state == ui::SHOW_STATE_DEFAULT) {
-    gfx::Display display = screen_->GetDisplayMatching(*bounds);
+    display::Display display = screen_->GetDisplayMatching(*bounds);
     gfx::Rect work_area = display.work_area();
     bounds->AdjustToFit(work_area);
     if (*bounds == work_area) {
@@ -78,7 +78,7 @@
   ui::WindowShowState passed_show_state = *show_state;
 
   bool is_saved_bounds = GetSavedWindowBounds(bounds_in_screen, show_state);
-  gfx::Display display;
+  display::Display display;
   if (is_saved_bounds) {
     display = screen_->GetDisplayMatching(*bounds_in_screen);
   } else {
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc
index f52c3c60..3db6636a 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc
@@ -61,8 +61,8 @@
   ui::test::EventGenerator generator(root_window);
   gfx::Point center =
       GetChromeIconBoundsForRootWindow(root_window).CenterPoint();
-  gfx::Display display =
-      gfx::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
+  display::Display display =
+      display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
   const gfx::Point& origin = display.bounds().origin();
   center.Offset(- origin.x(), - origin.y());
   generator.MoveMouseTo(center);
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
index a41b4e2d..b0a6f92a 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
@@ -26,7 +26,7 @@
 #include "ui/aura/env.h"
 #include "ui/aura/test/test_windows.h"
 #include "ui/aura/window_event_dispatcher.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/wm/public/activation_client.h"
 
 typedef ash::test::AshTestBase WindowSizerAshTest;
@@ -583,7 +583,7 @@
 TEST_F(WindowSizerAshTest, MAYBE_PlaceNewWindowsOnMultipleDisplays) {
   UpdateDisplay("1600x1200,1600x1200");
   gfx::Rect primary_bounds =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
   gfx::Rect secondary_bounds = ash::ScreenUtil::GetSecondaryDisplay().bounds();
 
   ash::Shell::GetInstance()->set_target_root_window(
@@ -633,8 +633,8 @@
   // Move the window to the right side of the secondary display and create a new
   // window. It should be opened then on the secondary display.
   {
-    gfx::Display second_display =
-        gfx::Screen::GetScreen()->GetDisplayNearestPoint(
+    display::Display second_display =
+        display::Screen::GetScreen()->GetDisplayNearestPoint(
             gfx::Point(1600 + 100, 10));
     browser_window->GetNativeWindow()->SetBoundsInScreen(
         gfx::Rect(secondary_bounds.CenterPoint().x() - 100, 10, 200, 200),
@@ -822,7 +822,7 @@
       chrome::CreateBrowserWithTestWindowForParams(&native_params));
 
   gfx::Rect display_bounds =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
   gfx::Rect specified_bounds = display_bounds;
 
   // Make a window bigger than the display work area.
diff --git a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
index 960a578..b0a84e7f 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
@@ -15,8 +15,8 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/testing_profile.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 
 #if defined(USE_AURA)
 #include "ui/aura/window.h"
@@ -24,12 +24,14 @@
 
 namespace {
 
-class TestScreen : public gfx::Screen {
+class TestScreen : public display::Screen {
  public:
-  TestScreen() : previous_screen_(gfx::Screen::GetScreen()) {
-    gfx::Screen::SetScreenInstance(this);
+  TestScreen() : previous_screen_(display::Screen::GetScreen()) {
+    display::Screen::SetScreenInstance(this);
   }
-  ~TestScreen() override { gfx::Screen::SetScreenInstance(previous_screen_); }
+  ~TestScreen() override {
+    display::Screen::SetScreenInstance(previous_screen_);
+  }
 
   // Sets the index of the display returned from GetDisplayNearestWindow().
   // Only used on aura.
@@ -37,7 +39,7 @@
     index_of_display_nearest_window_ = index;
   }
 
-  // Overridden from gfx::Screen:
+  // Overridden from display::Screen:
   gfx::Point GetCursorScreenPoint() override {
     NOTREACHED();
     return gfx::Point();
@@ -55,25 +57,28 @@
 
   int GetNumDisplays() const override { return displays_.size(); }
 
-  std::vector<gfx::Display> GetAllDisplays() const override {
+  std::vector<display::Display> GetAllDisplays() const override {
     return displays_;
   }
 
-  gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const override {
+  display::Display GetDisplayNearestWindow(
+      gfx::NativeView view) const override {
 #if defined(USE_AURA)
     return displays_[index_of_display_nearest_window_];
 #else
     NOTREACHED();
-    return gfx::Display();
+    return display::Display();
 #endif
   }
 
-  gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override {
+  display::Display GetDisplayNearestPoint(
+      const gfx::Point& point) const override {
     NOTREACHED();
-    return gfx::Display();
+    return display::Display();
   }
 
-  gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override {
+  display::Display GetDisplayMatching(
+      const gfx::Rect& match_rect) const override {
     int max_area = 0;
     size_t max_area_index = 0;
 
@@ -89,23 +94,27 @@
     return displays_[max_area_index];
   }
 
-  gfx::Display GetPrimaryDisplay() const override { return displays_[0]; }
+  display::Display GetPrimaryDisplay() const override { return displays_[0]; }
 
-  void AddObserver(gfx::DisplayObserver* observer) override { NOTREACHED(); }
+  void AddObserver(display::DisplayObserver* observer) override {
+    NOTREACHED();
+  }
 
-  void RemoveObserver(gfx::DisplayObserver* observer) override { NOTREACHED(); }
+  void RemoveObserver(display::DisplayObserver* observer) override {
+    NOTREACHED();
+  }
 
   void AddDisplay(const gfx::Rect& bounds,
                   const gfx::Rect& work_area) {
-    gfx::Display display(displays_.size(), bounds);
+    display::Display display(displays_.size(), bounds);
     display.set_work_area(work_area);
     displays_.push_back(display);
   }
 
  private:
-  gfx::Screen* previous_screen_;
+  display::Screen* previous_screen_;
   size_t index_of_display_nearest_window_ = 0u;
-  std::vector<gfx::Display> displays_;
+  std::vector<display::Display> displays_;
 
   DISALLOW_COPY_AND_ASSIGN(TestScreen);
 };
@@ -115,8 +124,8 @@
   TestTargetDisplayProvider() {}
   ~TestTargetDisplayProvider() override {}
 
-  gfx::Display GetTargetDisplay(const gfx::Screen* screen,
-                                const gfx::Rect& bounds) const override {
+  display::Display GetTargetDisplay(const display::Screen* screen,
+                                    const gfx::Rect& bounds) const override {
     // On ash, the bounds is used as a indicator to specify
     // the target display.
     return screen->GetDisplayMatching(bounds);
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 5151998..2607d8b2 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -323,8 +323,6 @@
             'chrome_resources.gyp:chrome_strings',
             '../base/base.gyp:base',
             '../ui/base/ui_base.gyp:ui_data_pack',
-            '../ui/gfx/gfx.gyp:gfx',
-            '../ui/gfx/gfx.gyp:gfx_geometry',
           ],
           'include_dirs': [
             '<(grit_out_dir)',
@@ -496,6 +494,7 @@
             'infobar_action_type_java',
             'most_visited_tile_type_java',
             'page_info_connection_type_java',
+            'policy_auditor_java',
             'profile_account_management_metrics_java',
             'resource_id_java',
             'shortcut_source_java',
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 0baec22..239de656 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -165,6 +165,8 @@
       'browser/component_updater/component_updater_resource_throttle.h',
       'browser/component_updater/ev_whitelist_component_installer.cc',
       'browser/component_updater/ev_whitelist_component_installer.h',
+      'browser/component_updater/origin_trials_component_installer.cc',
+      'browser/component_updater/origin_trials_component_installer.h',
       'browser/component_updater/pnacl_component_installer.cc',
       'browser/component_updater/pnacl_component_installer.h',
       'browser/component_updater/recovery_component_installer.cc',
@@ -461,10 +463,6 @@
       'browser/policy/schema_registry_service.h',
       'browser/policy/schema_registry_service_factory.cc',
       'browser/policy/schema_registry_service_factory.h',
-      'browser/sessions/restore_on_startup_policy_handler.cc',
-      'browser/sessions/restore_on_startup_policy_handler.h',
-      'browser/profiles/incognito_mode_policy_handler.cc',
-      'browser/profiles/incognito_mode_policy_handler.h',
       'browser/prerender/prerender_config.cc',
       'browser/prerender/prerender_config.h',
       'browser/prerender/prerender_contents.cc',
@@ -503,10 +501,12 @@
       'browser/process_resource_usage.h',
       'browser/process_singleton.h',
       'browser/process_singleton_win.cc',
-      'browser/push_messaging/background_budget_service.h',
+      'browser/profiles/incognito_mode_policy_handler.cc',
+      'browser/profiles/incognito_mode_policy_handler.h',
       'browser/push_messaging/background_budget_service.cc',
-      'browser/push_messaging/background_budget_service_factory.h',
+      'browser/push_messaging/background_budget_service.h',
       'browser/push_messaging/background_budget_service_factory.cc',
+      'browser/push_messaging/background_budget_service_factory.h',
       'browser/push_messaging/push_messaging_app_identifier.cc',
       'browser/push_messaging/push_messaging_app_identifier.h',
       'browser/push_messaging/push_messaging_constants.cc',
@@ -571,13 +571,15 @@
       'browser/search/suggestions/suggestions_ui.h',
       'browser/search/thumbnail_source.cc',
       'browser/search/thumbnail_source.h',
+      'browser/sessions/restore_on_startup_policy_handler.cc',
+      'browser/sessions/restore_on_startup_policy_handler.h',
       'browser/shell_integration.cc',
       'browser/shell_integration.h',
       'browser/shell_integration_android.cc',
       'browser/shell_integration_chromeos.cc',
       'browser/shell_integration_mac.mm',
-      'browser/shell_integration_win.h',
       'browser/shell_integration_win.cc',
+      'browser/shell_integration_win.h',
       'browser/site_details.cc',
       'browser/site_details.h',
       'browser/speech/chrome_speech_recognition_manager_delegate.cc',
@@ -674,7 +676,6 @@
     'chrome_browser_android_java_ui_sources': [
       'browser/after_startup_task_utils_android.cc',
       'browser/after_startup_task_utils_android.h',
-      'browser/platform_util_android.cc',
       'browser/android/accessibility/font_size_prefs_android.cc',
       'browser/android/accessibility/font_size_prefs_android.h',
       'browser/android/accessibility_util.cc',
@@ -708,8 +709,6 @@
       'browser/android/chrome_feature_list.h',
       'browser/android/chrome_jni_registrar.cc',
       'browser/android/chrome_jni_registrar.h',
-      'browser/android/chrome_media_client_android.cc',
-      'browser/android/chrome_media_client_android.h',
       'browser/android/chrome_startup_flags.cc',
       'browser/android/chrome_startup_flags.h',
       'browser/android/compositor/compositor_view.cc',
@@ -720,13 +719,13 @@
       'browser/android/compositor/layer/content_layer.h',
       'browser/android/compositor/layer/contextual_search_layer.cc',
       'browser/android/compositor/layer/contextual_search_layer.h',
+      'browser/android/compositor/layer/crushed_sprite_layer.cc',
+      'browser/android/compositor/layer/crushed_sprite_layer.h',
+      'browser/android/compositor/layer/layer.h',
       'browser/android/compositor/layer/overlay_panel_layer.cc',
       'browser/android/compositor/layer/overlay_panel_layer.h',
       'browser/android/compositor/layer/reader_mode_layer.cc',
       'browser/android/compositor/layer/reader_mode_layer.h',
-      'browser/android/compositor/layer/crushed_sprite_layer.cc',
-      'browser/android/compositor/layer/crushed_sprite_layer.h',
-      'browser/android/compositor/layer/layer.h',
       'browser/android/compositor/layer/tab_handle_layer.cc',
       'browser/android/compositor/layer/tab_handle_layer.h',
       'browser/android/compositor/layer/tab_layer.cc',
@@ -881,6 +880,8 @@
       'browser/android/ntp/ntp_snippets_bridge.h',
       'browser/android/ntp/ntp_snippets_launcher.cc',
       'browser/android/ntp/ntp_snippets_launcher.h',
+      'browser/android/ntp/popular_sites.cc',
+      'browser/android/ntp/popular_sites.h',
       'browser/android/omnibox/answers_image_bridge.cc',
       'browser/android/omnibox/answers_image_bridge.h',
       'browser/android/omnibox/autocomplete_controller_android.cc',
@@ -889,8 +890,8 @@
       'browser/android/omnibox/omnibox_prerender.h',
       'browser/android/password_ui_view_android.cc',
       'browser/android/password_ui_view_android.h',
-      'browser/android/ntp/popular_sites.cc',
-      'browser/android/ntp/popular_sites.h',
+      'browser/android/policy/policy_auditor.cc',
+      'browser/android/policy/policy_auditor.h',
       'browser/android/precache/precache_launcher.cc',
       'browser/android/precache/precache_launcher.h',
       'browser/android/preferences/autofill/autofill_profile_bridge.cc',
@@ -1004,8 +1005,6 @@
       'browser/net/spdyproxy/data_reduction_proxy_settings_android.cc',
       'browser/net/spdyproxy/data_reduction_proxy_settings_android.h',
       'browser/password_manager/account_chooser_dialog_android.cc',
-      'browser/password_manager/update_password_infobar_delegate.cc',
-      'browser/password_manager/update_password_infobar_delegate.h',
       'browser/password_manager/account_chooser_dialog_android.h',
       'browser/password_manager/auto_signin_first_run_dialog_android.cc',
       'browser/password_manager/auto_signin_first_run_dialog_android.h',
@@ -1013,8 +1012,11 @@
       'browser/password_manager/credential_android.h',
       'browser/password_manager/generated_password_saved_infobar_delegate_android.cc',
       'browser/password_manager/generated_password_saved_infobar_delegate_android.h',
+      'browser/password_manager/update_password_infobar_delegate.cc',
+      'browser/password_manager/update_password_infobar_delegate.h',
       'browser/permissions/permission_queue_controller.cc',
       'browser/permissions/permission_queue_controller.h',
+      'browser/platform_util_android.cc',
       'browser/precache/precache_manager_factory.cc',
       'browser/precache/precache_manager_factory.h',
       'browser/prerender/external_prerender_handler_android.cc',
@@ -1124,8 +1126,8 @@
     ],
     # Desktop Linux, ChromeOS, and Windows.
     'chrome_browser_non_mac_desktop_sources': [
-      'browser/renderer_context_menu/spelling_options_submenu_observer.h',
       'browser/renderer_context_menu/spelling_options_submenu_observer.cc',
+      'browser/renderer_context_menu/spelling_options_submenu_observer.h',
     ],
     # Desktop linux, doesn't count ChromeOS.
     'chrome_browser_linux_desktop_sources': [
@@ -1260,11 +1262,11 @@
       'browser/importer/profile_writer.h',
       'browser/lifetime/browser_close_manager.cc',
       'browser/lifetime/browser_close_manager.h',
-      'browser/lifetime/keep_alive_types.cc',
-      'browser/lifetime/keep_alive_types.h',
       'browser/lifetime/keep_alive_registry.cc',
       'browser/lifetime/keep_alive_registry.h',
       'browser/lifetime/keep_alive_state_observer.h',
+      'browser/lifetime/keep_alive_types.cc',
+      'browser/lifetime/keep_alive_types.h',
       'browser/lifetime/scoped_keep_alive.cc',
       'browser/lifetime/scoped_keep_alive.h',
       'browser/media/tab_desktop_media_list.cc',
@@ -1970,6 +1972,7 @@
       'android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java',
       'android/java/src/org/chromium/chrome/browser/password_manager/AutoSigninFirstRunDialog.java',
       'android/java/src/org/chromium/chrome/browser/PasswordUIView.java',
+      'android/java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java',
       'android/java/src/org/chromium/chrome/browser/precache/PrecacheLauncher.java',
       'android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java',
       'android/java/src/org/chromium/chrome/browser/preferences/LocationSettings.java',
@@ -2136,10 +2139,10 @@
       'browser/net/resource_prefetch_predictor_observer.h',
       'browser/net/safe_search_util.cc',
       'browser/net/safe_search_util.h',
-      'browser/net/service_providers_win.cc',
-      'browser/net/service_providers_win.h',
       'browser/net/sdch_owner_pref_storage.cc',
       'browser/net/sdch_owner_pref_storage.h',
+      'browser/net/service_providers_win.cc',
+      'browser/net/service_providers_win.h',
       'browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.cc',
       'browser/net/spdyproxy/data_reduction_proxy_chrome_io_data.h',
       'browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc',
@@ -2280,8 +2283,8 @@
     'chrome_browser_plugins_sources': [
       'browser/browsing_data/browsing_data_flash_lso_helper.cc',
       'browser/browsing_data/browsing_data_flash_lso_helper.h',
-      'browser/component_updater/pepper_flash_component_installer.h',
       'browser/component_updater/pepper_flash_component_installer.cc',
+      'browser/component_updater/pepper_flash_component_installer.h',
       'browser/metrics/plugin_metrics_provider.cc',
       'browser/metrics/plugin_metrics_provider.h',
       'browser/pepper_broker_infobar_delegate.cc',
@@ -2848,6 +2851,8 @@
       'browser/ssl/bad_clock_blocking_page.h',
       'browser/ssl/cert_report_helper.cc',
       'browser/ssl/cert_report_helper.h',
+      'browser/ssl/chrome_expect_ct_reporter.cc',
+      'browser/ssl/chrome_expect_ct_reporter.h',
       'browser/ssl/chrome_security_state_model_client.cc',
       'browser/ssl/chrome_security_state_model_client.h',
       'browser/ssl/chrome_ssl_host_state_delegate.cc',
@@ -2856,8 +2861,6 @@
       'browser/ssl/chrome_ssl_host_state_delegate_factory.h',
       'browser/ssl/common_name_mismatch_handler.cc',
       'browser/ssl/common_name_mismatch_handler.h',
-      'browser/ssl/chrome_expect_ct_reporter.cc',
-      'browser/ssl/chrome_expect_ct_reporter.h',
       'browser/ssl/ssl_blocking_page.cc',
       'browser/ssl/ssl_blocking_page.h',
       'browser/ssl/ssl_cert_reporter.h',
@@ -2881,14 +2884,14 @@
       'browser/supervised_user/child_accounts/family_info_fetcher.h',
       'browser/supervised_user/child_accounts/permission_request_creator_apiary.cc',
       'browser/supervised_user/child_accounts/permission_request_creator_apiary.h',
+      'browser/supervised_user/experimental/safe_search_url_reporter.cc',
+      'browser/supervised_user/experimental/safe_search_url_reporter.h',
       'browser/supervised_user/experimental/supervised_user_async_url_checker.cc',
       'browser/supervised_user/experimental/supervised_user_async_url_checker.h',
       'browser/supervised_user/experimental/supervised_user_blacklist.cc',
       'browser/supervised_user/experimental/supervised_user_blacklist.h',
       'browser/supervised_user/experimental/supervised_user_filtering_switches.cc',
       'browser/supervised_user/experimental/supervised_user_filtering_switches.h',
-      'browser/supervised_user/experimental/safe_search_url_reporter.cc',
-      'browser/supervised_user/experimental/safe_search_url_reporter.h',
       'browser/supervised_user/permission_request_creator.h',
       'browser/supervised_user/supervised_user_bookmarks_handler.cc',
       'browser/supervised_user/supervised_user_bookmarks_handler.h',
@@ -3327,6 +3330,7 @@
             '../components/components.gyp:net_log',
             '../components/components.gyp:network_hints_common',
             '../components/components.gyp:ntp_snippets',
+            '../components/components.gyp:ntp_tiles',
             '../components/components.gyp:packed_ct_ev_whitelist',
             '../components/components.gyp:password_manager_content_browser',
             '../components/components.gyp:password_manager_sync_browser',
@@ -3426,6 +3430,11 @@
                 '../ui/views/views.gyp:views'
               ],
             }],
+            ['use_x11==1', {
+              'dependencies': [
+                '../ui/base/x/ui_base_x.gyp:ui_base_x',
+              ],
+            }],
           ],
         }, {  # OS == "ios"
           'dependencies': [
@@ -4112,6 +4121,15 @@
           'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
         {
+          # GN: //chrome/android:chrome_android_java_enums_srcjar
+          'target_name': 'policy_auditor_java',
+          'type': 'none',
+          'variables': {
+            'source_file': 'browser/android/policy/policy_auditor.cc',
+          },
+          'includes': [ '../build/android/java_cpp_enum.gypi' ],
+        },
+        {
           # GN: //chrome/android:resource_id_javagen
           'target_name': 'resource_id_java',
           'type': 'none',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index 3378ff7..6570d41 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -767,6 +767,8 @@
         'browser/chromeos/policy/affiliated_invalidation_service_provider.h',
         'browser/chromeos/policy/affiliated_invalidation_service_provider_impl.cc',
         'browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h',
+        'browser/chromeos/policy/android_management_client.cc',
+        'browser/chromeos/policy/android_management_client.h',
         'browser/chromeos/policy/auto_enrollment_client.cc',
         'browser/chromeos/policy/auto_enrollment_client.h',
         'browser/chromeos/policy/bluetooth_policy_handler.cc',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 246a177..fe9ac06 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -23,6 +23,8 @@
       'common/chrome_content_client.h',
       'common/chrome_content_client_constants.cc',
       'common/chrome_content_client_ios.mm',
+      'common/chrome_media_client_android.cc',
+      'common/chrome_media_client_android.h',
       'common/chrome_result_codes.h',
       'common/chrome_utility_messages.h',
       'common/common_message_generator.cc',
diff --git a/chrome/chrome_nibs.gypi b/chrome/chrome_nibs.gypi
index dd430ab..f361bdc 100644
--- a/chrome/chrome_nibs.gypi
+++ b/chrome/chrome_nibs.gypi
@@ -7,6 +7,7 @@
 # tool and those that do not. A XIB should be listed in either one or the
 # other, but not both.
 {
+  # GN version: //chrome/app/nibs
   'variables': {
     'mac_translated_xibs': [
       'app/nibs/AppMenu.xib',
@@ -53,7 +54,6 @@
       'app/nibs/DevicePermissionsPrompt.xib',
       'app/nibs/FindBar.xib',
       'app/nibs/GlobalErrorBubble.xib',
-      'app/nibs/HungRendererDialog.xib',
       'app/nibs/InfoBar.xib',
       'app/nibs/Panel.xib',
     ],  # mac_untranslated_xibs
diff --git a/chrome/chrome_public_test_apk.isolate b/chrome/chrome_public_test_apk.isolate
index 8b3992a..b18a35a 100644
--- a/chrome/chrome_public_test_apk.isolate
+++ b/chrome/chrome_public_test_apk.isolate
@@ -3,29 +3,25 @@
 # found in the LICENSE file.
 
 {
-  'conditions': [
-    ['OS=="android"', {
-      'variables': {
-        'files': [
-          '<(DEPTH)/chrome/test/data/android/',
-          '<(DEPTH)/chrome/test/data/banners/',
-          '<(DEPTH)/chrome/test/data/encoding_tests/auto_detect/Big5_with_no_encoding_specified.html',
-          '<(DEPTH)/chrome/test/data/geolocation/',
-          '<(DEPTH)/chrome/test/data/google/',
-          '<(DEPTH)/chrome/test/data/image_search/valid.png',
-          '<(DEPTH)/chrome/test/data/navigation_interception/',
-          '<(DEPTH)/chrome/test/data/notifications/',
-          '<(DEPTH)/chrome/test/data/popup_blocker/',
-          '<(DEPTH)/chrome/test/data/push_messaging/',
-          '<(DEPTH)/chrome/test/data/translate/',
-          '<(DEPTH)/chrome/test/data/webapps/',
-          '<(DEPTH)/chrome/test/media_router/resources/',
-          '<(DEPTH)/content/test/data/android/geolocation.html',
-          '<(DEPTH)/content/test/data/media/getusermedia.html',
-          '<(DEPTH)/content/test/data/media/session/',
-          '<(DEPTH)/content/test/data/media/webrtc_test_utilities.js',
-        ],
-      },
-    }],
-  ],
+  'variables': {
+    'files': [
+      '<(DEPTH)/chrome/test/data/android/',
+      '<(DEPTH)/chrome/test/data/banners/',
+      '<(DEPTH)/chrome/test/data/encoding_tests/auto_detect/Big5_with_no_encoding_specified.html',
+      '<(DEPTH)/chrome/test/data/geolocation/',
+      '<(DEPTH)/chrome/test/data/google/',
+      '<(DEPTH)/chrome/test/data/image_search/valid.png',
+      '<(DEPTH)/chrome/test/data/navigation_interception/',
+      '<(DEPTH)/chrome/test/data/notifications/',
+      '<(DEPTH)/chrome/test/data/popup_blocker/',
+      '<(DEPTH)/chrome/test/data/push_messaging/',
+      '<(DEPTH)/chrome/test/data/translate/',
+      '<(DEPTH)/chrome/test/data/webapps/',
+      '<(DEPTH)/chrome/test/media_router/resources/',
+      '<(DEPTH)/content/test/data/android/geolocation.html',
+      '<(DEPTH)/content/test/data/media/getusermedia.html',
+      '<(DEPTH)/content/test/data/media/session/',
+      '<(DEPTH)/content/test/data/media/webrtc_test_utilities.js',
+    ],
+  },
 }
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 2e35b4c..4742da6 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1065,6 +1065,7 @@
       'browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc',
       'browser/chromeos/policy/affiliated_cloud_policy_invalidator_unittest.cc',
       'browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc',
+      'browser/chromeos/policy/android_management_client_unittest.cc',
       'browser/chromeos/policy/auto_enrollment_client_unittest.cc',
       'browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc',
       'browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc',
diff --git a/chrome/chrome_watcher/kasko_util.cc b/chrome/chrome_watcher/kasko_util.cc
index c6c446d..1bb0864 100644
--- a/chrome/chrome_watcher/kasko_util.cc
+++ b/chrome/chrome_watcher/kasko_util.cc
@@ -7,6 +7,7 @@
 #include <sddl.h>
 
 #include <memory>
+#include <set>
 #include <string>
 #include <utility>
 #include <vector>
@@ -141,7 +142,7 @@
 
 // Get the |process| and the |thread_id| of the node inside the |wait_chain|
 // that is of type ThreadType and belongs to a process that is valid for the
-// capture of a crash dump. Returns if such a node was found.
+// capture of a crash dump. Returns true if such a node was found.
 bool GetLastValidNodeInfo(const base::win::WaitChainNodeVector& wait_chain,
                           base::Process* process,
                           DWORD* thread_id) {
@@ -161,6 +162,68 @@
   return false;
 }
 
+// Adds the entire wait chain to |crash_keys|.
+//
+// As an example (key : value):
+// hung-process-wait-chain-00 : Thread 10242 in process 4554 with status Blocked
+// hung-process-wait-chain-01 : Lock of type ThreadWait with status Owned
+// hung-process-wait-chain-02 : Thread 77221 in process 4554 with status Blocked
+//
+void AddWaitChainToCrashKeys(const base::win::WaitChainNodeVector& wait_chain,
+                             std::vector<kasko::api::CrashKey>* crash_keys) {
+  for (size_t i = 0; i < wait_chain.size(); i++) {
+    AddCrashKey(
+        base::StringPrintf(L"hung-process-wait-chain-%02" PRIuS, i).c_str(),
+        base::win::WaitChainNodeToString(wait_chain[i]).c_str(), crash_keys);
+  }
+}
+
+base::FilePath GetExeFilePathForProcess(const base::Process& process) {
+  wchar_t exe_name[MAX_PATH];
+  DWORD exe_name_len = arraysize(exe_name);
+  // Note: requesting the Win32 path format.
+  if (::QueryFullProcessImageName(process.Handle(), 0, exe_name,
+                                  &exe_name_len) == 0) {
+    DPLOG(ERROR) << "Failed to get executable name for process";
+    return base::FilePath();
+  }
+
+  // QueryFullProcessImageName's documentation does not specify behavior when
+  // the buffer is too small, but we know that GetModuleFileNameEx succeeds and
+  // truncates the returned name in such a case. Given that paths of arbitrary
+  // length may exist, the conservative approach is to reject names when
+  // the returned length is that of the buffer.
+  if (exe_name_len > 0 && exe_name_len < arraysize(exe_name))
+    return base::FilePath(exe_name);
+
+  return base::FilePath();
+}
+
+// Adds the executable base name for each unique pid found in the |wait_chain|
+// to the |crash_keys|.
+void AddProcessExeNameToCrashKeys(
+    const base::win::WaitChainNodeVector& wait_chain,
+    std::vector<kasko::api::CrashKey>* crash_keys) {
+  std::set<DWORD> unique_pids;
+  for (size_t i = 0; i < wait_chain.size(); i += 2)
+    unique_pids.insert(wait_chain[i].ThreadObject.ProcessId);
+
+  for (DWORD pid : unique_pids) {
+    // This is racy on the pid but for the purposes of this function, some error
+    // threshold can be tolerated. Hopefully the race doesn't happen often.
+    base::Process process(
+        base::Process::OpenWithAccess(pid, PROCESS_QUERY_LIMITED_INFORMATION));
+
+    base::string16 exe_file_path = L"N/A";
+    if (process.IsValid())
+      exe_file_path = GetExeFilePathForProcess(process).BaseName().value();
+
+    AddCrashKey(
+        base::StringPrintf(L"hung-process-wait-chain-pid-%u", pid).c_str(),
+        exe_file_path.c_str(), crash_keys);
+  }
+}
+
 }  // namespace
 
 bool InitializeKaskoReporter(const base::string16& endpoint,
@@ -185,31 +248,13 @@
 }
 
 bool EnsureTargetProcessValidForCapture(const base::Process& process) {
-  // Ensure the target process shares the current process's executable name.
-  base::FilePath exe_self;
-  if (!PathService::Get(base::FILE_EXE, &exe_self))
+  // Ensure the target process's executable is inside the current Chrome
+  // directory.
+  base::FilePath chrome_dir;
+  if (!PathService::Get(base::DIR_EXE, &chrome_dir))
     return false;
 
-  wchar_t exe_name_other[MAX_PATH];
-  DWORD exe_name_other_len = arraysize(exe_name_other);
-  // Note: requesting the Win32 path format.
-  if (::QueryFullProcessImageName(process.Handle(), 0, exe_name_other,
-                                  &exe_name_other_len) == 0) {
-    DPLOG(ERROR) << "Failed to get executable name for other process";
-    return false;
-  }
-
-  // QueryFullProcessImageName's documentation does not specify behavior when
-  // the buffer is too small, but we know that GetModuleFileNameEx succeeds and
-  // truncates the returned name in such a case. Given that paths of arbitrary
-  // length may exist, the conservative approach is to reject names when
-  // the returned length is that of the buffer.
-  if (exe_name_other_len > 0 &&
-      exe_name_other_len < arraysize(exe_name_other)) {
-    return base::FilePath::CompareEqualIgnoreCase(exe_self.value(),
-                                                  exe_name_other);
-  }
-  return false;
+  return chrome_dir.IsParent(GetExeFilePathForProcess(process));
 }
 
 void DumpHungProcess(DWORD main_thread_id, const base::string16& channel,
@@ -236,22 +281,11 @@
         GetLastValidNodeInfo(wait_chain, &hung_process, &hung_thread_id);
     DCHECK(found_valid_node);
 
-    // The entire wait chain is added to the crash report via crash keys.
-    //
-    // As an example (key : value):
-    // hung-process-is-deadlock  : false
-    // hung-process-wait-chain-00 : Thread #10242 with status Blocked
-    // hung-process-wait-chain-01 : Lock of type ThreadWait with status Owned
-    // hung-process-wait-chain-02 : Thread #77221 with status Blocked
-    //
+    // Add some interesting data about the wait chain to the crash keys.
     AddCrashKey(L"hung-process-is-deadlock", is_deadlock ? L"true" : L"false",
                 &annotations);
-    for (size_t i = 0; i < wait_chain.size(); i++) {
-      AddCrashKey(
-          base::StringPrintf(L"hung-process-wait-chain-%02" PRIuS, i).c_str(),
-          base::win::WaitChainNodeToString(wait_chain[i]).c_str(),
-          &annotations);
-    }
+    AddWaitChainToCrashKeys(wait_chain, &annotations);
+    AddProcessExeNameToCrashKeys(wait_chain, &annotations);
   } else {
     // The call to GetThreadWaitChain() failed. Include the reason inside the
     // report using crash keys.
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index 5d66568f..3332ed6 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -73,6 +73,7 @@
     "//chrome/common/safe_browsing:proto",
     "//chrome/common/variations:fieldtrial_testing_config",
     "//chrome/installer/util:with_no_strings",
+    "//components/cdm/common",
     "//components/cloud_devices/common",
     "//components/component_updater",
     "//components/content_settings/core/common",
diff --git a/chrome/common/DEPS b/chrome/common/DEPS
index 3234cc6..a09049e 100644
--- a/chrome/common/DEPS
+++ b/chrome/common/DEPS
@@ -4,6 +4,7 @@
   "+components/autofill/content/common",
   "+components/autofill/core/common",
   "+components/bookmarks/common",
+  "+components/cdm/common",
   "+components/cloud_devices/common",
   "+components/content_settings/core/common",
   "+components/crash/core/common",
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index da7d532..fb1b7585 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -79,6 +79,10 @@
 #include "chrome/common/widevine_cdm_constants.h"
 #endif
 
+#if defined(OS_ANDROID)
+#include "chrome/common/chrome_media_client_android.h"
+#endif
+
 namespace {
 
 #if defined(ENABLE_PLUGINS)
@@ -687,3 +691,9 @@
 base::StringPiece ChromeContentClient::GetOriginTrialPublicKey() {
   return origin_trial_key_manager_.GetPublicKey();
 }
+
+#if defined(OS_ANDROID)
+media::MediaClientAndroid* ChromeContentClient::GetMediaClientAndroid() {
+  return new ChromeMediaClientAndroid();
+}
+#endif  // OS_ANDROID
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h
index bdc23a8d..0a08446 100644
--- a/chrome/common/chrome_content_client.h
+++ b/chrome/common/chrome_content_client.h
@@ -95,6 +95,10 @@
     return &origin_trial_key_manager_;
   }
 
+#if defined(OS_ANDROID)
+  media::MediaClientAndroid* GetMediaClientAndroid() override;
+#endif  // OS_ANDROID
+
  private:
   OriginTrialKeyManager origin_trial_key_manager_;
 };
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 067ebfb..c1546ba 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -14,6 +14,11 @@
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
 
+// Fixes for browser hang bugs are deployed in a field trial in order to measure
+// their impact. See crbug.com/478209.
+const base::Feature kBrowserHangFixesExperiment{
+    "BrowserHangFixesExperiment", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables Expect CT reporting, which sends reports for opted-in sites
 // that don't serve sufficient Certificate Transparency information.
 const base::Feature kExpectCTReporting{"ExpectCTReporting",
@@ -50,16 +55,8 @@
 // A new user experience for transitioning into fullscreen and mouse pointer
 // lock states. The name is a misnomer (for historical reasons); affects both
 // Views and Android builds.
-const base::Feature kSimplifiedFullscreenUI{
-    "ViewsSimplifiedFullscreenUI",
-#if defined(USE_AURA)
-    // Windows, Linux, Chrome OS.
-    base::FEATURE_ENABLED_BY_DEFAULT,
-#else
-    // Mac, Android.
-    base::FEATURE_DISABLED_BY_DEFAULT,
-#endif
-};
+const base::Feature kSimplifiedFullscreenUI{"ViewsSimplifiedFullscreenUI",
+                                            base::FEATURE_ENABLED_BY_DEFAULT};
 
 #if defined(SYZYASAN)
 // Enable the deferred free mechanism in the syzyasan module, which helps the
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index a90d33da..e2d2599 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -19,6 +19,8 @@
 extern const base::Feature kAutomaticTabDiscarding;
 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
 
+extern const base::Feature kBrowserHangFixesExperiment;
+
 extern const base::Feature kExpectCTReporting;
 
 extern const base::Feature kExperimentalKeyboardLockUI;
diff --git a/chrome/browser/android/chrome_media_client_android.cc b/chrome/common/chrome_media_client_android.cc
similarity index 69%
rename from chrome/browser/android/chrome_media_client_android.cc
rename to chrome/common/chrome_media_client_android.cc
index 1f8a542..3aca17d 100644
--- a/chrome/browser/android/chrome_media_client_android.cc
+++ b/chrome/common/chrome_media_client_android.cc
@@ -2,13 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/android/chrome_media_client_android.h"
+#include "chrome/common/chrome_media_client_android.h"
 
-ChromeMediaClientAndroid::ChromeMediaClientAndroid() {
-}
+ChromeMediaClientAndroid::ChromeMediaClientAndroid() {}
 
-ChromeMediaClientAndroid::~ChromeMediaClientAndroid() {
-}
+ChromeMediaClientAndroid::~ChromeMediaClientAndroid() {}
 
 media::MediaDrmBridgeDelegate*
 ChromeMediaClientAndroid::GetMediaDrmBridgeDelegate(
diff --git a/chrome/browser/android/chrome_media_client_android.h b/chrome/common/chrome_media_client_android.h
similarity index 73%
rename from chrome/browser/android/chrome_media_client_android.h
rename to chrome/common/chrome_media_client_android.h
index fb7c027..2e322e5 100644
--- a/chrome/browser/android/chrome_media_client_android.h
+++ b/chrome/common/chrome_media_client_android.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ANDROID_CHROME_MEDIA_CLIENT_ANDROID_H_
-#define CHROME_BROWSER_ANDROID_CHROME_MEDIA_CLIENT_ANDROID_H_
+#ifndef CHROME_COMMON_CHROME_MEDIA_CLIENT_ANDROID_H_
+#define CHROME_COMMON_CHROME_MEDIA_CLIENT_ANDROID_H_
 
 #include <stdint.h>
 
 #include "base/macros.h"
-#include "components/cdm/browser/widevine_drm_delegate_android.h"
+#include "components/cdm/common/widevine_drm_delegate_android.h"
 #include "media/base/android/media_client_android.h"
 
 class ChromeMediaClientAndroid : public media::MediaClientAndroid {
@@ -26,4 +26,4 @@
   DISALLOW_COPY_AND_ASSIGN(ChromeMediaClientAndroid);
 };
 
-#endif  // CHROME_BROWSER_ANDROID_CHROME_MEDIA_CLIENT_ANDROID_H_
+#endif  // CHROME_COMMON_CHROME_MEDIA_CLIENT_ANDROID_H_
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 30f75d4..4fa85eb3 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -282,9 +282,6 @@
 // Disables the new bookmark app system.
 const char kDisableNewBookmarkApps[]        = "disable-new-bookmark-apps";
 
-// Disables showing popular sites on the NTP.
-const char kDisableNTPPopularSites[]        = "disable-ntp-popular-sites";
-
 // Disable auto-reload of error pages if offline.
 const char kDisableOfflineAutoReload[]       = "disable-offline-auto-reload";
 
@@ -449,14 +446,6 @@
 // Enables the new bookmark app system.
 const char kEnableNewBookmarkApps[]         = "enable-new-bookmark-apps";
 
-// Enables showing popular sites on the NTP.
-const char kEnableNTPPopularSites[]         = "enable-ntp-popular-sites";
-
-// Enables using the default search engine country to show country specific
-// popular sites on the NTP.
-const char kEnableNTPSearchEngineCountryDetection[] =
-    "enable-ntp-search-engine-country-detection";
-
 // Enable auto-reload of error pages if offline.
 const char kEnableOfflineAutoReload[]       = "enable-offline-auto-reload";
 
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 32fe74b..ca0df6e 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -81,7 +81,6 @@
 extern const char kDisableHttp2[];
 extern const char kDisableMinimizeOnSecondLauncherItemClick[];
 extern const char kDisableNewBookmarkApps[];
-extern const char kDisableNTPPopularSites[];
 extern const char kDisableOfflineAutoReload[];
 extern const char kDisableOfflineAutoReloadVisibleOnly[];
 extern const char kDisableOutOfProcessPac[];
@@ -131,8 +130,6 @@
 extern const char kEnableNavigationTracing[];
 extern const char kEnableNetBenchmarking[];
 extern const char kEnableNewBookmarkApps[];
-extern const char kEnableNTPPopularSites[];
-extern const char kEnableNTPSearchEngineCountryDetection[];
 extern const char kEnableOfflineAutoReload[];
 extern const char kEnableOfflineAutoReloadVisibleOnly[];
 extern const char kEnablePanels[];
diff --git a/chrome/common/pepper_flash.cc b/chrome/common/pepper_flash.cc
index d7a5ac4..cad9199 100644
--- a/chrome/common/pepper_flash.cc
+++ b/chrome/common/pepper_flash.cc
@@ -126,8 +126,16 @@
 
   std::string arch;
   manifest.GetStringASCII("x-ppapi-arch", &arch);
-  if (arch != kPepperFlashArch)
+  if (arch != kPepperFlashArch) {
+#if defined(OS_MACOSX)
+    // On Mac OS X the arch is 'x64' for component updated Flash but 'mac' for
+    // system Flash, so accept both variations.
+    if (arch != kPepperFlashOperatingSystem)
+      return false;
+#else
     return false;
+#endif
+  }
 
   *version_out = version;
   return true;
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 73bb224..925f61b 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1494,15 +1494,6 @@
 // Which page should be visible on the new tab page v4
 const char kNtpShownPage[] = "ntp.shown_page";
 
-#if BUILDFLAG(ANDROID_JAVA_UI)
-// Ordered list of website suggestions shown on the new tab page that will allow
-// retaining the order even if the suggestions change over time.
-const char kNTPSuggestionsURL[] = "ntp.suggestions_url";
-
-// Whether the suggestion was derived from personal data.
-const char kNTPSuggestionsIsPersonal[] = "ntp.suggestions_is_personal";
-#endif
-
 // A private RSA key for ADB handshake.
 const char kDevToolsAdbKey[] = "devtools.adb_key";
 
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index e28d0f9572..4e67376 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -528,10 +528,6 @@
 extern const char kNtpCollapsedSyncPromo[];
 #endif
 extern const char kNtpShownPage[];
-#if BUILDFLAG(ANDROID_JAVA_UI)
-extern const char kNTPSuggestionsURL[];
-extern const char kNTPSuggestionsIsPersonal[];
-#endif
 
 extern const char kDevToolsAdbKey[];
 extern const char kDevToolsDisabled[];
diff --git a/chrome/installer/mini_installer.gyp b/chrome/installer/mini_installer.gyp
index cdb5227b..4bf29048 100644
--- a/chrome/installer/mini_installer.gyp
+++ b/chrome/installer/mini_installer.gyp
@@ -26,7 +26,7 @@
           'includes': [
             'mini_installer.gypi',
           ],
-        }
+        },
       ],
       'conditions': [
         ['test_isolation_mode != "noop"', {
@@ -46,6 +46,44 @@
             },
           ],
         }],
+        # next_version_mini_installer.exe can't be generated in an x86 Debug
+        # component build because it requires too much memory. Don't define the
+        # target for any x86 component build since gyp doesn't allow use of the
+        # configuration name in conditionals.
+        ['component!="shared_library" or target_arch!="ia32"', {
+          'targets': [
+            {
+              # GN version: //chrome/installer/mini_installer:next_version_mini_installer
+              'target_name': 'next_version_mini_installer',
+              'type': 'none',
+              'dependencies': [
+                'mini_installer',
+                '<(DEPTH)/chrome/installer/upgrade_test.gyp:alternate_version_generator',
+              ],
+              'variables': {
+                'alternate_version_generator_exe': 'alternate_version_generator.exe',
+                'next_version_mini_installer_exe': 'next_version_mini_installer.exe',
+              },
+              'actions': [
+                {
+                  'action_name': 'generate_next_version_mini_installer',
+                  'inputs': [
+                    '<(PRODUCT_DIR)/<(alternate_version_generator_exe)',
+                    '<(PRODUCT_DIR)/mini_installer.exe',
+                  ],
+                  'outputs': [
+                    '<(PRODUCT_DIR)/next_version_mini_installer.exe',
+                  ],
+                  'action': [
+                    '<(PRODUCT_DIR)/<(alternate_version_generator_exe)',
+                    '--force',
+                    '--out=<(PRODUCT_DIR)/<(next_version_mini_installer_exe)',
+                  ],
+                }
+              ],
+            },
+          ],
+        }],
       ],
     }],
   ],
diff --git a/chrome/installer/mini_installer/BUILD.gn b/chrome/installer/mini_installer/BUILD.gn
index 643d7bd8..3c51be1 100644
--- a/chrome/installer/mini_installer/BUILD.gn
+++ b/chrome/installer/mini_installer/BUILD.gn
@@ -204,3 +204,27 @@
     "//build/win:default_exe_manifest",
   ]
 }
+
+# next_version_mini_installer.exe can't be generated in an x86 Debug component
+# build because it requires too much memory.
+if (!(is_component_build && is_debug && target_cpu == "x86")) {
+  action("next_version_mini_installer") {
+    script = "generate_next_version_mini_installer.py"
+    testonly = true
+    inputs = [
+      "$root_out_dir/alternate_version_generator.exe",
+      "$root_out_dir/mini_installer.exe",
+    ]
+    outputs = [
+      "$root_out_dir/$target_name.exe",
+    ]
+    args = [
+      "--out",
+      "$target_name.exe",
+    ]
+    deps = [
+      ":mini_installer",
+      "//chrome/installer/test:alternate_version_generator",
+    ]
+  }
+}
diff --git a/chrome/installer/mini_installer/generate_next_version_mini_installer.py b/chrome/installer/mini_installer/generate_next_version_mini_installer.py
new file mode 100644
index 0000000..0cccf71
--- /dev/null
+++ b/chrome/installer/mini_installer/generate_next_version_mini_installer.py
@@ -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.
+
+"""Generates a mini_installer with a higher version than an existing one."""
+
+import argparse
+import subprocess
+import sys
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--out', help='Path to the generated mini_installer.')
+  args = parser.parse_args()
+  assert args.out
+
+  return subprocess.call([
+      'alternate_version_generator.exe',
+      '--force',
+      '--out=' + args.out,
+      ])
+
+
+if '__main__' == __name__:
+  sys.exit(main())
diff --git a/chrome/installer/test/alternate_version_generator_main.cc b/chrome/installer/test/alternate_version_generator_main.cc
index 9ee11901..3761735d 100644
--- a/chrome/installer/test/alternate_version_generator_main.cc
+++ b/chrome/installer/test/alternate_version_generator_main.cc
@@ -160,8 +160,10 @@
   std::wstring original_version;
   std::wstring new_version;
 
-  if (upgrade_test::GenerateAlternateVersion(mini_installer, out, direction,
-                                             &original_version, &new_version)) {
+  if (upgrade_test::GenerateAlternateVersion(
+          base::MakeAbsoluteFilePath(mini_installer),
+          base::MakeAbsoluteFilePath(out), direction, &original_version,
+          &new_version)) {
     fwprintf(stdout, L"Generated version %s from version %s\n",
              new_version.c_str(), original_version.c_str());
     return EXIT_SUCCESS;
diff --git a/chrome/installer/util/logging_installer.cc b/chrome/installer/util/logging_installer.cc
index 0def364..7e184ee 100644
--- a/chrome/installer/util/logging_installer.cc
+++ b/chrome/installer/util/logging_installer.cc
@@ -115,7 +115,11 @@
     return base::FilePath(base::UTF8ToWide(path));
 
   static const base::FilePath::CharType kLogFilename[] =
+#if defined(GOOGLE_CHROME_BUILD)
       FILE_PATH_LITERAL("chrome_installer.log");
+#else  // CHROMIUM_BUILD
+      FILE_PATH_LITERAL("chromium_installer.log");
+#endif
 
   // Fallback to current directory if getting the temp directory fails.
   base::FilePath tmp_path;
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 3be44db4e..23741db 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1243,6 +1243,11 @@
 
 void ChromeContentRendererClient::AddKeySystems(
     std::vector<media::KeySystemInfo>* key_systems) {
+  AddChromeKeySystemsInfo(key_systems);
+}
+
+void ChromeContentRendererClient::AddSupportedKeySystems(
+    std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
   AddChromeKeySystems(key_systems);
 }
 
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index aa3c859..4ab17cd5 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -130,6 +130,9 @@
                                          blink::WebFrame* frame) override;
   bool AllowPepperMediaStreamAPI(const GURL& url) override;
   void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
+  void AddSupportedKeySystems(
+      std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
+      override;
   bool IsPluginAllowedToUseDevChannelAPIs() override;
   bool IsPluginAllowedToUseCameraDeviceAPI(const GURL& url) override;
   bool IsPluginAllowedToUseCompositorAPI(const GURL& url) override;
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc
index e05fe0dc..31a4199 100644
--- a/chrome/renderer/media/chrome_key_systems.cc
+++ b/chrome/renderer/media/chrome_key_systems.cc
@@ -15,9 +15,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/common/render_messages.h"
-#include "components/cdm/renderer/widevine_key_systems.h"
+#include "components/cdm/renderer/widevine_key_system_properties.h"
 #include "content/public/renderer/render_thread.h"
 #include "media/base/eme_constants.h"
+#include "media/base/key_system_info.h"
+#include "media/base/key_system_properties.h"
+
 #include "media/media_features.h"
 
 #if defined(OS_ANDROID)
@@ -34,6 +37,7 @@
 #endif
 
 using media::KeySystemInfo;
+using media::KeySystemProperties;
 using media::SupportedCodecs;
 
 #if defined(ENABLE_PEPPER_CDMS)
@@ -150,7 +154,7 @@
 }
 
 static void AddPepperBasedWidevine(
-    std::vector<KeySystemInfo>* concrete_key_systems) {
+    std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) {
 #if defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
   Version glibc_version(gnu_get_libc_version());
   DCHECK(glibc_version.IsValid());
@@ -198,7 +202,7 @@
 #endif  // defined(USE_PROPRIETARY_CODECS)
   }
 
-  cdm::AddWidevineWithCodecs(
+  concrete_key_systems->emplace_back(new cdm::WidevineKeySystemProperties(
       supported_codecs,
 #if defined(OS_CHROMEOS)
       media::EmeRobustness::HW_SECURE_ALL,  // Maximum audio robustness.
@@ -206,33 +210,37 @@
       media::EmeSessionTypeSupport::
           SUPPORTED_WITH_IDENTIFIER,  // Persistent-license.
       media::EmeSessionTypeSupport::
-          NOT_SUPPORTED,                      // Persistent-release-message.
-      media::EmeFeatureSupport::REQUESTABLE,  // Persistent state.
-      media::EmeFeatureSupport::REQUESTABLE,  // Distinctive identifier.
+          NOT_SUPPORTED,                        // Persistent-release-message.
+      media::EmeFeatureSupport::REQUESTABLE,    // Persistent state.
+      media::EmeFeatureSupport::REQUESTABLE));  // Distinctive identifier.
 #else   // (Desktop)
       media::EmeRobustness::SW_SECURE_CRYPTO,       // Maximum audio robustness.
       media::EmeRobustness::SW_SECURE_DECODE,       // Maximum video robustness.
       media::EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-license.
       media::EmeSessionTypeSupport::
-          NOT_SUPPORTED,                        // persistent-release-message.
-      media::EmeFeatureSupport::REQUESTABLE,    // Persistent state.
-      media::EmeFeatureSupport::NOT_SUPPORTED,  // Distinctive identifier.
+          NOT_SUPPORTED,                          // persistent-release-message.
+      media::EmeFeatureSupport::REQUESTABLE,      // Persistent state.
+      media::EmeFeatureSupport::NOT_SUPPORTED));  // Distinctive identifier.
 #endif  // defined(OS_CHROMEOS)
-      concrete_key_systems);
 }
 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
 #endif  // defined(ENABLE_PEPPER_CDMS)
 
-void AddChromeKeySystems(std::vector<KeySystemInfo>* key_systems_info) {
+void AddChromeKeySystemsInfo(std::vector<KeySystemInfo>* key_systems_info) {
 #if defined(ENABLE_PEPPER_CDMS)
   AddExternalClearKey(key_systems_info);
+#endif
+}
 
+void AddChromeKeySystems(
+    std::vector<std::unique_ptr<KeySystemProperties>>* key_systems_properties) {
+#if defined(ENABLE_PEPPER_CDMS)
 #if defined(WIDEVINE_CDM_AVAILABLE)
-  AddPepperBasedWidevine(key_systems_info);
+  AddPepperBasedWidevine(key_systems_properties);
 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
 #endif  // defined(ENABLE_PEPPER_CDMS)
 
 #if defined(OS_ANDROID)
-  cdm::AddAndroidWidevine(key_systems_info);
+  cdm::AddAndroidWidevine(key_systems_properties);
 #endif  // defined(OS_ANDROID)
 }
diff --git a/chrome/renderer/media/chrome_key_systems.h b/chrome/renderer/media/chrome_key_systems.h
index dfec84f..ab1be50 100644
--- a/chrome/renderer/media/chrome_key_systems.h
+++ b/chrome/renderer/media/chrome_key_systems.h
@@ -5,10 +5,23 @@
 #ifndef CHROME_RENDERER_MEDIA_CHROME_KEY_SYSTEMS_H_
 #define CHROME_RENDERER_MEDIA_CHROME_KEY_SYSTEMS_H_
 
+#include <memory>
 #include <vector>
 
-#include "media/base/key_system_info.h"
+namespace media {
+struct KeySystemInfo;
+class KeySystemProperties;
+}
 
-void AddChromeKeySystems(std::vector<media::KeySystemInfo>* key_systems_info);
+// DEPRECATED: Register the key systems supported by populating
+// |key_systems_info|.  TODO(halliwell): move all key systems to
+// KeySystemProperties API.
+void AddChromeKeySystemsInfo(
+    std::vector<media::KeySystemInfo>* key_systems_info);
+
+// Register the key systems supported by populating |key_systems_properties|.
+void AddChromeKeySystems(
+    std::vector<std::unique_ptr<media::KeySystemProperties>>*
+        key_systems_properties);
 
 #endif  // CHROME_RENDERER_MEDIA_CHROME_KEY_SYSTEMS_H_
diff --git a/chrome/renderer/resources/extensions/automation/automation_event.js b/chrome/renderer/resources/extensions/automation/automation_event.js
index 0ba408d..bd5a3d2 100644
--- a/chrome/renderer/resources/extensions/automation/automation_event.js
+++ b/chrome/renderer/resources/extensions/automation/automation_event.js
@@ -4,19 +4,20 @@
 
 var utils = require('utils');
 
-var AutomationEventImpl = function(type, target) {
+function AutomationEventImpl(type, target) {
   this.propagationStopped = false;
 
   // TODO(aboxhall): make these read-only properties
   this.type = type;
   this.target = target;
   this.eventPhase = Event.NONE;
-};
+}
 
 AutomationEventImpl.prototype = {
+  __proto__: null,
   stopPropagation: function() {
     this.propagationStopped = true;
-  }
+  },
 };
 
 function AutomationEvent() {
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js
index 3c87581..f36a2b9 100644
--- a/chrome/renderer/resources/extensions/automation/automation_node.js
+++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -199,15 +199,13 @@
  */
 function AutomationNodeImpl(root) {
   this.rootImpl = root;
-  // Public attributes. No actual data gets set on this object.
-  this.listeners = {};
+  this.listeners = {__proto__: null};
 }
 
 AutomationNodeImpl.prototype = {
+  __proto__: null,
   treeID: -1,
   id: -1,
-  role: '',
-  state: { busy: true },
   isRootNode: false,
 
   get root() {
@@ -275,7 +273,7 @@
     for (var i = 0; i < count; ++i) {
       var childID = GetChildIDAtIndex(this.treeID, this.id, i);
       var child = this.rootImpl.get(childID);
-      children.push(child);
+      $Array.push(children, child);
     }
     return children;
   },
@@ -326,7 +324,7 @@
       { treeID: this.rootImpl.treeID,
         automationNodeID: this.id,
         selector: selector },
-      this.domQuerySelectorCallback_.bind(this, callback));
+      $Function.bind(this.domQuerySelectorCallback_, this, callback));
   },
 
   find: function(params) {
@@ -345,7 +343,11 @@
     this.removeEventListener(eventType, callback);
     if (!this.listeners[eventType])
       this.listeners[eventType] = [];
-    this.listeners[eventType].push({callback: callback, capture: !!capture});
+    $Array.push(this.listeners[eventType], {
+      __proto__: null,
+      callback: callback,
+      capture: !!capture,
+    });
   },
 
   // TODO(dtseng/aboxhall): Check this impl against spec.
@@ -354,7 +356,7 @@
       var listeners = this.listeners[eventType];
       for (var i = 0; i < listeners.length; i++) {
         if (callback === listeners[i].callback)
-          listeners.splice(i, 1);
+          $Array.splice(listeners, i, 1);
       }
     }
   },
@@ -370,7 +372,7 @@
     var path = [];
     var parent = this.parent;
     while (parent) {
-      path.push(parent);
+      $Array.push(path, parent);
       parent = parent.parent;
     }
     var event = new AutomationEvent(eventType, this.wrapper);
@@ -394,7 +396,7 @@
     var childIDs = [];
     for (var i = 0; i < count; ++i) {
       var childID = GetChildIDAtIndex(this.treeID, this.id, i);
-      childIDs.push(childID);
+      $Array.push(childIDs, childID);
     }
 
     var result = 'node id=' + this.id +
@@ -500,7 +502,7 @@
     this.forAllDescendants_(function(node) {
       if (privates(node).impl.matchInternal_(params)) {
         if (opt_results)
-          opt_results.push(node);
+          $Array.push(opt_results, node);
         else
           result = node;
         return !opt_results;
@@ -518,20 +520,20 @@
    *     for each node. Return true to early-out the traversal.
    */
   forAllDescendants_: function(closure) {
-    var stack = this.wrapper.children.reverse();
+    var stack = $Array.reverse(this.wrapper.children);
     while (stack.length > 0) {
-      var node = stack.pop();
+      var node = $Array.pop(stack);
       if (closure(node))
         return;
 
       var children = node.children;
       for (var i = children.length - 1; i >= 0; i--)
-        stack.push(children[i]);
+        $Array.push(stack, children[i]);
     }
   },
 
   matchInternal_: function(params) {
-    if (Object.keys(params).length == 0)
+    if ($Object.keys(params).length === 0)
       return false;
 
     if ('role' in params && this.role != params.role)
@@ -549,7 +551,7 @@
         if (typeof attrValue != 'object') {
           if (this[attribute] !== attrValue)
             return false;
-        } else if (attrValue instanceof RegExp) {
+        } else if (attrValue instanceof $RegExp.self) {
           if (typeof this[attribute] != 'string')
             return false;
           if (!attrValue.test(this[attribute]))
@@ -660,38 +662,42 @@
 
 var publicAttributes = [];
 
-stringAttributes.forEach(function (attributeName) {
-  publicAttributes.push(attributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+$Array.forEach(stringAttributes, function(attributeName) {
+  $Array.push(publicAttributes, attributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+    __proto__: null,
     get: function() {
       return GetStringAttribute(this.treeID, this.id, attributeName);
     }
   });
 });
 
-boolAttributes.forEach(function (attributeName) {
-  publicAttributes.push(attributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+$Array.forEach(boolAttributes, function(attributeName) {
+  $Array.push(publicAttributes, attributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+    __proto__: null,
     get: function() {
       return GetBoolAttribute(this.treeID, this.id, attributeName);
     }
   });
 });
 
-intAttributes.forEach(function (attributeName) {
-  publicAttributes.push(attributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+$Array.forEach(intAttributes, function(attributeName) {
+  $Array.push(publicAttributes, attributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+    __proto__: null,
     get: function() {
       return GetIntAttribute(this.treeID, this.id, attributeName);
     }
   });
 });
 
-nodeRefAttributes.forEach(function (params) {
+$Array.forEach(nodeRefAttributes, function(params) {
   var srcAttributeName = params[0];
   var dstAttributeName = params[1];
-  publicAttributes.push(dstAttributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
+  $Array.push(publicAttributes, dstAttributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
+    __proto__: null,
     get: function() {
       var id = GetIntAttribute(this.treeID, this.id, srcAttributeName);
       if (id)
@@ -702,20 +708,22 @@
   });
 });
 
-intListAttributes.forEach(function (attributeName) {
-  publicAttributes.push(attributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+$Array.forEach(intListAttributes, function(attributeName) {
+  $Array.push(publicAttributes, attributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+    __proto__: null,
     get: function() {
       return GetIntListAttribute(this.treeID, this.id, attributeName);
     }
   });
 });
 
-nodeRefListAttributes.forEach(function (params) {
+$Array.forEach(nodeRefListAttributes, function(params) {
   var srcAttributeName = params[0];
   var dstAttributeName = params[1];
-  publicAttributes.push(dstAttributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
+  $Array.push(publicAttributes, dstAttributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
+    __proto__: null,
     get: function() {
       var ids = GetIntListAttribute(this.treeID, this.id, srcAttributeName);
       if (!ids)
@@ -724,27 +732,29 @@
       for (var i = 0; i < ids.length; ++i) {
         var node = this.rootImpl.get(ids[i]);
         if (node)
-          result.push(node);
+          $Array.push(result, node);
       }
       return result;
     }
   });
 });
 
-floatAttributes.forEach(function (attributeName) {
-  publicAttributes.push(attributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+$Array.forEach(floatAttributes, function(attributeName) {
+  $Array.push(publicAttributes, attributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
+    __proto__: null,
     get: function() {
       return GetFloatAttribute(this.treeID, this.id, attributeName);
     }
   });
 });
 
-htmlAttributes.forEach(function (params) {
+$Array.forEach(htmlAttributes, function(params) {
   var srcAttributeName = params[0];
   var dstAttributeName = params[1];
-  publicAttributes.push(dstAttributeName);
-  Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
+  $Array.push(publicAttributes, dstAttributeName);
+  $Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
+    __proto__: null,
     get: function() {
       return GetHtmlAttribute(this.treeID, this.id, srcAttributeName);
     }
@@ -769,29 +779,30 @@
  * @constructor
  */
 function AutomationRootNodeImpl(treeID) {
-  AutomationNodeImpl.call(this, this);
+  $Function.call(AutomationNodeImpl, this, this);
   this.treeID = treeID;
-  this.axNodeDataCache_ = {};
+  this.axNodeDataCache_ = {__proto__: null};
 }
 
-AutomationRootNodeImpl.idToAutomationRootNode_ = {};
+utils.defineProperty(AutomationRootNodeImpl, 'idToAutomationRootNode_',
+    {__proto__: null});
 
-AutomationRootNodeImpl.get = function(treeID) {
+utils.defineProperty(AutomationRootNodeImpl, 'get', function(treeID) {
   var result = AutomationRootNodeImpl.idToAutomationRootNode_[treeID];
   return result || undefined;
-}
+});
 
-AutomationRootNodeImpl.getOrCreate = function(treeID) {
+utils.defineProperty(AutomationRootNodeImpl, 'getOrCreate', function(treeID) {
   if (AutomationRootNodeImpl.idToAutomationRootNode_[treeID])
     return AutomationRootNodeImpl.idToAutomationRootNode_[treeID];
   var result = new AutomationRootNode(treeID);
   AutomationRootNodeImpl.idToAutomationRootNode_[treeID] = result;
   return result;
-}
+});
 
-AutomationRootNodeImpl.destroy = function(treeID) {
+utils.defineProperty(AutomationRootNodeImpl, 'destroy', function(treeID) {
   delete AutomationRootNodeImpl.idToAutomationRootNode_[treeID];
-}
+});
 
 AutomationRootNodeImpl.prototype = {
   __proto__: AutomationNodeImpl.prototype,
@@ -927,8 +938,7 @@
       if (nodeImpl.isRootNode)
         output += indent + 'tree id=' + nodeImpl.treeID + '\n';
       output += indent +
-          AutomationNodeImpl.prototype.toString.call(nodeImpl) +
-          '\n';
+        $Function.call(AutomationNodeImpl.prototype.toString, nodeImpl) + '\n';
       indent += '  ';
       var children = nodeImpl.children;
       for (var i = 0; i < children.length; ++i)
@@ -991,17 +1001,17 @@
   ],
 });
 
-AutomationRootNode.get = function(treeID) {
+utils.defineProperty(AutomationRootNode, 'get', function(treeID) {
   return AutomationRootNodeImpl.get(treeID);
-}
+});
 
-AutomationRootNode.getOrCreate = function(treeID) {
+utils.defineProperty(AutomationRootNode, 'getOrCreate', function(treeID) {
   return AutomationRootNodeImpl.getOrCreate(treeID);
-}
+});
 
-AutomationRootNode.destroy = function(treeID) {
+utils.defineProperty(AutomationRootNode, 'destroy', function(treeID) {
   AutomationRootNodeImpl.destroy(treeID);
-}
+});
 
 exports.$set('AutomationNode', AutomationNode);
 exports.$set('AutomationRootNode', AutomationRootNode);
diff --git a/chrome/renderer/resources/extensions/enterprise_platform_keys/key_pair.js b/chrome/renderer/resources/extensions/enterprise_platform_keys/key_pair.js
index 1cab18f84..d31ffaf5 100644
--- a/chrome/renderer/resources/extensions/enterprise_platform_keys/key_pair.js
+++ b/chrome/renderer/resources/extensions/enterprise_platform_keys/key_pair.js
@@ -17,7 +17,7 @@
  * @param {KeyUsage[]} usages The allowed key usages.
  * @constructor
  */
-var KeyPairImpl = function(publicKeySpki, algorithm, usages) {
+function KeyPairImpl(publicKeySpki, algorithm, usages) {
   this.publicKey = new Key(KeyType.public,
                            publicKeySpki,
                            algorithm,
@@ -28,7 +28,8 @@
                             algorithm,
                             intersect([KeyUsage.sign], usages),
                             false /* not extractable */);
-};
+}
+$Object.setPrototypeOf(KeyPairImpl.prototype, null);
 
 function KeyPair() {
   privates(KeyPair).constructPrivate(this, arguments);
diff --git a/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js b/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js
index c53bec3..52bca98 100644
--- a/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js
+++ b/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js
@@ -16,7 +16,7 @@
 // This error is thrown by the internal and public API's token functions and
 // must be rethrown by this custom binding. Keep this in sync with the C++ part
 // of this API.
-var errorInvalidToken = "The token is not valid.";
+var errorInvalidToken = 'The token is not valid.';
 
 // The following errors are specified in WebCrypto.
 // TODO(pneubeck): These should be DOMExceptions.
@@ -76,12 +76,12 @@
  * @param {string} tokenId The id of the backing Token.
  * @constructor
  */
-var EnterpriseSubtleCryptoImpl = function(tokenId) {
-  SubtleCryptoImpl.call(this, tokenId);
-};
+function EnterpriseSubtleCryptoImpl(tokenId) {
+  $Function.call(SubtleCryptoImpl, this, tokenId);
+}
 
 EnterpriseSubtleCryptoImpl.prototype =
-    Object.create(SubtleCryptoImpl.prototype);
+    $Object.create(SubtleCryptoImpl.prototype);
 
 EnterpriseSubtleCryptoImpl.prototype.generateKey =
     function(algorithm, extractable, keyUsages) {
diff --git a/chrome/renderer/resources/extensions/enterprise_platform_keys/token.js b/chrome/renderer/resources/extensions/enterprise_platform_keys/token.js
index 266db59..5253808b 100644
--- a/chrome/renderer/resources/extensions/enterprise_platform_keys/token.js
+++ b/chrome/renderer/resources/extensions/enterprise_platform_keys/token.js
@@ -10,10 +10,11 @@
  * @param {string} id The id of the new Token.
  * @constructor
  */
-var TokenImpl = function(id) {
+function TokenImpl(id) {
   this.id = id;
   this.subtleCrypto = new SubtleCrypto(id);
-};
+}
+$Object.setPrototypeOf(TokenImpl.prototype, null);
 
 function Token() {
   privates(Token).constructPrivate(this, arguments);
diff --git a/chrome/renderer/resources/extensions/platform_keys/key.js b/chrome/renderer/resources/extensions/platform_keys/key.js
index bea1fc40..bde4c856 100644
--- a/chrome/renderer/resources/extensions/platform_keys/key.js
+++ b/chrome/renderer/resources/extensions/platform_keys/key.js
@@ -9,6 +9,7 @@
  * @enum {string}
  */
 var KeyType = {
+  __proto__: null,
   public: 'public',
   private: 'private'
 };
@@ -18,6 +19,7 @@
  * @enum {string}
  */
 var KeyUsage = {
+  __proto__: null,
   sign: 'sign',
   verify: 'verify'
 };
@@ -32,22 +34,25 @@
  * @param {boolean} extractable Whether the key is extractable.
  * @constructor
  */
-var KeyImpl = function(type, publicKeySpki, algorithm, usages, extractable) {
+function KeyImpl(type, publicKeySpki, algorithm, usages, extractable) {
   this.type = type;
   this.spki = publicKeySpki;
   this.algorithm = algorithm;
   this.usages = usages;
   this.extractable = extractable;
-};
+}
+$Object.setPrototypeOf(KeyImpl.prototype, null);
 
-var KeyBase = function() {};
-
-Object.defineProperty(KeyBase.prototype, 'algorithm', {
-  enumerable: true,
-  get: function() {
+/**
+ * The public base class of Key.
+ */
+function KeyBase() {}
+KeyBase.prototype = {
+  constructor: KeyBase,
+  get algorithm() {
     return utils.deepCopy(privates(this).impl.algorithm);
-  }
-});
+  },
+};
 
 function Key() {
   privates(Key).constructPrivate(this, arguments);
diff --git a/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js b/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js
index 3904003..0fdfca6 100644
--- a/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js
+++ b/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js
@@ -14,7 +14,7 @@
 // This error is thrown by the internal and public API's token functions and
 // must be rethrown by this custom binding. Keep this in sync with the C++ part
 // of this API.
-var errorInvalidToken = "The token is not valid.";
+var errorInvalidToken = 'The token is not valid.';
 
 // The following errors are specified in WebCrypto.
 // TODO(pneubeck): These should be DOMExceptions.
@@ -55,9 +55,10 @@
  * @param {string} tokenId The id of the backing Token.
  * @constructor
  */
-var SubtleCryptoImpl = function(tokenId) {
+function SubtleCryptoImpl(tokenId) {
   this.tokenId = tokenId;
-};
+}
+$Object.setPrototypeOf(SubtleCryptoImpl.prototype, null);
 
 SubtleCryptoImpl.prototype.sign = function(algorithm, key, dataView) {
   var subtleCrypto = this;
diff --git a/chrome/renderer/resources/extensions/web_view/chrome_web_view.js b/chrome/renderer/resources/extensions/web_view/chrome_web_view.js
index abad162..bbea26b2 100644
--- a/chrome/renderer/resources/extensions/web_view/chrome_web_view.js
+++ b/chrome/renderer/resources/extensions/web_view/chrome_web_view.js
@@ -37,11 +37,12 @@
                                     opt_argSchemas,
                                     opt_eventOptions) {
   var subEventName = GetUniqueSubEventName(opt_eventName);
-  EventBindings.Event.call(this,
-                           subEventName,
-                           opt_argSchemas,
-                           opt_eventOptions,
-                           webViewInstanceId);
+  $Function.call(EventBindings.Event,
+                 this,
+                 subEventName,
+                 opt_argSchemas,
+                 opt_eventOptions,
+                 webViewInstanceId);
 
   var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
   if (!view) {
@@ -52,19 +53,21 @@
     $Function.apply(this.dispatch, this, $Array.slice(arguments));
   }.bind(this), {instanceId: webViewInstanceId});
 }
+$Object.setPrototypeOf(ContextMenusOnClickedEvent.prototype,
+                       EventBindings.Event.prototype);
 
-ContextMenusOnClickedEvent.prototype.__proto__ = EventBindings.Event.prototype;
-
+// This event is exposed as <webview>.contextMenus.onShow.
 function ContextMenusOnContextMenuEvent(webViewInstanceId,
                                         opt_eventName,
                                         opt_argSchemas,
                                         opt_eventOptions) {
   var subEventName = GetUniqueSubEventName(opt_eventName);
-  EventBindings.Event.call(this,
-                           subEventName,
-                           opt_argSchemas,
-                           opt_eventOptions,
-                           webViewInstanceId);
+  $Function.call(EventBindings.Event,
+                 this,
+                 subEventName,
+                 opt_argSchemas,
+                 opt_eventOptions,
+                 webViewInstanceId);
 
   var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
   if (!view) {
@@ -91,8 +94,8 @@
   }.bind(this), {instanceId: webViewInstanceId});
 }
 
-ContextMenusOnContextMenuEvent.prototype.__proto__ =
-    EventBindings.Event.prototype;
+$Object.setPrototypeOf(ContextMenusOnContextMenuEvent.prototype,
+                       EventBindings.Event.prototype);
 
 // -----------------------------------------------------------------------------
 // WebViewContextMenusImpl object.
@@ -101,6 +104,7 @@
 function WebViewContextMenusImpl(viewInstanceId) {
   this.viewInstanceId_ = viewInstanceId;
 }
+$Object.setPrototypeOf(WebViewContextMenusImpl.prototype, null);
 
 WebViewContextMenusImpl.prototype.create = function() {
   var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
@@ -188,8 +192,6 @@
   }.bind(this);
 
   // Expose <webview>.contextMenus object.
-  // TODO(lazyboy): Add documentation for contextMenus:
-  // http://crbug.com/470979.
   $Object.defineProperty(
       this.element,
       'contextMenus',
diff --git a/chrome/test/base/view_event_test_platform_part_default.cc b/chrome/test/base/view_event_test_platform_part_default.cc
index 2914bb60..7505009 100644
--- a/chrome/test/base/view_event_test_platform_part_default.cc
+++ b/chrome/test/base/view_event_test_platform_part_default.cc
@@ -7,7 +7,7 @@
 #include "base/macros.h"
 #include "chrome/test/base/view_event_test_platform_part.h"
 #include "ui/aura/env.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/views/widget/desktop_aura/desktop_screen.h"
 
 namespace {
@@ -19,7 +19,7 @@
       ui::ContextFactory* context_factory) {
 #if defined(USE_AURA)
     screen_.reset(views::CreateDesktopScreen());
-    gfx::Screen::SetScreenInstance(screen_.get());
+    display::Screen::SetScreenInstance(screen_.get());
     env_ = aura::Env::CreateInstance();
     env_->set_context_factory(context_factory);
 #endif
@@ -28,7 +28,7 @@
   ~ViewEventTestPlatformPartDefault() override {
 #if defined(USE_AURA)
     env_.reset();
-    gfx::Screen::SetScreenInstance(nullptr);
+    display::Screen::SetScreenInstance(nullptr);
 #endif
   }
 
@@ -36,7 +36,7 @@
   gfx::NativeWindow GetContext() override { return NULL; }
 
  private:
-  std::unique_ptr<gfx::Screen> screen_;
+  std::unique_ptr<display::Screen> screen_;
   std::unique_ptr<aura::Env> env_;
 
   DISALLOW_COPY_AND_ASSIGN(ViewEventTestPlatformPartDefault);
diff --git a/chrome/test/data/save_page/1.css b/chrome/test/data/save_page/1.css
index 750524d..d6c5498 100644
--- a/chrome/test/data/save_page/1.css
+++ b/chrome/test/data/save_page/1.css
@@ -1,3 +1,13 @@
+/**
+ * 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.
+ */
 body {
   font-size: 20px;
-}
\ No newline at end of file
+}
+
+.icon:before {
+  content: "\e003 \e004 b";
+}
+
diff --git a/chrome/test/media_router/media_router_integration_browsertest.cc b/chrome/test/media_router/media_router_integration_browsertest.cc
index 0ba435e..aa99175f 100644
--- a/chrome/test/media_router/media_router_integration_browsertest.cc
+++ b/chrome/test/media_router/media_router_integration_browsertest.cc
@@ -502,6 +502,10 @@
   ExecuteJavaScriptAPI(web_contents, kCheckSessionScript);
   std::string session_id(GetStartedConnectionId(web_contents));
 
+  // Wait a few seconds for MediaRouter to receive updates containing the
+  // created route.
+  Wait(base::TimeDelta::FromSeconds(3));
+
   OpenTestPageInNewTab(FILE_PATH_LITERAL("basic_test.html"));
   content::WebContents* new_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -532,6 +536,10 @@
   ExecuteJavaScriptAPI(web_contents, kCheckSessionScript);
   std::string session_id(GetStartedConnectionId(web_contents));
 
+  // Wait a few seconds for MediaRouter to receive updates containing the
+  // created route.
+  Wait(base::TimeDelta::FromSeconds(3));
+
   SetTestData(FILE_PATH_LITERAL("fail_reconnect_session.json"));
   OpenTestPage(FILE_PATH_LITERAL("fail_reconnect_session.html"));
   content::WebContents* new_web_contents =
diff --git a/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py b/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py
index c44a843..b341188 100644
--- a/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py
+++ b/chrome/test/media_router/telemetry/benchmarks/media_router_cpu_memory_metric.py
@@ -43,7 +43,10 @@
           continue
         # Get rid of 0 values
         non_zero_results = [result for result in process_results if result]
-        avg_result = round(sum(non_zero_results)/len(non_zero_results), 4)
+        if non_zero_results:
+          avg_result = round(sum(non_zero_results)/len(non_zero_results), 4)
+        else:
+          avg_result = 0
         if metric == 'privateMemory':
           avg_result = round(avg_result/(1024 * 1024), 2)
         results.AddValue(scalar.ScalarValue(
diff --git a/chrome/test/media_router/telemetry/benchmarks/pagesets/bear-vp9-opus.webm b/chrome/test/media_router/telemetry/benchmarks/pagesets/bear-vp9-opus.webm
new file mode 100644
index 0000000..80355cfa5
--- /dev/null
+++ b/chrome/test/media_router/telemetry/benchmarks/pagesets/bear-vp9-opus.webm
Binary files differ
diff --git a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py
index 538d99b..5c5223d 100644
--- a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py
+++ b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_page.py
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import logging
 import os
 import time
 import utils
@@ -39,6 +40,49 @@
       # code which closes the dialog, it is expected.
       pass
 
+  def CloseExistingRoute(self, action_runner, sink_name):
+    """Closes the existing route if it exists, otherwise does nothing."""
+
+    action_runner.TapElement(selector='#start_session_button')
+    action_runner.Wait(5)
+    for tab in action_runner.tab.browser.tabs:
+      if tab.url == 'chrome://media-router/':
+        if self.CheckIfExistingRoute(tab, sink_name):
+          self.ChooseSink(tab, sink_name)
+          tab.ExecuteJavaScript(
+              "window.document.getElementById('media-router-container')."
+              "shadowRoot.getElementById('route-details').shadowRoot."
+              "getElementById('close-route-button').click();")
+    self.CloseDialog(tab)
+    # Wait for 5s to make sure the route is closed.
+    action_runner.Wait(5)
+
+  def CheckIfExistingRoute(self, tab, sink_name):
+    """"Checks if there is existing route for the specific sink."""
+
+    tab.ExecuteJavaScript(
+        "var sinks = window.document.getElementById('media-router-container')."
+        "  allSinks;"
+        "var sink_id = null;"
+        "for (var i=0; i<sinks.length; i++) {"
+        "  if (sinks[i].name == '%s') {"
+        "    console.info('sink id: ' + sinks[i].id); "
+        "    sink_id = sinks[i].id;"
+        "    break;"
+        "  }"
+        "}"
+        "var routes = window.document.getElementById('media-router-container')."
+        "  routeList;"
+        "for (var i=0; i<routes.length; i++) {"
+        "  if (!!sink_id && routes[i].sinkId == sink_id) {"
+        "    window.__telemetry_route_id = routes[i].id;"
+        "    break;"
+        "  }"
+        "}" % sink_name)
+    route = tab.EvaluateJavaScript('!!window.__telemetry_route_id')
+    logging.info('Is there existing route? ' + str(route))
+    return route
+
   def ExecuteAsyncJavaScript(self, action_runner, script, verify_func,
                              error_message, timeout=5):
     """Executes async javascript function and waits until it finishes."""
diff --git a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py
index a7203ba..8c655563 100644
--- a/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py
+++ b/chrome/test/media_router/telemetry/benchmarks/pagesets/media_router_perf_pages.py
@@ -10,6 +10,7 @@
 from telemetry.core import exceptions
 from telemetry.page import shared_page_state
 
+SESSION_TIME = 300  # 5 minutes
 
 class SharedState(shared_page_state.SharedPageState):
   """Shared state that restarts the browser for every single story."""
@@ -59,7 +60,7 @@
     action_runner.Wait(5)
     with action_runner.CreateInteraction('Idle'):
       action_runner.ExecuteJavaScript('collectPerfData();')
-      action_runner.Wait(300)
+      action_runner.Wait(SESSION_TIME)
 
 
 class CastFlingingPage(media_router_page.CastPage):
@@ -72,13 +73,17 @@
         shared_page_state_class=SharedState)
 
   def RunPageInteractions(self, action_runner):
-     # Wait for 5s after Chrome is opened in order to get consistent results.
+    sink_name = self._GetDeviceName()
+    # Wait for 5s after Chrome is opened in order to get consistent results.
     action_runner.Wait(5)
     with action_runner.CreateInteraction('flinging'):
+
       self._WaitForResult(
           action_runner,
           lambda: action_runner.EvaluateJavaScript('initialized'),
-          'Failed to initialize')
+          'Failed to initialize',
+          timeout=30)
+      self.CloseExistingRoute(action_runner, sink_name)
 
       # Start session
       action_runner.TapElement(selector='#start_session_button')
@@ -92,7 +97,7 @@
       for tab in action_runner.tab.browser.tabs:
         # Choose sink
         if tab.url == 'chrome://media-router/':
-          self.ChooseSink(tab, self._GetDeviceName())
+          self.ChooseSink(tab, sink_name)
 
       self._WaitForResult(
         action_runner,
@@ -110,7 +115,7 @@
 
       action_runner.Wait(5)
       action_runner.ExecuteJavaScript('collectPerfData();')
-      action_runner.Wait(300)
+      action_runner.Wait(SESSION_TIME)
       # Stop session
       self.ExecuteAsyncJavaScript(
           action_runner,
@@ -119,6 +124,49 @@
           'Failed to stop session')
 
 
+class CastMirroringPage(media_router_page.CastPage):
+  """Cast page to mirror a tab to Chromecast device."""
+
+  def __init__(self, page_set):
+    super(CastMirroringPage, self).__init__(
+        page_set=page_set,
+        url='file://mirroring.html',
+        shared_page_state_class=SharedState)
+
+  def RunPageInteractions(self, action_runner):
+    sink_name = self._GetDeviceName()
+    # Wait for 5s after Chrome is opened in order to get consistent results.
+    action_runner.Wait(5)
+    with action_runner.CreateInteraction('mirroring'):
+      self.CloseExistingRoute(action_runner, sink_name)
+
+      # Start session
+      action_runner.TapElement(selector='#start_session_button')
+      self._WaitForResult(
+          action_runner,
+          lambda: len(action_runner.tab.browser.tabs) >= 2,
+          'MR dialog never showed up.')
+
+      # Wait for 2s to make sure the dialog is fully loaded.
+      action_runner.Wait(2)
+      for tab in action_runner.tab.browser.tabs:
+        # Choose sink
+        if tab.url == 'chrome://media-router/':
+          self.ChooseSink(tab, sink_name)
+
+      # Wait for 5s to make sure the route is created.
+      action_runner.Wait(5)
+      action_runner.TapElement(selector='#start_session_button')
+      action_runner.Wait(2)
+      for tab in action_runner.tab.browser.tabs:
+        if tab.url == 'chrome://media-router/':
+          if not self.CheckIfExistingRoute(tab, sink_name):
+            raise page.page_test.Failure('Failed to start mirroring session.')
+      action_runner.ExecuteJavaScript('collectPerfData();')
+      action_runner.Wait(SESSION_TIME)
+      self.CloseExistingRoute(action_runner, sink_name)
+
+
 class MediaRouterDialogPageSet(story.StorySet):
   """Pageset for media router dialog latency tests."""
 
@@ -136,3 +184,4 @@
         cloud_storage_bucket=story.PARTNER_BUCKET)
     self.AddStory(CastIdlePage(self))
     self.AddStory(CastFlingingPage(self))
+    self.AddStory(CastMirroringPage(self))
diff --git a/chrome/test/media_router/telemetry/benchmarks/pagesets/mirroring.html b/chrome/test/media_router/telemetry/benchmarks/pagesets/mirroring.html
new file mode 100644
index 0000000..9cf71ae
--- /dev/null
+++ b/chrome/test/media_router/telemetry/benchmarks/pagesets/mirroring.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>MR Perf Test</title>
+    <script type="text/javascript" src="cpu_memory_script.js"></script>
+    <script>
+      function startSession() {
+        var startSessionRequest = new PresentationRequest("http://google.com");
+        startSessionRequest.start();
+        console.log('start session');
+      }
+    </script>
+  </head>
+  <body>
+    <button id="start_session_button" onclick="startSession()">
+      Start session
+    </button>
+    <video id="video_player" controls autoplay loop src="bear-vp9-opus.webm">
+    </video>
+  </body>
+</html>
\ No newline at end of file
diff --git a/chrome/tools/BUILD.gn b/chrome/tools/BUILD.gn
index 12bcbf8..af932bd 100644
--- a/chrome/tools/BUILD.gn
+++ b/chrome/tools/BUILD.gn
@@ -11,5 +11,9 @@
     deps = [
       "//chrome/tools/service_discovery_sniffer",
     ]
+  } else if (is_mac) {
+    deps = [
+      "//chrome/tools/mac_helpers",
+    ]
   }
 }
diff --git a/chrome/tools/mac_helpers/BUILD.gn b/chrome/tools/mac_helpers/BUILD.gn
new file mode 100644
index 0000000..801ccda9
--- /dev/null
+++ b/chrome/tools/mac_helpers/BUILD.gn
@@ -0,0 +1,19 @@
+# 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.
+
+executable("infoplist_strings_tool") {
+  configs += [ "//build/config/compiler:wexit_time_destructors" ]
+
+  sources = [
+    "infoplist_strings_util.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//chrome:strings",
+    "//ui/base:ui_data_pack",
+  ]
+
+  libs = [ "Foundation.framework" ]
+}
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index d801a967..b47d300 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -110,6 +110,7 @@
     "//net",
     "//ui/base",
     "//ui/compositor",
+    "//ui/display",
     "//ui/gl",
   ]
 
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS
index 8e042c4..c14e3fc 100644
--- a/chromecast/browser/DEPS
+++ b/chromecast/browser/DEPS
@@ -3,7 +3,7 @@
   # embedder and can include from all other chromecast/ directories.
   "+cc/base/switches.h",
   "+chromecast",
-  "+components/cdm/browser",
+  "+components/cdm/common",
   "+components/crash",
   "+components/devtools_discovery",
   "+components/devtools_http_handler",
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index 62793e3c..e9f8252f 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -69,6 +69,7 @@
 #include "chromecast/browser/media/cast_media_client_android.h"
 #include "components/crash/content/browser/crash_dump_manager_android.h"
 #include "media/base/android/media_client_android.h"
+#include "media/base/media_switches.h"
 #include "net/android/network_change_notifier_factory_android.h"
 #else
 #include "chromecast/net/network_change_notifier_factory_cast.h"
@@ -79,7 +80,7 @@
 // header, but is exported to allow injecting the overlay-composited
 // callback.
 #include "chromecast/graphics/cast_screen.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "ui/ozone/platform/cast/overlay_manager_cast.h"  // nogncheck
 #endif
 
@@ -195,6 +196,10 @@
   // Disables Chromecast-specific WiFi-related features on ATV for now.
   { switches::kNoWifi, "" },
   { switches::kDisableGestureRequirementForMediaPlayback, ""},
+  // TODO(sanfin): Unified Media Pipeline is disabled on ATV because of extant
+  // issues with DRM and v8 that block media playback for numerous apps.
+  // Reenable when the Unified Media Pipeline is stable enough for testing.
+  { switches::kDisableUnifiedMediaPipeline, ""},
 #else
   // GPU shader disk cache disabling is largely to conserve disk space.
   { switches::kDisableGpuShaderDiskCache, "" },
@@ -368,8 +373,8 @@
   // code.  See CastContentWindow::CreateWindowTree for update when resolution
   // is available.
   cast_browser_process_->SetCastScreen(base::WrapUnique(new CastScreen));
-  DCHECK(!gfx::Screen::GetScreen());
-  gfx::Screen::SetScreenInstance(cast_browser_process_->cast_screen());
+  DCHECK(!display::Screen::GetScreen());
+  display::Screen::SetScreenInstance(cast_browser_process_->cast_screen());
 #endif
 
   content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
diff --git a/chromecast/browser/cast_content_window.cc b/chromecast/browser/cast_content_window.cc
index 0828604..3223d83 100644
--- a/chromecast/browser/cast_content_window.cc
+++ b/chromecast/browser/cast_content_window.cc
@@ -75,8 +75,8 @@
   // Aura initialization
   CastScreen* cast_screen =
       shell::CastBrowserProcess::GetInstance()->cast_screen();
-  if (!gfx::Screen::GetScreen())
-    gfx::Screen::SetScreenInstance(cast_screen);
+  if (!display::Screen::GetScreen())
+    display::Screen::SetScreenInstance(cast_screen);
   if (cast_screen->GetPrimaryDisplay().size() != initial_size)
     cast_screen->UpdateDisplaySize(initial_size);
 
diff --git a/chromecast/browser/media/BUILD.gn b/chromecast/browser/media/BUILD.gn
index ffa4baf..1789de3 100644
--- a/chromecast/browser/media/BUILD.gn
+++ b/chromecast/browser/media/BUILD.gn
@@ -49,7 +49,7 @@
   ]
 
   if (is_android) {
-    deps += [ "//components/cdm/browser" ]
+    deps += [ "//components/cdm/common" ]
   } else {
     sources += [
       "cma_message_filter_host.cc",
diff --git a/chromecast/browser/media/cast_media_client_android.h b/chromecast/browser/media/cast_media_client_android.h
index a7aaa1d..cf65f81 100644
--- a/chromecast/browser/media/cast_media_client_android.h
+++ b/chromecast/browser/media/cast_media_client_android.h
@@ -9,7 +9,7 @@
 
 #include "base/macros.h"
 #include "chromecast/media/cdm/playready_drm_delegate_android.h"
-#include "components/cdm/browser/widevine_drm_delegate_android.h"
+#include "components/cdm/common/widevine_drm_delegate_android.h"
 #include "media/base/android/media_client_android.h"
 
 namespace chromecast {
diff --git a/chromecast/graphics/BUILD.gn b/chromecast/graphics/BUILD.gn
index f48251d2..64a3104a 100644
--- a/chromecast/graphics/BUILD.gn
+++ b/chromecast/graphics/BUILD.gn
@@ -15,6 +15,7 @@
     deps = [
       "//chromecast/public",
       "//ui/aura",
+      "//ui/display",
       "//ui/gfx",
       "//ui/gfx/geometry",
     ]
diff --git a/chromecast/graphics/cast_screen.cc b/chromecast/graphics/cast_screen.cc
index 2017dc9a..db4079fa 100644
--- a/chromecast/graphics/cast_screen.cc
+++ b/chromecast/graphics/cast_screen.cc
@@ -7,10 +7,10 @@
 #include <stdint.h>
 
 #include "ui/aura/env.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/screen.h"
 
 namespace chromecast {
 
@@ -61,32 +61,32 @@
   return 1;
 }
 
-std::vector<gfx::Display> CastScreen::GetAllDisplays() const {
-  return std::vector<gfx::Display>(1, display_);
+std::vector<display::Display> CastScreen::GetAllDisplays() const {
+  return std::vector<display::Display>(1, display_);
 }
 
-gfx::Display CastScreen::GetDisplayNearestWindow(
+display::Display CastScreen::GetDisplayNearestWindow(
     gfx::NativeWindow window) const {
   return display_;
 }
 
-gfx::Display CastScreen::GetDisplayNearestPoint(const gfx::Point& point) const {
+display::Display CastScreen::GetDisplayNearestPoint(
+    const gfx::Point& point) const {
   return display_;
 }
 
-gfx::Display CastScreen::GetDisplayMatching(const gfx::Rect& match_rect) const {
+display::Display CastScreen::GetDisplayMatching(
+    const gfx::Rect& match_rect) const {
   return display_;
 }
 
-gfx::Display CastScreen::GetPrimaryDisplay() const {
+display::Display CastScreen::GetPrimaryDisplay() const {
   return display_;
 }
 
-void CastScreen::AddObserver(gfx::DisplayObserver* observer) {
-}
+void CastScreen::AddObserver(display::DisplayObserver* observer) {}
 
-void CastScreen::RemoveObserver(gfx::DisplayObserver* observer) {
-}
+void CastScreen::RemoveObserver(display::DisplayObserver* observer) {}
 
 CastScreen::CastScreen() : display_(kDisplayId) {
   display_.SetScaleAndBounds(1.0f,
diff --git a/chromecast/graphics/cast_screen.h b/chromecast/graphics/cast_screen.h
index ba665be..43ca0cc 100644
--- a/chromecast/graphics/cast_screen.h
+++ b/chromecast/graphics/cast_screen.h
@@ -8,20 +8,20 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "chromecast/public/graphics_types.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
 
 namespace chromecast {
 namespace shell {
 class CastBrowserMainParts;
 }  // namespace shell
 
-// CastScreen is Chromecast's own minimal implementation of gfx::Screen.
+// CastScreen is Chromecast's own minimal implementation of display::Screen.
 // Right now, it almost exactly duplicates the behavior of aura's TestScreen
 // class for necessary methods. The instantiation of CastScreen occurs in
 // CastBrowserMainParts, where its ownership is assigned to CastBrowserProcess.
 // To then subsequently access CastScreen, see CastBrowerProcess.
-class CastScreen : public gfx::Screen {
+class CastScreen : public display::Screen {
  public:
   ~CastScreen() override;
 
@@ -31,23 +31,25 @@
   // Updates the primary display size.
   void UpdateDisplaySize(const gfx::Size& size);
 
-  // gfx::Screen overrides:
+  // display::Screen overrides:
   gfx::Point GetCursorScreenPoint() override;
   gfx::NativeWindow GetWindowUnderCursor() override;
   gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
   int GetNumDisplays() const override;
-  std::vector<gfx::Display> GetAllDisplays() const override;
-  gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
-  gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override;
-  gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
-  gfx::Display GetPrimaryDisplay() const override;
-  void AddObserver(gfx::DisplayObserver* observer) override;
-  void RemoveObserver(gfx::DisplayObserver* observer) override;
+  std::vector<display::Display> GetAllDisplays() const override;
+  display::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
+  display::Display GetDisplayNearestPoint(
+      const gfx::Point& point) const override;
+  display::Display GetDisplayMatching(
+      const gfx::Rect& match_rect) const override;
+  display::Display GetPrimaryDisplay() const override;
+  void AddObserver(display::DisplayObserver* observer) override;
+  void RemoveObserver(display::DisplayObserver* observer) override;
 
  private:
   CastScreen();
 
-  gfx::Display display_;
+  display::Display display_;
   DisplayResizeCallback display_resize_cb_;
 
   friend class shell::CastBrowserMainParts;
diff --git a/chromecast/media/BUILD.gn b/chromecast/media/BUILD.gn
index e0d739d..c79adce 100644
--- a/chromecast/media/BUILD.gn
+++ b/chromecast/media/BUILD.gn
@@ -59,6 +59,7 @@
     "//media/base:test_support",
     "//testing/gmock",
     "//testing/gtest",
+    "//ui/display",
     "//ui/gfx/geometry",
   ]
 
diff --git a/chromecast/media/base/video_plane_controller.h b/chromecast/media/base/video_plane_controller.h
index 852cdfba..04e9b943 100644
--- a/chromecast/media/base/video_plane_controller.h
+++ b/chromecast/media/base/video_plane_controller.h
@@ -48,8 +48,8 @@
 
   // Sets graphics hardware plane resolution, and clears any cached video plane
   // geometry parameters. This must be called at least once when the hardware
-  // graphics plane resolution (same resolution as gfx::Screen) is known, then
-  // later when it changes. If there is no change to the graphics plane
+  // graphics plane resolution (same resolution as display::Screen) is known,
+  // then later when it changes. If there is no change to the graphics plane
   // resolution from the last call to this method, it is a no-op.
   void SetGraphicsPlaneResolution(const Size& resolution);
 
diff --git a/chromecast/net/connectivity_checker_impl.cc b/chromecast/net/connectivity_checker_impl.cc
index 80ee89d6..392ca8a 100644
--- a/chromecast/net/connectivity_checker_impl.cc
+++ b/chromecast/net/connectivity_checker_impl.cc
@@ -35,7 +35,7 @@
 
 // Default url for connectivity checking.
 const char kDefaultConnectivityCheckUrl[] =
-    "https://clients3.google.com/generate_204";
+    "https://connectivitycheck.gstatic.com/generate_204";
 
 // Delay notification of network change events to smooth out rapid flipping.
 // Histogram "Cast.Network.Down.Duration.In.Seconds" shows 40% of network
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index d02ffc33..3fb375a 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -101,8 +101,14 @@
 }
 
 void CastContentRendererClient::AddKeySystems(
-    std::vector< ::media::KeySystemInfo>* key_systems) {
-  AddChromecastKeySystems(key_systems);
+    std::vector<::media::KeySystemInfo>* key_systems_info) {
+  AddChromecastKeySystemsInfo(key_systems_info);
+}
+
+void CastContentRendererClient::AddSupportedKeySystems(
+    std::vector<std::unique_ptr<::media::KeySystemProperties>>*
+        key_systems_properties) {
+  AddChromecastKeySystems(key_systems_properties);
 }
 
 #if !defined(OS_ANDROID)
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index cb04ad6a..245958e 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -35,7 +35,10 @@
   void RenderThreadStarted() override;
   void RenderViewCreated(content::RenderView* render_view) override;
   void AddKeySystems(
-      std::vector< ::media::KeySystemInfo>* key_systems) override;
+      std::vector<::media::KeySystemInfo>* key_systems_info) override;
+  void AddSupportedKeySystems(
+      std::vector<std::unique_ptr<::media::KeySystemProperties>>*
+          key_systems_properties) override;
 #if !defined(OS_ANDROID)
   std::unique_ptr<::media::RendererFactory> CreateMediaRendererFactory(
       content::RenderFrame* render_frame,
diff --git a/chromecast/renderer/key_systems_cast.cc b/chromecast/renderer/key_systems_cast.cc
index c1257fd..4acfd110 100644
--- a/chromecast/renderer/key_systems_cast.cc
+++ b/chromecast/renderer/key_systems_cast.cc
@@ -10,7 +10,7 @@
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "chromecast/media/base/key_systems_common.h"
-#include "components/cdm/renderer/widevine_key_systems.h"
+#include "components/cdm/renderer/widevine_key_system_properties.h"
 #include "media/base/eme_constants.h"
 
 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
@@ -21,7 +21,9 @@
 
 namespace chromecast {
 namespace shell {
+namespace {
 
+#if defined(PLAYREADY_CDM_AVAILABLE)
 void AddKeySystemWithCodecs(
     const std::string& key_system_name,
     std::vector<::media::KeySystemInfo>* key_systems_info) {
@@ -30,44 +32,47 @@
   info.supported_init_data_types = ::media::kInitDataTypeMaskCenc;
   info.supported_codecs =
       ::media::EME_CODEC_MP4_AAC | ::media::EME_CODEC_MP4_AVC1;
-  info.max_audio_robustness = ::media::EmeRobustness::EMPTY;
-  info.max_video_robustness = ::media::EmeRobustness::EMPTY;
+  info.max_audio_robustness = EmeRobustness::EMPTY;
+  info.max_video_robustness = EmeRobustness::EMPTY;
 #if defined(OS_ANDROID)
-  info.persistent_license_support =
-      ::media::EmeSessionTypeSupport::NOT_SUPPORTED;
+  info.persistent_license_support = EmeSessionTypeSupport::NOT_SUPPORTED;
 #else
-  info.persistent_license_support =
-      ::media::EmeSessionTypeSupport::SUPPORTED;
+  info.persistent_license_support = EmeSessionTypeSupport::SUPPORTED;
 #endif
   info.persistent_release_message_support =
-      ::media::EmeSessionTypeSupport::NOT_SUPPORTED;
-  info.persistent_state_support = ::media::EmeFeatureSupport::ALWAYS_ENABLED;
-  info.distinctive_identifier_support =
-      ::media::EmeFeatureSupport::ALWAYS_ENABLED;
+      EmeSessionTypeSupport::NOT_SUPPORTED;
+  info.persistent_state_support = EmeFeatureSupport::ALWAYS_ENABLED;
+  info.distinctive_identifier_support = EmeFeatureSupport::ALWAYS_ENABLED;
   key_systems_info->push_back(info);
 }
+#endif  // defined(PLAYREADY_CDM_AVAILABLE)
+
+}  // namespace
 
 void AddChromecastKeySystems(
-    std::vector<::media::KeySystemInfo>* key_systems_info) {
+    std::vector<std::unique_ptr<::media::KeySystemProperties>>*
+        key_systems_properties) {
 #if defined(WIDEVINE_CDM_AVAILABLE)
   ::media::SupportedCodecs codecs =
       ::media::EME_CODEC_MP4_AAC | ::media::EME_CODEC_MP4_AVC1 |
       ::media::EME_CODEC_WEBM_VP8 | ::media::EME_CODEC_WEBM_VP9;
-  cdm::AddWidevineWithCodecs(
-      codecs,                                // Regular codecs.
+  key_systems_properties->emplace_back(new cdm::WidevineKeySystemProperties(
+      codecs,  // Regular codecs.
 #if defined(OS_ANDROID)
-      codecs,                                // Hardware-secure codecs.
-#endif  // defined(OS_ANDROID)
+      codecs,  // Hardware-secure codecs.
+#endif
       EmeRobustness::HW_SECURE_ALL,          // Max audio robustness.
       EmeRobustness::HW_SECURE_ALL,          // Max video robustness.
       EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-license.
       EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-release-message.
       // Note: On Chromecast, all CDMs may have persistent state.
-      EmeFeatureSupport::ALWAYS_ENABLED,     // Persistent state.
-      EmeFeatureSupport::ALWAYS_ENABLED,     // Distinctive identifier.
-      key_systems_info);
+      EmeFeatureSupport::ALWAYS_ENABLED,    // Persistent state.
+      EmeFeatureSupport::ALWAYS_ENABLED));  // Distinctive identifier.
 #endif  // defined(WIDEVINE_CDM_AVAILABLE)
+}
 
+void AddChromecastKeySystemsInfo(
+    std::vector<::media::KeySystemInfo>* key_systems_info) {
 #if defined(PLAYREADY_CDM_AVAILABLE)
   AddKeySystemWithCodecs(media::kChromecastPlayreadyKeySystem,
                          key_systems_info);
diff --git a/chromecast/renderer/key_systems_cast.h b/chromecast/renderer/key_systems_cast.h
index d59993f..158518f8 100644
--- a/chromecast/renderer/key_systems_cast.h
+++ b/chromecast/renderer/key_systems_cast.h
@@ -5,21 +5,20 @@
 #ifndef CHROMECAST_RENDERER_KEY_SYSTEMS_CAST_H_
 #define CHROMECAST_RENDERER_KEY_SYSTEMS_CAST_H_
 
+#include <memory>
 #include <vector>
 
 #include "media/base/key_system_info.h"
+#include "media/base/key_system_properties.h"
 
 namespace chromecast {
 namespace shell {
 
-// Adds a single key system by name.
-// TODO(gunsch): modify this API to accept specifying different supported
-// features, and/or APIs per key system type.
-void AddKeySystemWithCodecs(
-    const std::string& key_system_name,
-    std::vector<::media::KeySystemInfo>* concrete_key_systems);
-
 void AddChromecastKeySystems(
+    std::vector<std::unique_ptr<::media::KeySystemProperties>>*
+        key_systems_properties);
+
+void AddChromecastKeySystemsInfo(
     std::vector<::media::KeySystemInfo>* key_systems_info);
 
 }  // namespace shell
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 276a6576..13112ff 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -93,8 +93,6 @@
     "dbus/services/service_provider_test_helper.h",
     "disks/mock_disk_mount_manager.cc",
     "disks/mock_disk_mount_manager.h",
-    "geolocation/simple_geolocation_request_test_monitor.cc",
-    "geolocation/simple_geolocation_request_test_monitor.h",
     "login/auth/fake_extended_authenticator.cc",
     "login/auth/fake_extended_authenticator.h",
     "login/auth/mock_auth_attempt_state_resolver.cc",
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index b0eeab0..dde451e8f 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -248,6 +248,8 @@
       'geolocation/simple_geolocation_provider.h',
       'geolocation/simple_geolocation_request.cc',
       'geolocation/simple_geolocation_request.h',
+      'geolocation/simple_geolocation_request_test_monitor.cc',
+      'geolocation/simple_geolocation_request_test_monitor.h',
       'hugepage_text/hugepage_text.cc',
       'hugepage_text/hugepage_text.h',
       'login/auth/auth_attempt_state.cc',
@@ -587,8 +589,6 @@
         'dbus/services/service_provider_test_helper.h',
         'disks/mock_disk_mount_manager.cc',
         'disks/mock_disk_mount_manager.h',
-        'geolocation/simple_geolocation_request_test_monitor.cc',
-        'geolocation/simple_geolocation_request_test_monitor.h',
         'login/auth/fake_extended_authenticator.cc',
         'login/auth/fake_extended_authenticator.h',
         'login/auth/mock_auth_attempt_state_resolver.cc',
diff --git a/chromeos/geolocation/simple_geolocation_request_test_monitor.h b/chromeos/geolocation/simple_geolocation_request_test_monitor.h
index 2213db2..b50b735d 100644
--- a/chromeos/geolocation/simple_geolocation_request_test_monitor.h
+++ b/chromeos/geolocation/simple_geolocation_request_test_monitor.h
@@ -6,6 +6,7 @@
 #define CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_TEST_MONITOR_H_
 
 #include "base/macros.h"
+#include "chromeos/chromeos_export.h"
 
 namespace chromeos {
 
@@ -13,8 +14,9 @@
 
 // This is global hook, that allows to monitor SimpleGeolocationRequest
 // in tests.
-
-class SimpleGeolocationRequestTestMonitor {
+//
+// Note: we need CHROMEOS_EXPORT for tests.
+class CHROMEOS_EXPORT SimpleGeolocationRequestTestMonitor {
  public:
   SimpleGeolocationRequestTestMonitor();
 
diff --git a/components/OWNERS b/components/OWNERS
index 66fc1e5..ca4e8e7 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -83,6 +83,8 @@
 
 per-file history.gypi=file://components/history/OWNERS
 
+per-file image_fetcher.gypi=file://components/image_fetcher/OWNERS
+
 per-file infobars.gypi=file://components/infobars/OWNERS
 
 per-file invalidation.gypi=file://components/invalidation/OWNERS
@@ -113,6 +115,8 @@
 
 per-file ntp_snippets.gypi=file://components/ntp_snippets/OWNERS
 
+per-file ntp_tiles.gypi=file://components/ntp_tiles/OWNERS
+
 per-file offline_pages.gypi=file://components/offline_pages/OWNERS
 
 per-file omnibox.gypi=file://components/omnibox/OWNERS
diff --git a/components/arc.gypi b/components/arc.gypi
index bc85836..5aa8c91 100644
--- a/components/arc.gypi
+++ b/components/arc.gypi
@@ -68,6 +68,8 @@
         'arc/net/arc_net_host_impl.h',
         'arc/power/arc_power_bridge.cc',
         'arc/power/arc_power_bridge.h',
+        'arc/window_manager/arc_window_manager_bridge.cc',
+        'arc/window_manager/arc_window_manager_bridge.h',
       ],
     },
     {
@@ -120,6 +122,7 @@
         'arc/common/process.mojom',
         'arc/common/video.mojom',
         'arc/common/video_accelerator.mojom',
+        'arc/common/window_manager.mojom',
       ],
     },
     {
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index 230fb0f..7c05adcb 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -46,6 +46,8 @@
     "net/arc_net_host_impl.h",
     "power/arc_power_bridge.cc",
     "power/arc_power_bridge.h",
+    "window_manager/arc_window_manager_bridge.cc",
+    "window_manager/arc_window_manager_bridge.h",
   ]
 
   deps = [
@@ -97,6 +99,7 @@
     "common/process.mojom",
     "common/video.mojom",
     "common/video_accelerator.mojom",
+    "common/window_manager.mojom",
   ]
 }
 
diff --git a/components/arc/arc_bridge_service.cc b/components/arc/arc_bridge_service.cc
index 4e7ac24..975ba46 100644
--- a/components/arc/arc_bridge_service.cc
+++ b/components/arc/arc_bridge_service.cc
@@ -86,6 +86,8 @@
     observer->OnProcessInstanceReady();
   if (video_instance())
     observer->OnVideoInstanceReady();
+  if (window_manager_instance())
+    observer->OnWindowManagerInstanceReady();
 }
 
 void ArcBridgeService::RemoveObserver(Observer* observer) {
@@ -466,6 +468,32 @@
   FOR_EACH_OBSERVER(Observer, observer_list(), OnVideoInstanceClosed());
 }
 
+void ArcBridgeService::OnWindowManagerInstanceReady(
+    mojom::WindowManagerInstancePtr window_manager_ptr) {
+  DCHECK(CalledOnValidThread());
+  temporary_window_manager_ptr_ = std::move(window_manager_ptr);
+  temporary_window_manager_ptr_.QueryVersion(base::Bind(
+      &ArcBridgeService::OnWindowManagerVersionReady,
+      weak_factory_.GetWeakPtr()));
+}
+
+void ArcBridgeService::OnWindowManagerVersionReady(int32_t version) {
+  DCHECK(CalledOnValidThread());
+  window_manager_ptr_ = std::move(temporary_window_manager_ptr_);
+  window_manager_ptr_.set_connection_error_handler(base::Bind(
+      &ArcBridgeService::CloseWindowManagerChannel,
+      weak_factory_.GetWeakPtr()));
+  FOR_EACH_OBSERVER(Observer, observer_list(), OnWindowManagerInstanceReady());
+}
+
+void ArcBridgeService::CloseWindowManagerChannel() {
+  if (!window_manager_ptr_)
+    return;
+
+  window_manager_ptr_.reset();
+  FOR_EACH_OBSERVER(Observer, observer_list(), OnWindowManagerInstanceClosed());
+}
+
 void ArcBridgeService::SetState(State state) {
   DCHECK(CalledOnValidThread());
   // DCHECK on enum classes not supported.
@@ -503,6 +531,7 @@
   ClosePowerChannel();
   CloseProcessChannel();
   CloseVideoChannel();
+  CloseWindowManagerChannel();
 }
 
 }  // namespace arc
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h
index 42f83ca..6781001 100644
--- a/components/arc/arc_bridge_service.h
+++ b/components/arc/arc_bridge_service.h
@@ -132,6 +132,10 @@
     virtual void OnVideoInstanceReady() {}
     virtual void OnVideoInstanceClosed() {}
 
+    // Called whenever the ARC window manager interface state changes.
+    virtual void OnWindowManagerInstanceReady() {}
+    virtual void OnWindowManagerInstanceClosed() {}
+
    protected:
     virtual ~Observer() {}
   };
@@ -194,6 +198,9 @@
   mojom::PowerInstance* power_instance() { return power_ptr_.get(); }
   mojom::ProcessInstance* process_instance() { return process_ptr_.get(); }
   mojom::VideoInstance* video_instance() { return video_ptr_.get(); }
+  mojom::WindowManagerInstance* window_manager_instance() {
+    return window_manager_ptr_.get();
+  }
 
   int32_t app_version() const { return app_ptr_.version(); }
   int32_t audio_version() const { return audio_ptr_.version(); }
@@ -212,6 +219,9 @@
   int32_t power_version() const { return power_ptr_.version(); }
   int32_t process_version() const { return process_ptr_.version(); }
   int32_t video_version() const { return video_ptr_.version(); }
+  int32_t window_manager_version() const {
+    return window_manager_ptr_.version();
+  }
 
   // ArcHost:
   void OnAppInstanceReady(mojom::AppInstancePtr app_ptr) override;
@@ -234,6 +244,8 @@
   void OnPowerInstanceReady(mojom::PowerInstancePtr power_ptr) override;
   void OnProcessInstanceReady(mojom::ProcessInstancePtr process_ptr) override;
   void OnVideoInstanceReady(mojom::VideoInstancePtr video_ptr) override;
+  void OnWindowManagerInstanceReady(
+      mojom::WindowManagerInstancePtr window_manager_ptr) override;
 
   // Gets the current state of the bridge service.
   State state() const { return state_; }
@@ -280,6 +292,7 @@
   void ClosePowerChannel();
   void CloseProcessChannel();
   void CloseVideoChannel();
+  void CloseWindowManagerChannel();
 
   // Callbacks for QueryVersion.
   void OnAppVersionReady(int32_t version);
@@ -297,6 +310,7 @@
   void OnPowerVersionReady(int32_t version);
   void OnProcessVersionReady(int32_t version);
   void OnVideoVersionReady(int32_t version);
+  void OnWindowManagerVersionReady(int32_t version);
 
   // Mojo interfaces.
   mojom::AppInstancePtr app_ptr_;
@@ -314,6 +328,7 @@
   mojom::PowerInstancePtr power_ptr_;
   mojom::ProcessInstancePtr process_ptr_;
   mojom::VideoInstancePtr video_ptr_;
+  mojom::WindowManagerInstancePtr window_manager_ptr_;
 
   // Temporary Mojo interfaces.  After a Mojo interface pointer has been
   // received from the other endpoint, we still need to asynchronously query
@@ -336,6 +351,7 @@
   mojom::PowerInstancePtr temporary_power_ptr_;
   mojom::ProcessInstancePtr temporary_process_ptr_;
   mojom::VideoInstancePtr temporary_video_ptr_;
+  mojom::WindowManagerInstancePtr temporary_window_manager_ptr_;
 
   base::ObserverList<Observer> observer_list_;
 
diff --git a/components/arc/arc_service_manager.cc b/components/arc/arc_service_manager.cc
index 77cb39f..34bf4cd 100644
--- a/components/arc/arc_service_manager.cc
+++ b/components/arc/arc_service_manager.cc
@@ -19,6 +19,7 @@
 #include "components/arc/metrics/arc_metrics_service.h"
 #include "components/arc/net/arc_net_host_impl.h"
 #include "components/arc/power/arc_power_bridge.h"
+#include "components/arc/window_manager/arc_window_manager_bridge.h"
 #include "ui/arc/notification/arc_notification_manager.h"
 
 namespace arc {
@@ -92,6 +93,17 @@
       new ArcNotificationManager(arc_bridge_service(), account_id)));
 }
 
+void ArcServiceManager::OnAshStarted() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  // We might come here multiple times. As such we should only do this once.
+  if (on_ash_started_called_)
+    return;
+
+  on_ash_started_called_ = true;
+  AddService(
+      base::WrapUnique(new ArcWindowManagerBridge(arc_bridge_service())));
+}
+
 void ArcServiceManager::Shutdown() {
   services_.clear();
 }
diff --git a/components/arc/arc_service_manager.h b/components/arc/arc_service_manager.h
index 30715e9..76d98e5 100644
--- a/components/arc/arc_service_manager.h
+++ b/components/arc/arc_service_manager.h
@@ -38,6 +38,9 @@
   // Called when the main profile is initialized after user logs in.
   void OnPrimaryUserProfilePrepared(const AccountId& account_id);
 
+  // Called once the windowing system (ash) has been started.
+  void OnAshStarted();
+
   // Called to shut down all ARC services.
   void Shutdown();
 
@@ -51,6 +54,10 @@
   std::unique_ptr<ArcBridgeService> arc_bridge_service_;
   std::vector<std::unique_ptr<ArcService>> services_;
 
+  // True once the window manager service got added, barring adding any more
+  // of those since OnAshStarted() might be called multiple times.
+  bool on_ash_started_called_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(ArcServiceManager);
 };
 
diff --git a/components/arc/common/arc_bridge.mojom b/components/arc/common/arc_bridge.mojom
index af2e1c6..b67a8a3a 100644
--- a/components/arc/common/arc_bridge.mojom
+++ b/components/arc/common/arc_bridge.mojom
@@ -19,6 +19,7 @@
 import "power.mojom";
 import "process.mojom";
 import "video.mojom";
+import "window_manager.mojom";
 
 interface ArcBridgeHost {
   // Keep the entries alphabetical. In order to do so without breaking
@@ -71,6 +72,9 @@
 
   // Notifies Chrome that the VideoInstance interface is ready.
   [MinVersion=6] OnVideoInstanceReady@107(VideoInstance instance_ptr);
+  
+  // Notifies Android of entering / exiting TouchView.
+  [MinVersion=11] OnWindowManagerInstanceReady@117(WindowManagerInstance instance_ptr);
 };
 
 interface ArcBridgeInstance {
diff --git a/components/arc/common/net.mojom b/components/arc/common/net.mojom
index ac5914b..ab727b0 100644
--- a/components/arc/common/net.mojom
+++ b/components/arc/common/net.mojom
@@ -16,16 +16,51 @@
   VISIBLE_ONLY = 1,
 };
 
-struct WifiConfiguration {
-  // These correspond to ONC properties returned by
-  // chrome.networkingPrivate.getNetworks().
-  // See components/onc/docs/onc_spec.html
-  string ssid;
+[Extensible]
+enum ConnectionStateType {
+  CONNECTED = 0,
+  CONNECTING = 1,
+  NOT_CONNECTED = 2,
+};
+
+struct VisibleNetworkDetails {
   int32 frequency;
   int32 signal_strength;
   string bssid;
-  string security;
-  [MinVersion=1] string? guid;
+};
+
+struct ConfiguredNetworkDetails {
+  string passphrase;
+  bool autoconnect;
+};
+
+union NetworkDetails {
+  VisibleNetworkDetails visible;
+  ConfiguredNetworkDetails configured;
+};
+
+struct WifiConfiguration {
+  // These correspond to ONC properties returned by
+  // chrome.networkingPrivate.getNetworks() and createNetwork().
+  // See components/onc/docs/onc_spec.html
+
+  // SSID encoded as a series of hex bytes, e.g. "61626364"
+  // This allows for handling SSIDs which are not valid UTF-8 strings.
+  [MinVersion=2] string? hexssid@6;
+
+  [MinVersion=1] string? guid@5;
+  string security@4;
+
+  // Fields specific to either visible or configured networks.
+  [MinVersion=2] NetworkDetails? details@7;
+
+  // Deprecated.  These will be removed when both sides support NetworkDetails.
+  int32 frequency@1;
+  int32 signal_strength@2;
+  string bssid@3;
+
+  // Deprecated. |hexssid| will be used, going forward.
+  string ssid@0;
 };
 
 struct NetworkData {
@@ -53,6 +88,20 @@
   // state. It is false if WiFi manipulation is prohibited due to a policy or
   // its current state.
   [MinVersion=3] SetWifiEnabledState@4(bool is_enabled) => (bool result);
+
+  // Creates a new network and returns the GUID.  If an error occurs,
+  // |guid| will be an empty string.
+  [MinVersion=4] CreateNetwork@5(WifiConfiguration cfg) => (string guid);
+
+  // Deletes an existing network.
+  [MinVersion=4] ForgetNetwork@6(string guid) => (NetworkResult status);
+
+  // Initiates a network connection.  If called when connected to a different
+  // network, it will drop the current connection first.
+  [MinVersion=4] StartConnect@7(string guid) => (NetworkResult status);
+
+  // Disconnects from network |guid|.
+  [MinVersion=4] StartDisconnect@8(string guid) => (NetworkResult status);
 };
 
 interface NetInstance {
diff --git a/components/arc/common/window_manager.mojom b/components/arc/common/window_manager.mojom
new file mode 100644
index 0000000..60fd3a74
--- /dev/null
+++ b/components/arc/common/window_manager.mojom
@@ -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.
+
+module arc.mojom;
+
+[Extensible]
+enum WindowManagerMode {
+  MODE_NORMAL = 0,
+  MODE_TOUCH_VIEW = 1
+};
+
+interface WindowManagerInstance {
+  // Informs of the currently used window mode.
+  OnWindowManagerModeChange(WindowManagerMode mode);
+};
diff --git a/components/arc/net/DEPS b/components/arc/net/DEPS
index 541abf5..5e505cc 100644
--- a/components/arc/net/DEPS
+++ b/components/arc/net/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+chromeos/login",
   "+chromeos/network",
   "+components/onc",
 ]
diff --git a/components/arc/net/OWNERS b/components/arc/net/OWNERS
new file mode 100644
index 0000000..b68dae8
--- /dev/null
+++ b/components/arc/net/OWNERS
@@ -0,0 +1,5 @@
+set noparent
+
+abhishekbh@chromium.org
+cernekee@chromium.org
+snanda@chromium.org
diff --git a/components/arc/net/arc_net_host_impl.cc b/components/arc/net/arc_net_host_impl.cc
index 8e2acd3..2c57bba 100644
--- a/components/arc/net/arc_net_host_impl.cc
+++ b/components/arc/net/arc_net_host_impl.cc
@@ -8,12 +8,17 @@
 #include <string>
 #include <vector>
 
+#include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "chromeos/login/login_state.h"
+#include "chromeos/network/managed_network_configuration_handler.h"
+#include "chromeos/network/network_connection_handler.h"
 #include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/network_type_pattern.h"
 #include "chromeos/network/network_util.h"
@@ -32,6 +37,22 @@
   return chromeos::NetworkHandler::Get()->network_state_handler();
 }
 
+chromeos::ManagedNetworkConfigurationHandler* GetManagedConfigurationHandler() {
+  return chromeos::NetworkHandler::Get()
+      ->managed_network_configuration_handler();
+}
+
+chromeos::NetworkConnectionHandler* GetNetworkConnectionHandler() {
+  return chromeos::NetworkHandler::Get()->network_connection_handler();
+}
+
+bool IsDeviceOwner() {
+  // Check whether the logged-in Chrome OS user is allowed to add or
+  // remove WiFi networks.
+  return chromeos::LoginState::Get()->GetLoggedInUserType() ==
+         chromeos::LoginState::LOGGED_IN_USER_OWNER;
+}
+
 ArcNetHostImpl::ArcNetHostImpl(ArcBridgeService* bridge_service)
     : ArcService(bridge_service), binding_(this) {
   arc_bridge_service()->AddObserver(this);
@@ -138,12 +159,172 @@
     DCHECK(!tmp.empty());
     wc->bssid = tmp;
 
+    mojom::VisibleNetworkDetailsPtr details =
+        mojom::VisibleNetworkDetails::New();
+    details->frequency = wc->frequency;
+    details->signal_strength = wc->signal_strength;
+    details->bssid = wc->bssid;
+    wc->details = mojom::NetworkDetails::New();
+    wc->details->set_visible(std::move(details));
+
     networks.push_back(std::move(wc));
   }
   data->networks = std::move(networks);
   callback.Run(std::move(data));
 }
 
+void CreateNetworkSuccessCallback(
+    const arc::mojom::NetHost::CreateNetworkCallback& mojo_callback,
+    const std::string& service_path,
+    const std::string& guid) {
+  VLOG(1) << "CreateNetworkSuccessCallback";
+  mojo_callback.Run(guid);
+}
+
+void CreateNetworkFailureCallback(
+    const arc::mojom::NetHost::CreateNetworkCallback& mojo_callback,
+    const std::string& error_name,
+    std::unique_ptr<base::DictionaryValue> error_data) {
+  VLOG(1) << "CreateNetworkFailureCallback: " << error_name;
+  mojo_callback.Run("");
+}
+
+void ArcNetHostImpl::CreateNetwork(mojom::WifiConfigurationPtr cfg,
+                                   const CreateNetworkCallback& callback) {
+  if (!IsDeviceOwner()) {
+    callback.Run("");
+    return;
+  }
+
+  std::unique_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
+  std::unique_ptr<base::DictionaryValue> wifi_dict(new base::DictionaryValue);
+
+  if (cfg->hexssid.is_null() || !cfg->details) {
+    callback.Run("");
+    return;
+  }
+  mojom::ConfiguredNetworkDetailsPtr details =
+      std::move(cfg->details->get_configured());
+  if (!details) {
+    callback.Run("");
+    return;
+  }
+
+  properties->SetStringWithoutPathExpansion(onc::network_config::kType,
+                                            onc::network_config::kWiFi);
+  wifi_dict->SetStringWithoutPathExpansion(onc::wifi::kHexSSID, cfg->hexssid);
+  wifi_dict->SetBooleanWithoutPathExpansion(onc::wifi::kAutoConnect,
+                                            details->autoconnect);
+  if (cfg->security.get().empty()) {
+    wifi_dict->SetStringWithoutPathExpansion(onc::wifi::kSecurity,
+                                             onc::wifi::kSecurityNone);
+  } else {
+    wifi_dict->SetStringWithoutPathExpansion(onc::wifi::kSecurity,
+                                             cfg->security);
+    if (!details->passphrase.is_null()) {
+      wifi_dict->SetStringWithoutPathExpansion(onc::wifi::kPassphrase,
+                                               details->passphrase);
+    }
+  }
+  properties->SetWithoutPathExpansion(onc::network_config::kWiFi,
+                                      std::move(wifi_dict));
+
+  std::string user_id_hash = chromeos::LoginState::Get()->primary_user_hash();
+  GetManagedConfigurationHandler()->CreateConfiguration(
+      user_id_hash, *properties,
+      base::Bind(&CreateNetworkSuccessCallback, callback),
+      base::Bind(&CreateNetworkFailureCallback, callback));
+}
+
+void ForgetNetworkSuccessCallback(
+    const arc::mojom::NetHost::ForgetNetworkCallback& mojo_callback) {
+  mojo_callback.Run(mojom::NetworkResult::SUCCESS);
+}
+
+void ForgetNetworkFailureCallback(
+    const arc::mojom::NetHost::ForgetNetworkCallback& mojo_callback,
+    const std::string& error_name,
+    std::unique_ptr<base::DictionaryValue> error_data) {
+  VLOG(1) << "ForgetNetworkFailureCallback: " << error_name;
+  mojo_callback.Run(mojom::NetworkResult::FAILURE);
+}
+
+void ArcNetHostImpl::ForgetNetwork(const mojo::String& guid,
+                                   const ForgetNetworkCallback& callback) {
+  if (!IsDeviceOwner()) {
+    callback.Run(mojom::NetworkResult::FAILURE);
+    return;
+  }
+
+  const chromeos::NetworkState* network =
+      GetStateHandler()->GetNetworkStateFromGuid(guid);
+
+  if (!network) {
+    callback.Run(mojom::NetworkResult::FAILURE);
+    return;
+  }
+
+  GetManagedConfigurationHandler()->RemoveConfiguration(
+      network->path(), base::Bind(&ForgetNetworkSuccessCallback, callback),
+      base::Bind(&ForgetNetworkFailureCallback, callback));
+}
+
+void StartConnectSuccessCallback(
+    const arc::mojom::NetHost::StartConnectCallback& mojo_callback) {
+  mojo_callback.Run(mojom::NetworkResult::SUCCESS);
+}
+
+void StartConnectFailureCallback(
+    const arc::mojom::NetHost::StartConnectCallback& mojo_callback,
+    const std::string& error_name,
+    std::unique_ptr<base::DictionaryValue> error_data) {
+  VLOG(1) << "StartConnectFailureCallback: " << error_name;
+  mojo_callback.Run(mojom::NetworkResult::FAILURE);
+}
+
+void ArcNetHostImpl::StartConnect(const mojo::String& guid,
+                                  const StartConnectCallback& callback) {
+  const chromeos::NetworkState* network =
+      GetStateHandler()->GetNetworkStateFromGuid(guid);
+
+  if (!network) {
+    callback.Run(mojom::NetworkResult::FAILURE);
+    return;
+  }
+
+  GetNetworkConnectionHandler()->ConnectToNetwork(
+      network->path(), base::Bind(&StartConnectSuccessCallback, callback),
+      base::Bind(&StartConnectFailureCallback, callback), false);
+}
+
+void StartDisconnectSuccessCallback(
+    const arc::mojom::NetHost::StartDisconnectCallback& mojo_callback) {
+  mojo_callback.Run(mojom::NetworkResult::SUCCESS);
+}
+
+void StartDisconnectFailureCallback(
+    const arc::mojom::NetHost::StartDisconnectCallback& mojo_callback,
+    const std::string& error_name,
+    std::unique_ptr<base::DictionaryValue> error_data) {
+  VLOG(1) << "StartDisconnectFailureCallback: " << error_name;
+  mojo_callback.Run(mojom::NetworkResult::FAILURE);
+}
+
+void ArcNetHostImpl::StartDisconnect(const mojo::String& guid,
+                                     const StartDisconnectCallback& callback) {
+  const chromeos::NetworkState* network =
+      GetStateHandler()->GetNetworkStateFromGuid(guid);
+
+  if (!network) {
+    callback.Run(mojom::NetworkResult::FAILURE);
+    return;
+  }
+
+  GetNetworkConnectionHandler()->DisconnectNetwork(
+      network->path(), base::Bind(&StartDisconnectSuccessCallback, callback),
+      base::Bind(&StartDisconnectFailureCallback, callback));
+}
+
 void ArcNetHostImpl::GetWifiEnabledState(
     const GetWifiEnabledStateCallback& callback) {
   bool is_enabled = GetStateHandler()->IsTechnologyEnabled(
diff --git a/components/arc/net/arc_net_host_impl.h b/components/arc/net/arc_net_host_impl.h
index 04de3c1..af5df41 100644
--- a/components/arc/net/arc_net_host_impl.h
+++ b/components/arc/net/arc_net_host_impl.h
@@ -32,32 +32,39 @@
   explicit ArcNetHostImpl(ArcBridgeService* arc_bridge_service);
   ~ArcNetHostImpl() override;
 
-  // Called when a GetNetworks call is sent from ARC.
+  // ARC -> Chrome calls:
+
   void GetNetworksDeprecated(
       bool configured_only,
       bool visible_only,
       const GetNetworksDeprecatedCallback& callback) override;
 
-  // Called when a GetNetworks call is sent from ARC.
   void GetNetworks(mojom::GetNetworksRequestType type,
                    const GetNetworksCallback& callback) override;
 
-  // Called when a GetWifiEnabledState call is sent from ARC.
   void GetWifiEnabledState(
       const GetWifiEnabledStateCallback& callback) override;
 
-  // Called when a SetWifiEnabledState call is sent from ARC.
   void SetWifiEnabledState(
       bool is_enabled,
       const SetWifiEnabledStateCallback& callback) override;
 
-  // Called when a StartScan call is sent from ARC.
   void StartScan() override;
 
+  void CreateNetwork(mojom::WifiConfigurationPtr cfg,
+                     const CreateNetworkCallback& callback) override;
+
+  void ForgetNetwork(const mojo::String& guid,
+                     const ForgetNetworkCallback& callback) override;
+
+  void StartConnect(const mojo::String& guid,
+                    const StartConnectCallback& callback) override;
+
+  void StartDisconnect(const mojo::String& guid,
+                       const StartDisconnectCallback& callback) override;
+
   // Overriden from chromeos::NetworkStateHandlerObserver.
   void ScanCompleted(const chromeos::DeviceState* /*unused*/) override;
-
-  // Overriden from chromeos::NetworkStateHandlerObserver.
   void OnShuttingDown() override;
 
   // Overridden from ArcBridgeService::Observer:
diff --git a/components/arc/window_manager/DEPS b/components/arc/window_manager/DEPS
new file mode 100644
index 0000000..ea4bd7e
--- /dev/null
+++ b/components/arc/window_manager/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+ash",
+]
diff --git a/components/arc/window_manager/arc_window_manager_bridge.cc b/components/arc/window_manager/arc_window_manager_bridge.cc
new file mode 100644
index 0000000..6007117
--- /dev/null
+++ b/components/arc/window_manager/arc_window_manager_bridge.cc
@@ -0,0 +1,74 @@
+// 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/arc/window_manager/arc_window_manager_bridge.h"
+
+#include "ash/shell.h"
+#include "ash/wm/maximize_mode/maximize_mode_controller.h"
+#include "base/logging.h"
+#include "components/arc/arc_bridge_service.h"
+
+namespace arc {
+
+ArcWindowManagerBridge::ArcWindowManagerBridge(ArcBridgeService* bridge_service)
+    : ArcService(bridge_service),
+      current_mode_(mojom::WindowManagerMode::MODE_NORMAL) {
+  arc_bridge_service()->AddObserver(this);
+  if (!ash::Shell::HasInstance()) {
+    // The shell gets always loaded before ARC. If there is no shell it can only
+    // mean that a unit test is running.
+    return;
+  }
+  // Monitor any mode changes from now on.
+  ash::Shell::GetInstance()->AddShellObserver(this);
+}
+
+void ArcWindowManagerBridge::OnWindowManagerInstanceReady() {
+  if (!ash::Shell::HasInstance()) {
+    // The shell gets always loaded before ARC. If there is no shell it can only
+    // mean that a unit test is running.
+    return;
+  }
+  ash::MaximizeModeController* controller =
+      ash::Shell::GetInstance()->maximize_mode_controller();
+  if (!controller)
+    return;
+
+  // Set the initial mode configuration.
+  SendWindowManagerModeChange(controller->IsMaximizeModeWindowManagerEnabled());
+}
+
+ArcWindowManagerBridge::~ArcWindowManagerBridge() {
+  if (ash::Shell::HasInstance())
+    ash::Shell::GetInstance()->RemoveShellObserver(this);
+  arc_bridge_service()->RemoveObserver(this);
+}
+
+void ArcWindowManagerBridge::OnMaximizeModeStarted() {
+  SendWindowManagerModeChange(true);
+}
+
+void ArcWindowManagerBridge::OnMaximizeModeEnded() {
+  SendWindowManagerModeChange(false);
+}
+
+void ArcWindowManagerBridge::SendWindowManagerModeChange(
+    bool touch_view_enabled) {
+  // We let the ArcBridgeService check that we are calling on the right thread.
+  DCHECK(ArcBridgeService::Get() != nullptr);
+  mojom::WindowManagerMode wm_mode = touch_view_enabled ?
+      mojom::WindowManagerMode::MODE_TOUCH_VIEW :
+      mojom::WindowManagerMode::MODE_NORMAL;
+
+  mojom::WindowManagerInstance* wm_instance =
+      arc_bridge_service()->window_manager_instance();
+  if (!wm_instance || wm_mode == current_mode_) {
+    return;
+  }
+  VLOG(1) << "Sending window manager mode change to " << wm_mode;
+  wm_instance->OnWindowManagerModeChange(wm_mode);
+  current_mode_ = wm_mode;
+}
+
+}  // namespace arc
diff --git a/components/arc/window_manager/arc_window_manager_bridge.h b/components/arc/window_manager/arc_window_manager_bridge.h
new file mode 100644
index 0000000..c6176583
--- /dev/null
+++ b/components/arc/window_manager/arc_window_manager_bridge.h
@@ -0,0 +1,42 @@
+// 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_ARC_WINDOW_MANAGER_ARC_WINDOW_MANAGER_BRIDGE_H_
+#define COMPONENTS_ARC_WINDOW_MANAGER_ARC_WINDOW_MANAGER_BRIDGE_H_
+
+#include <string>
+
+#include "ash/shell_observer.h"
+#include "base/macros.h"
+#include "components/arc/arc_bridge_service.h"
+#include "components/arc/arc_service.h"
+
+namespace arc {
+
+class ArcWindowManagerBridge : public ArcService,
+                               public ArcBridgeService::Observer,
+                               public ash::ShellObserver {
+ public:
+  explicit ArcWindowManagerBridge(ArcBridgeService* bridge_service);
+  ~ArcWindowManagerBridge() override;
+
+  // ArcBridgeService::Observer
+  void OnWindowManagerInstanceReady() override;
+
+  // Ash::Shell::ShellObserver
+  void OnMaximizeModeStarted() override;
+  void OnMaximizeModeEnded() override;
+
+ private:
+  void SendWindowManagerModeChange(bool touch_view_enabled);
+
+  // Remembers the currently set mode on the Android side.
+  mojom::WindowManagerMode current_mode_;
+
+  DISALLOW_COPY_AND_ASSIGN(ArcWindowManagerBridge);
+};
+
+}  // namespace arc
+
+#endif  // COMPONENTS_ARC_WINDOW_MANAGER_ARC_WINDOW_MANAGER_BRIDGE_H_
diff --git a/components/autofill.gypi b/components/autofill.gypi
index c9c4041c..378e79a 100644
--- a/components/autofill.gypi
+++ b/components/autofill.gypi
@@ -397,6 +397,7 @@
             '../third_party/icu/icu.gyp:icuuc',
             '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber',
             '../ui/base/ui_base.gyp:ui_base',
+            '../ui/display/display.gyp:display',
             '../ui/gfx/gfx.gyp:gfx',
             '../ui/gfx/gfx.gyp:gfx_geometry',
             '../url/url.gyp:url_lib',
diff --git a/components/autofill/content/browser/BUILD.gn b/components/autofill/content/browser/BUILD.gn
index baa997d6..a5be4587 100644
--- a/components/autofill/content/browser/BUILD.gn
+++ b/components/autofill/content/browser/BUILD.gn
@@ -35,8 +35,8 @@
     "//components/autofill/content/common",
     "//components/autofill/core/browser",
     "//components/autofill/core/common",
-    "//components/prefs",
     "//components/os_crypt",
+    "//components/prefs",
     "//components/resources",
     "//components/strings",
     "//components/user_prefs",
@@ -51,6 +51,7 @@
     "//third_party/icu",
     "//third_party/libphonenumber",
     "//ui/base",
+    "//ui/display",
     "//ui/gfx",
     "//ui/gfx/geometry",
     "//url",
diff --git a/components/autofill/content/browser/risk/fingerprint.cc b/components/autofill/content/browser/risk/fingerprint.cc
index f60edfa..06dfa98 100644
--- a/components/autofill/content/browser/risk/fingerprint.cc
+++ b/components/autofill/content/browser/risk/fingerprint.cc
@@ -42,8 +42,8 @@
 #include "gpu/config/gpu_info.h"
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
+#include "ui/display/screen.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
 
 using blink::WebScreenInfo;
 
@@ -126,10 +126,10 @@
 // into the |machine|.
 void AddScreenInfoToFingerprint(const WebScreenInfo& screen_info,
                                 Fingerprint::MachineCharacteristics* machine) {
-  machine->set_screen_count(gfx::Screen::GetScreen()->GetNumDisplays());
+  machine->set_screen_count(display::Screen::GetScreen()->GetNumDisplays());
 
   const gfx::Size screen_size =
-      gfx::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel();
+      display::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel();
   machine->mutable_screen_size()->set_width(screen_size.width());
   machine->mutable_screen_size()->set_height(screen_size.height());
 
diff --git a/components/autofill/core/browser/autofill_data_model_unittest.cc b/components/autofill/core/browser/autofill_data_model_unittest.cc
index 443401690..99021740 100644
--- a/components/autofill/core/browser/autofill_data_model_unittest.cc
+++ b/components/autofill/core/browser/autofill_data_model_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/time/time.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace autofill {
@@ -60,7 +61,7 @@
   model.set_origin("chrome://settings/autofill");
   EXPECT_FALSE(model.IsVerified());
 
-  model.set_origin("Chrome Settings");
+  model.set_origin(kSettingsOrigin);
   EXPECT_TRUE(model.IsVerified());
 
   model.set_origin("Some gibberish string");
diff --git a/components/autofill/core/browser/autofill_profile_unittest.cc b/components/autofill/core/browser/autofill_profile_unittest.cc
index 20086169..a41b756 100644
--- a/components/autofill/core/browser/autofill_profile_unittest.cc
+++ b/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -19,6 +19,7 @@
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -72,7 +73,7 @@
 
 void SetupTestProfile(AutofillProfile& profile) {
   profile.set_guid(base::GenerateGUID());
-  profile.set_origin("Chrome settings");
+  profile.set_origin(kSettingsOrigin);
   test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
                        "marion@me.xyz", "Fox", "123 Zoo St.", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
@@ -224,7 +225,7 @@
   EXPECT_EQ(ASCIIToUTF16("Jane Doe, 123 Letha Shore."), labels[1]);
 
   profiles.push_back(
-      new AutofillProfile(base::GenerateGUID(), "Chrome settings"));
+      new AutofillProfile(base::GenerateGUID(), kSettingsOrigin));
   test::SetProfileInfo(
       profiles[2],
       "John",
@@ -854,7 +855,7 @@
   //   (5) Has a language code.
   AutofillProfile b = a;
   b.set_guid(base::GenerateGUID());
-  b.set_origin("Chrome settings");
+  b.set_origin(kSettingsOrigin);
   b.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("area 51"));
   b.SetRawInfo(COMPANY_NAME, base::string16());
 
@@ -862,7 +863,7 @@
   b.set_language_code("en");
 
   EXPECT_TRUE(a.OverwriteWith(b, "en-US"));
-  EXPECT_EQ("Chrome settings", a.origin());
+  EXPECT_EQ(kSettingsOrigin, a.origin());
   EXPECT_EQ(ASCIIToUTF16("area 51"), a.GetRawInfo(ADDRESS_HOME_LINE2));
   EXPECT_EQ(ASCIIToUTF16("Fox"), a.GetRawInfo(COMPANY_NAME));
   base::string16 name = a.GetInfo(AutofillType(NAME_FULL), "en-US");
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc
index 972fea0f..459481a 100644
--- a/components/autofill/core/browser/autofill_test_utils.cc
+++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -14,6 +14,7 @@
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
@@ -31,12 +32,6 @@
 namespace autofill {
 namespace test {
 
-namespace {
-
-const char kSettingsOrigin[] = "Chrome settings";
-
-}  // namespace
-
 std::unique_ptr<PrefService> PrefServiceForTesting() {
   scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
       new user_prefs::PrefRegistrySyncable());
diff --git a/components/autofill/core/browser/credit_card_unittest.cc b/components/autofill/core/browser/credit_card_unittest.cc
index 24be282..2f282578 100644
--- a/components/autofill/core/browser/credit_card_unittest.cc
+++ b/components/autofill/core/browser/credit_card_unittest.cc
@@ -14,6 +14,7 @@
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/validation.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/form_field_data.h"
 #include "grit/components_scaled_resources.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -364,11 +365,11 @@
   // Try again, but with only the original card having a verified origin.
   // |a| should be unchanged.
   a = original_card;
-  a.set_origin("Chrome settings");
+  a.set_origin(kSettingsOrigin);
   b.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("J. Dillinger"));
 
   EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
-  EXPECT_EQ("Chrome settings", a.origin());
+  EXPECT_EQ(kSettingsOrigin, a.origin());
   EXPECT_EQ(ASCIIToUTF16("John Dillinger"),
             a.GetRawInfo(CREDIT_CARD_NAME_FULL));
   EXPECT_EQ(ASCIIToUTF16("09"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
@@ -420,10 +421,10 @@
   // Try again, but with only the new card having a verified origin.
   // |a| should be updated.
   a = original_card;
-  b.set_origin("Chrome settings");
+  b.set_origin(kSettingsOrigin);
 
   EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
-  EXPECT_EQ("Chrome settings", a.origin());
+  EXPECT_EQ(kSettingsOrigin, a.origin());
   EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME_FULL));
   EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
   EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
@@ -432,10 +433,10 @@
   // |a| should be updated.
   a = original_card;
   a.set_origin("Chrome Autofill dialog");
-  b.set_origin("Chrome settings");
+  b.set_origin(kSettingsOrigin);
 
   EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
-  EXPECT_EQ("Chrome settings", a.origin());
+  EXPECT_EQ(kSettingsOrigin, a.origin());
   EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME_FULL));
   EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
   EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 37080aa5..f229534b 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -28,6 +28,7 @@
 #include "components/autofill/core/browser/personal_data_manager_observer.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/form_data.h"
@@ -605,8 +606,8 @@
   // Try to update with just the origin changed.
   AutofillProfile original_profile(profile);
   CreditCard original_credit_card(credit_card);
-  profile.set_origin("Chrome settings");
-  credit_card.set_origin("Chrome settings");
+  profile.set_origin(kSettingsOrigin);
+  credit_card.set_origin(kSettingsOrigin);
 
   EXPECT_TRUE(profile.IsVerified());
   EXPECT_TRUE(credit_card.IsVerified());
@@ -1919,7 +1920,7 @@
 TEST_F(PersonalDataManagerTest,
        ImportAddressProfiles_ExistingVerifiedProfileWithConflict) {
   // Start with a verified profile.
-  AutofillProfile profile(base::GenerateGUID(), "Chrome settings");
+  AutofillProfile profile(base::GenerateGUID(), kSettingsOrigin);
   test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
                        "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
@@ -2507,7 +2508,7 @@
 TEST_F(PersonalDataManagerTest,
        ImportCreditCard_ExistingVerifiedCardWithConflict) {
   // Start with a verified credit card.
-  CreditCard credit_card(base::GenerateGUID(), "Chrome settings");
+  CreditCard credit_card(base::GenerateGUID(), kSettingsOrigin);
   test::SetCreditCardInfo(&credit_card, "Biggie Smalls",
                           "4111 1111 1111 1111" /* Visa */, "01", "2999");
   EXPECT_TRUE(credit_card.IsVerified());
@@ -2697,7 +2698,7 @@
 
   AutofillProfile new_verified_profile = profile;
   new_verified_profile.set_guid(base::GenerateGUID());
-  new_verified_profile.set_origin("Chrome settings");
+  new_verified_profile.set_origin(kSettingsOrigin);
   new_verified_profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
                                   ASCIIToUTF16("1 234 567-8910"));
   EXPECT_TRUE(new_verified_profile.IsVerified());
@@ -2719,7 +2720,7 @@
 // overwriting existing verified profiles as well.
 TEST_F(PersonalDataManagerTest, SaveImportedProfileWithExistingVerifiedData) {
   // Start with a verified profile.
-  AutofillProfile profile(base::GenerateGUID(), "Chrome settings");
+  AutofillProfile profile(base::GenerateGUID(), kSettingsOrigin);
   test::SetProfileInfo(&profile,
       "Marion", "Mitchell", "Morrison",
       "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA",
@@ -2756,7 +2757,7 @@
 // Ensure that verified credit cards can be saved via SaveImportedCreditCard.
 TEST_F(PersonalDataManagerTest, SaveImportedCreditCardWithVerifiedData) {
   // Start with a verified credit card.
-  CreditCard credit_card(base::GenerateGUID(), "Chrome settings");
+  CreditCard credit_card(base::GenerateGUID(), kSettingsOrigin);
   test::SetCreditCardInfo(&credit_card,
       "Biggie Smalls", "4111 1111 1111 1111" /* Visa */, "01", "2999");
   EXPECT_TRUE(credit_card.IsVerified());
@@ -2993,7 +2994,7 @@
       personal_data_->GetDefaultCountryCodeForNewAddress();
   EXPECT_EQ(2U, default_country.size());
 
-  AutofillProfile moose(base::GenerateGUID(), "Chrome settings");
+  AutofillProfile moose(base::GenerateGUID(), kSettingsOrigin);
   test::SetProfileInfo(&moose, "Moose", "P", "McMahon", "mpm@example.com",
       "", "1 Taiga TKTR", "", "Calgary", "AB", "T2B 2K2",
       "CA", "(800) 555-9000");
@@ -3021,7 +3022,7 @@
 }
 
 TEST_F(PersonalDataManagerTest, DefaultCountryCodeComesFromProfiles) {
-  AutofillProfile moose(base::GenerateGUID(), "Chrome settings");
+  AutofillProfile moose(base::GenerateGUID(), kSettingsOrigin);
   test::SetProfileInfo(&moose, "Moose", "P", "McMahon", "mpm@example.com",
       "", "1 Taiga TKTR", "", "Calgary", "AB", "T2B 2K2",
       "CA", "(800) 555-9000");
@@ -3030,11 +3031,11 @@
   EXPECT_EQ("CA", personal_data_->GetDefaultCountryCodeForNewAddress());
 
   // Multiple profiles cast votes.
-  AutofillProfile armadillo(base::GenerateGUID(), "Chrome settings");
+  AutofillProfile armadillo(base::GenerateGUID(), kSettingsOrigin);
   test::SetProfileInfo(&armadillo, "Armin", "Dill", "Oh", "ado@example.com",
       "", "1 Speed Bump", "", "Lubbock", "TX", "77500",
       "MX", "(800) 555-9000");
-  AutofillProfile armadillo2(base::GenerateGUID(), "Chrome settings");
+  AutofillProfile armadillo2(base::GenerateGUID(), kSettingsOrigin);
   test::SetProfileInfo(&armadillo2, "Armin", "Dill", "Oh", "ado@example.com",
       "", "2 Speed Bump", "", "Lubbock", "TX", "77500",
       "MX", "(800) 555-9000");
@@ -3057,7 +3058,7 @@
   personal_data_->RemoveByGUID(armadillo.guid());
   ResetPersonalDataManager(USER_MODE_NORMAL);
   // But unverified profiles can be a tie breaker.
-  armadillo.set_origin("Chrome settings");
+  armadillo.set_origin(kSettingsOrigin);
   personal_data_->AddProfile(armadillo);
   ResetPersonalDataManager(USER_MODE_NORMAL);
   EXPECT_EQ("MX", personal_data_->GetDefaultCountryCodeForNewAddress());
@@ -3065,7 +3066,7 @@
   // Invalid country codes are ignored.
   personal_data_->RemoveByGUID(armadillo.guid());
   personal_data_->RemoveByGUID(moose.guid());
-  AutofillProfile space_invader(base::GenerateGUID(), "Chrome settings");
+  AutofillProfile space_invader(base::GenerateGUID(), kSettingsOrigin);
   test::SetProfileInfo(&space_invader, "Marty", "", "Martian",
       "mm@example.com", "", "1 Flying Object", "", "Valles Marineris", "",
       "", "XX", "");
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
index dc15397..da62a11 100644
--- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
@@ -15,6 +15,7 @@
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/country_names.h"
 #include "components/autofill/core/browser/webdata/autofill_change.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "sync/api/sync_error_factory.h"
 #include "sync/api/sync_error_factory_mock.h"
 #include "sync/protocol/sync.pb.h"
@@ -39,7 +40,6 @@
 const char kGuid4[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44E";
 const char kHttpOrigin[] = "http://www.example.com/";
 const char kHttpsOrigin[] = "https://www.example.com/";
-const char kSettingsOrigin[] = "Chrome settings";
 
 class MockAutofillProfileSyncableService
     : public AutofillProfileSyncableService {
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index 78a1a11..5243b1a 100644
--- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -27,6 +27,7 @@
 #include "components/autofill/core/browser/webdata/autofill_change.h"
 #include "components/autofill/core/browser/webdata/autofill_entry.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/autofill/core/common/autofill_util.h"
 #include "components/autofill/core/common/form_field_data.h"
@@ -788,7 +789,7 @@
   EXPECT_FALSE(s_billing_updated.Step());
 
   // Update the 'Billing' profile.
-  billing_profile.set_origin("Chrome settings");
+  billing_profile.set_origin(kSettingsOrigin);
   billing_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Janice"));
   billing_profile.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("C."));
   billing_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Joplin"));
@@ -1401,7 +1402,7 @@
   EXPECT_EQ(std::string(), s_autofill_profiles_bounded.ColumnString(1));
   ASSERT_TRUE(s_autofill_profiles_bounded.Step());
   EXPECT_EQ(31, s_autofill_profiles_bounded.ColumnInt64(0));
-  EXPECT_EQ("Chrome settings", s_autofill_profiles_bounded.ColumnString(1));
+  EXPECT_EQ(kSettingsOrigin, s_autofill_profiles_bounded.ColumnString(1));
   sql::Statement s_credit_cards_bounded(
       db_->GetSQLConnection()->GetUniqueStatement(
           "SELECT date_modified, origin FROM credit_cards"));
@@ -1415,7 +1416,7 @@
             s_credit_cards_bounded.ColumnString(1));
   ASSERT_TRUE(s_credit_cards_bounded.Step());
   EXPECT_EQ(37, s_credit_cards_bounded.ColumnInt64(0));
-  EXPECT_EQ("Chrome settings", s_credit_cards_bounded.ColumnString(1));
+  EXPECT_EQ(kSettingsOrigin, s_credit_cards_bounded.ColumnString(1));
 
   // Remove all origin URLS.
   profiles.clear();
@@ -1433,7 +1434,7 @@
   EXPECT_EQ(std::string(), s_autofill_profiles_all.ColumnString(1));
   ASSERT_TRUE(s_autofill_profiles_all.Step());
   EXPECT_EQ(31, s_autofill_profiles_all.ColumnInt64(0));
-  EXPECT_EQ("Chrome settings", s_autofill_profiles_all.ColumnString(1));
+  EXPECT_EQ(kSettingsOrigin, s_autofill_profiles_all.ColumnString(1));
   sql::Statement s_credit_cards_all(
       db_->GetSQLConnection()->GetUniqueStatement(
           "SELECT date_modified, origin FROM credit_cards"));
@@ -1446,7 +1447,7 @@
   EXPECT_EQ(std::string(), s_credit_cards_all.ColumnString(1));
   ASSERT_TRUE(s_credit_cards_all.Step());
   EXPECT_EQ(37, s_credit_cards_all.ColumnInt64(0));
-  EXPECT_EQ("Chrome settings", s_credit_cards_all.ColumnString(1));
+  EXPECT_EQ(kSettingsOrigin, s_credit_cards_all.ColumnString(1));
 }
 
 TEST_F(AutofillTableTest, Autofill_GetAllAutofillEntries_NoResults) {
diff --git a/components/autofill/core/common/autofill_constants.cc b/components/autofill/core/common/autofill_constants.cc
index eeefcdbed..6e30f511 100644
--- a/components/autofill/core/common/autofill_constants.cc
+++ b/components/autofill/core/common/autofill_constants.cc
@@ -15,4 +15,6 @@
     "https://support.google.com/chrome/?p=settings_autofill";
 #endif
 
+const char kSettingsOrigin[] = "Chrome settings";
+
 }  // namespace autofill
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h
index 9a1886a..ab09290 100644
--- a/components/autofill/core/common/autofill_constants.h
+++ b/components/autofill/core/common/autofill_constants.h
@@ -14,6 +14,9 @@
 // Help URL for the Autofill dialog.
 extern const char kHelpURL[];
 
+// The origin of an AutofillDataModel created or modified in the settings page.
+extern const char kSettingsOrigin[];
+
 // The number of fields required by Autofill to execute its heuristic and
 // crowdsourcing prediction routines. Ideally we would execute those routines no
 // matter how many fields are in the forms; however, finding the label for each
diff --git a/components/browsing_data_ui/history_notice_utils.cc b/components/browsing_data_ui/history_notice_utils.cc
index 1116c3f..c1568f2 100644
--- a/components/browsing_data_ui/history_notice_utils.cc
+++ b/components/browsing_data_ui/history_notice_utils.cc
@@ -23,9 +23,7 @@
   if (!sync_service ||
       !sync_service->IsSyncActive() ||
       sync_service->IsUsingSecondaryPassphrase() ||
-      !history_service ||
-      (!testing::g_override_other_forms_of_browsing_history_query &&
-       !history_service->HasOtherFormsOfBrowsingHistory())) {
+      !history_service) {
     callback.Run(false);
     return;
   }
@@ -37,6 +35,13 @@
     const ProfileSyncService* sync_service,
     history::WebHistoryService* history_service,
     base::Callback<void(bool)> callback) {
+  if (!history_service ||
+      (!testing::g_override_other_forms_of_browsing_history_query &&
+       !history_service->HasOtherFormsOfBrowsingHistory())) {
+    callback.Run(false);
+    return;
+  }
+
   ShouldShowNoticeAboutOtherFormsOfBrowsingHistory(
       sync_service, history_service, callback);
 }
diff --git a/components/cdm.gypi b/components/cdm.gypi
index 853ff35..3698f34 100644
--- a/components/cdm.gypi
+++ b/components/cdm.gypi
@@ -18,6 +18,14 @@
         'cdm/common/cdm_message_generator.h',
         'cdm/common/cdm_messages_android.h',
       ],
+      'conditions': [
+        ['OS == "android"', {
+          'sources': [
+            'cdm/common/widevine_drm_delegate_android.cc',
+            'cdm/common/widevine_drm_delegate_android.h',
+          ],
+        }],
+      ],
     },
     {
       # GN version: //components/cdm/renderer
@@ -30,12 +38,12 @@
         '../third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h',
       ],
       'include_dirs': [
-        # Needed by widevine_key_systems.cc.
+        # Needed by widevine_key_system_properties.cc.
         '<(SHARED_INTERMEDIATE_DIR)',
       ],
       'sources': [
-        'cdm/renderer/widevine_key_systems.cc',
-        'cdm/renderer/widevine_key_systems.h',
+        'cdm/renderer/widevine_key_system_properties.cc',
+        'cdm/renderer/widevine_key_system_properties.h',
       ],
       'conditions': [
         ['OS == "android"', {
@@ -64,8 +72,6 @@
           'sources': [
             'cdm/browser/cdm_message_filter_android.cc',
             'cdm/browser/cdm_message_filter_android.h',
-            'cdm/browser/widevine_drm_delegate_android.cc',
-            'cdm/browser/widevine_drm_delegate_android.h',
           ],
         },
       ],
diff --git a/components/cdm/DEPS b/components/cdm/DEPS
index 5ca4943..7417b99 100644
--- a/components/cdm/DEPS
+++ b/components/cdm/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+ipc",
   "+media/base",
+  "+media/cdm",
 ]
diff --git a/components/cdm/browser/BUILD.gn b/components/cdm/browser/BUILD.gn
index 1a6e272..79f30dd 100644
--- a/components/cdm/browser/BUILD.gn
+++ b/components/cdm/browser/BUILD.gn
@@ -6,8 +6,6 @@
   sources = [
     "cdm_message_filter_android.cc",
     "cdm_message_filter_android.h",
-    "widevine_drm_delegate_android.cc",
-    "widevine_drm_delegate_android.h",
   ]
 
   deps = [
diff --git a/components/cdm/common/BUILD.gn b/components/cdm/common/BUILD.gn
index 25cd70b..fc43c7e 100644
--- a/components/cdm/common/BUILD.gn
+++ b/components/cdm/common/BUILD.gn
@@ -7,6 +7,8 @@
     "cdm_message_generator.cc",
     "cdm_message_generator.h",
     "cdm_messages_android.h",
+    "widevine_drm_delegate_android.cc",
+    "widevine_drm_delegate_android.h",
   ]
 
   deps = [
diff --git a/components/cdm/browser/widevine_drm_delegate_android.cc b/components/cdm/common/widevine_drm_delegate_android.cc
similarity index 78%
rename from components/cdm/browser/widevine_drm_delegate_android.cc
rename to components/cdm/common/widevine_drm_delegate_android.cc
index d2e7f67b..d8e0f43 100644
--- a/components/cdm/browser/widevine_drm_delegate_android.cc
+++ b/components/cdm/common/widevine_drm_delegate_android.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/cdm/browser/widevine_drm_delegate_android.h"
+#include "components/cdm/common/widevine_drm_delegate_android.h"
 
 #include "base/macros.h"
 #include "media/cdm/cenc_utils.h"
@@ -12,16 +12,14 @@
 namespace {
 
 const uint8_t kWidevineUuid[16] = {
-    0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,
-    0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED };
+    0xED, 0xEF, 0x8B, 0xA9, 0x79, 0xD6, 0x4A, 0xCE,  //
+    0xA3, 0xC8, 0x27, 0xDC, 0xD5, 0x1D, 0x21, 0xED};
 
 }  // namespace
 
-WidevineDrmDelegateAndroid::WidevineDrmDelegateAndroid() {
-}
+WidevineDrmDelegateAndroid::WidevineDrmDelegateAndroid() {}
 
-WidevineDrmDelegateAndroid::~WidevineDrmDelegateAndroid() {
-}
+WidevineDrmDelegateAndroid::~WidevineDrmDelegateAndroid() {}
 
 const std::vector<uint8_t> WidevineDrmDelegateAndroid::GetUUID() const {
   return std::vector<uint8_t>(kWidevineUuid,
diff --git a/components/cdm/browser/widevine_drm_delegate_android.h b/components/cdm/common/widevine_drm_delegate_android.h
similarity index 81%
rename from components/cdm/browser/widevine_drm_delegate_android.h
rename to components/cdm/common/widevine_drm_delegate_android.h
index 6beb601..2fd50d7c 100644
--- a/components/cdm/browser/widevine_drm_delegate_android.h
+++ b/components/cdm/common/widevine_drm_delegate_android.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_CDM_BROWSER_WIDEVINE_DRM_DELEGATE_ANDROID_H_
-#define COMPONENTS_CDM_BROWSER_WIDEVINE_DRM_DELEGATE_ANDROID_H_
+#ifndef COMPONENTS_CDM_COMMON_WIDEVINE_DRM_DELEGATE_ANDROID_H_
+#define COMPONENTS_CDM_COMMON_WIDEVINE_DRM_DELEGATE_ANDROID_H_
 
 #include <stdint.h>
 
@@ -31,4 +31,4 @@
 
 }  // namespace cdm
 
-#endif  // COMPONENTS_CDM_BROWSER_WIDEVINE_DRM_DELEGATE_ANDROID_H_
+#endif  // COMPONENTS_CDM_COMMON_WIDEVINE_DRM_DELEGATE_ANDROID_H_
diff --git a/components/cdm/renderer/BUILD.gn b/components/cdm/renderer/BUILD.gn
index ef4d03d0..f364f89 100644
--- a/components/cdm/renderer/BUILD.gn
+++ b/components/cdm/renderer/BUILD.gn
@@ -4,8 +4,8 @@
 
 static_library("renderer") {
   sources = [
-    "widevine_key_systems.cc",
-    "widevine_key_systems.h",
+    "widevine_key_system_properties.cc",
+    "widevine_key_system_properties.h",
   ]
 
   if (is_android) {
diff --git a/components/cdm/renderer/android_key_systems.cc b/components/cdm/renderer/android_key_systems.cc
index 56d2aec6..8e4f7529 100644
--- a/components/cdm/renderer/android_key_systems.cc
+++ b/components/cdm/renderer/android_key_systems.cc
@@ -10,21 +10,89 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "components/cdm/common/cdm_messages_android.h"
-#include "components/cdm/renderer/widevine_key_systems.h"
+#include "components/cdm/renderer/widevine_key_system_properties.h"
 #include "content/public/renderer/render_thread.h"
 #include "media/base/eme_constants.h"
 #include "media/base/media_switches.h"
 
 #include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
 
+using media::EmeConfigRule;
 using media::EmeFeatureSupport;
+using media::EmeInitDataType;
 using media::EmeRobustness;
 using media::EmeSessionTypeSupport;
-using media::KeySystemInfo;
+using media::KeySystemProperties;
 using media::SupportedCodecs;
 
 namespace cdm {
 
+namespace {
+
+// Implementation of KeySystemProperties for platform-supported key systems.
+// Assumes that platform key systems support no features but can and will
+// make use of persistence and identifiers.
+class AndroidPlatformKeySystemProperties : public KeySystemProperties {
+ public:
+  AndroidPlatformKeySystemProperties(const std::string& name,
+                                     SupportedCodecs supported_codecs)
+      : name_(name), supported_codecs_(supported_codecs) {}
+
+  std::string GetKeySystemName() const override { return name_; }
+
+  bool IsSupportedInitDataType(EmeInitDataType init_data_type) const override {
+    // Here we assume that support for a container implies support for the
+    // associated initialization data type. KeySystems handles validating
+    // |init_data_type| x |container| pairings.
+    switch (init_data_type) {
+      case EmeInitDataType::WEBM:
+        return (supported_codecs_ & media::EME_CODEC_WEBM_ALL) != 0;
+      case EmeInitDataType::CENC:
+#if defined(USE_PROPRIETARY_CODECS)
+        return (supported_codecs_ & media::EME_CODEC_MP4_ALL) != 0;
+#else
+        return false;
+#endif  // defined(USE_PROPRIETARY_CODECS)
+      case EmeInitDataType::KEYIDS:
+      case EmeInitDataType::UNKNOWN:
+        return false;
+    }
+    NOTREACHED();
+    return false;
+  }
+
+  SupportedCodecs GetSupportedCodecs() const override {
+    return supported_codecs_;
+  }
+
+  EmeConfigRule GetRobustnessConfigRule(
+      media::EmeMediaType media_type,
+      const std::string& requested_robustness) const override {
+    return requested_robustness.empty() ? EmeConfigRule::SUPPORTED
+                                        : EmeConfigRule::NOT_SUPPORTED;
+  }
+
+  EmeSessionTypeSupport GetPersistentLicenseSessionSupport() const override {
+    return EmeSessionTypeSupport::NOT_SUPPORTED;
+  }
+  EmeSessionTypeSupport GetPersistentReleaseMessageSessionSupport()
+      const override {
+    return EmeSessionTypeSupport::NOT_SUPPORTED;
+  }
+  EmeFeatureSupport GetPersistentStateSupport() const override {
+    return EmeFeatureSupport::ALWAYS_ENABLED;
+  }
+  EmeFeatureSupport GetDistinctiveIdentifierSupport() const override {
+    return EmeFeatureSupport::ALWAYS_ENABLED;
+  }
+
+ private:
+  const std::string name_;
+  const SupportedCodecs supported_codecs_;
+};
+
+}  // namespace
+
 static SupportedKeySystemResponse QueryKeySystemSupport(
     const std::string& key_system) {
   SupportedKeySystemRequest request;
@@ -41,7 +109,8 @@
   return response;
 }
 
-void AddAndroidWidevine(std::vector<KeySystemInfo>* concrete_key_systems) {
+void AddAndroidWidevine(
+    std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) {
   SupportedKeySystemResponse response = QueryKeySystemSupport(
       kWidevineKeySystem);
 
@@ -50,7 +119,7 @@
   // persistence-based features are supported.
 
   if (response.compositing_codecs != media::EME_CODEC_NONE) {
-    AddWidevineWithCodecs(
+    concrete_key_systems->emplace_back(new WidevineKeySystemProperties(
         response.compositing_codecs,           // Regular codecs.
         response.non_compositing_codecs,       // Hardware-secure codecs.
         EmeRobustness::HW_SECURE_CRYPTO,       // Max audio robustness.
@@ -58,8 +127,7 @@
         EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-license.
         EmeSessionTypeSupport::NOT_SUPPORTED,  // persistent-release-message.
         EmeFeatureSupport::ALWAYS_ENABLED,     // Persistent state.
-        EmeFeatureSupport::ALWAYS_ENABLED,     // Distinctive identifier.
-        concrete_key_systems);
+        EmeFeatureSupport::ALWAYS_ENABLED));   // Distinctive identifier.
   } else {
     // It doesn't make sense to support secure codecs but not regular codecs.
     DCHECK(response.non_compositing_codecs == media::EME_CODEC_NONE);
@@ -67,7 +135,7 @@
 }
 
 void AddAndroidPlatformKeySystems(
-    std::vector<KeySystemInfo>* concrete_key_systems) {
+    std::vector<std::unique_ptr<KeySystemProperties>>* concrete_key_systems) {
   std::vector<std::string> key_system_names;
   content::RenderThread::Get()->Send(
       new ChromeViewHostMsg_GetPlatformKeySystemNames(&key_system_names));
@@ -76,30 +144,8 @@
        it != key_system_names.end(); ++it) {
     SupportedKeySystemResponse response = QueryKeySystemSupport(*it);
     if (response.compositing_codecs != media::EME_CODEC_NONE) {
-      KeySystemInfo info;
-      info.key_system = *it;
-      info.supported_codecs = response.compositing_codecs;
-      // Here we assume that support for a container implies support for the
-      // associated initialization data type. KeySystems handles validating
-      // |init_data_type| x |container| pairings.
-      if (response.compositing_codecs & media::EME_CODEC_WEBM_ALL)
-        info.supported_init_data_types |= media::kInitDataTypeMaskWebM;
-#if defined(USE_PROPRIETARY_CODECS)
-      if (response.compositing_codecs & media::EME_CODEC_MP4_ALL)
-        info.supported_init_data_types |= media::kInitDataTypeMaskCenc;
-#endif  // defined(USE_PROPRIETARY_CODECS)
-      info.max_audio_robustness = EmeRobustness::EMPTY;
-      info.max_video_robustness = EmeRobustness::EMPTY;
-      // Assume that platform key systems support no features but can and will
-      // make use of persistence and identifiers.
-      info.persistent_license_support =
-          media::EmeSessionTypeSupport::NOT_SUPPORTED;
-      info.persistent_release_message_support =
-          media::EmeSessionTypeSupport::NOT_SUPPORTED;
-      info.persistent_state_support = media::EmeFeatureSupport::ALWAYS_ENABLED;
-      info.distinctive_identifier_support =
-          media::EmeFeatureSupport::ALWAYS_ENABLED;
-      concrete_key_systems->push_back(info);
+      concrete_key_systems->emplace_back(new AndroidPlatformKeySystemProperties(
+          *it, response.compositing_codecs));
     }
   }
 }
diff --git a/components/cdm/renderer/android_key_systems.h b/components/cdm/renderer/android_key_systems.h
index fb962b15..f5111c7 100644
--- a/components/cdm/renderer/android_key_systems.h
+++ b/components/cdm/renderer/android_key_systems.h
@@ -5,19 +5,22 @@
 #ifndef COMPONENTS_CDM_RENDERER_ANDROID_KEY_SYSTEMS_H_
 #define COMPONENTS_CDM_RENDERER_ANDROID_KEY_SYSTEMS_H_
 
+#include <memory>
 #include <vector>
 
-#include "media/base/key_system_info.h"
+#include "media/base/key_system_properties.h"
 
 namespace cdm {
 
 void AddAndroidWidevine(
-    std::vector<media::KeySystemInfo>* concrete_key_systems);
+    std::vector<std::unique_ptr<media::KeySystemProperties>>*
+        concrete_key_systems);
 
 // Add platform-supported key systems which are not explicitly handled
 // by Chrome.
 void AddAndroidPlatformKeySystems(
-    std::vector<media::KeySystemInfo>* concrete_key_systems);
+    std::vector<std::unique_ptr<media::KeySystemProperties>>*
+        concrete_key_systems);
 
 }  // namespace cdm
 
diff --git a/components/cdm/renderer/widevine_key_system_properties.cc b/components/cdm/renderer/widevine_key_system_properties.cc
new file mode 100644
index 0000000..3a6eab49
--- /dev/null
+++ b/components/cdm/renderer/widevine_key_system_properties.cc
@@ -0,0 +1,176 @@
+// 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/cdm/renderer/widevine_key_system_properties.h"
+
+#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
+
+#if defined(WIDEVINE_CDM_AVAILABLE)
+
+using media::EmeConfigRule;
+using media::EmeFeatureSupport;
+using media::EmeInitDataType;
+using media::EmeMediaType;
+using media::EmeRobustness;
+using media::EmeSessionTypeSupport;
+using media::SupportedCodecs;
+
+namespace cdm {
+namespace {
+
+EmeRobustness ConvertRobustness(const std::string& robustness) {
+  if (robustness.empty())
+    return EmeRobustness::EMPTY;
+  if (robustness == "SW_SECURE_CRYPTO")
+    return EmeRobustness::SW_SECURE_CRYPTO;
+  if (robustness == "SW_SECURE_DECODE")
+    return EmeRobustness::SW_SECURE_DECODE;
+  if (robustness == "HW_SECURE_CRYPTO")
+    return EmeRobustness::HW_SECURE_CRYPTO;
+  if (robustness == "HW_SECURE_DECODE")
+    return EmeRobustness::HW_SECURE_DECODE;
+  if (robustness == "HW_SECURE_ALL")
+    return EmeRobustness::HW_SECURE_ALL;
+  return EmeRobustness::INVALID;
+}
+
+}  // namespace
+
+WidevineKeySystemProperties::WidevineKeySystemProperties(
+    media::SupportedCodecs supported_codecs,
+#if defined(OS_ANDROID)
+    media::SupportedCodecs supported_secure_codecs,
+#endif  // defined(OS_ANDROID)
+    media::EmeRobustness max_audio_robustness,
+    media::EmeRobustness max_video_robustness,
+    media::EmeSessionTypeSupport persistent_license_support,
+    media::EmeSessionTypeSupport persistent_release_message_support,
+    media::EmeFeatureSupport persistent_state_support,
+    media::EmeFeatureSupport distinctive_identifier_support)
+    : supported_codecs_(supported_codecs),
+#if defined(OS_ANDROID)
+      supported_secure_codecs_(supported_secure_codecs),
+#endif  // defined(OS_ANDROID)
+      max_audio_robustness_(max_audio_robustness),
+      max_video_robustness_(max_video_robustness),
+      persistent_license_support_(persistent_license_support),
+      persistent_release_message_support_(persistent_release_message_support),
+      persistent_state_support_(persistent_state_support),
+      distinctive_identifier_support_(distinctive_identifier_support) {
+}
+
+std::string WidevineKeySystemProperties::GetKeySystemName() const {
+  return kWidevineKeySystem;
+}
+
+bool WidevineKeySystemProperties::IsSupportedInitDataType(
+    EmeInitDataType init_data_type) const {
+  // Here we assume that support for a container imples support for the
+  // associated initialization data type. KeySystems handles validating
+  // |init_data_type| x |container| pairings.
+  if (init_data_type == EmeInitDataType::WEBM)
+    return (supported_codecs_ & media::EME_CODEC_WEBM_ALL) != 0;
+#if defined(USE_PROPRIETARY_CODECS)
+  if (init_data_type == EmeInitDataType::CENC)
+    return (supported_codecs_ & media::EME_CODEC_MP4_ALL) != 0;
+#endif  // defined(USE_PROPRIETARY_CODECS)
+
+  return false;
+}
+
+SupportedCodecs WidevineKeySystemProperties::GetSupportedCodecs() const {
+  return supported_codecs_;
+}
+
+#if defined(OS_ANDROID)
+SupportedCodecs WidevineKeySystemProperties::GetSupportedSecureCodecs() const {
+  return supported_secure_codecs_;
+}
+#endif
+
+EmeConfigRule WidevineKeySystemProperties::GetRobustnessConfigRule(
+    EmeMediaType media_type,
+    const std::string& requested_robustness) const {
+  EmeRobustness robustness = ConvertRobustness(requested_robustness);
+  if (robustness == EmeRobustness::INVALID)
+    return EmeConfigRule::NOT_SUPPORTED;
+
+  EmeRobustness max_robustness = EmeRobustness::INVALID;
+  switch (media_type) {
+    case EmeMediaType::AUDIO:
+      max_robustness = max_audio_robustness_;
+      break;
+    case EmeMediaType::VIDEO:
+      max_robustness = max_video_robustness_;
+      break;
+  }
+
+  // We can compare robustness levels whenever they are not HW_SECURE_CRYPTO
+  // and SW_SECURE_DECODE in some order. If they are exactly those two then the
+  // robustness requirement is not supported.
+  if ((max_robustness == EmeRobustness::HW_SECURE_CRYPTO &&
+       robustness == EmeRobustness::SW_SECURE_DECODE) ||
+      (max_robustness == EmeRobustness::SW_SECURE_DECODE &&
+       robustness == EmeRobustness::HW_SECURE_CRYPTO) ||
+      robustness > max_robustness) {
+    return EmeConfigRule::NOT_SUPPORTED;
+  }
+
+#if defined(OS_CHROMEOS)
+  // TODO(ddorwin): Remove this once we have confirmed it is not necessary.
+  // See https://crbug.com/482277
+  if (robustness == EmeRobustness::EMPTY)
+    return EmeConfigRule::SUPPORTED;
+
+  // Hardware security requires remote attestation.
+  if (robustness >= EmeRobustness::HW_SECURE_CRYPTO)
+    return EmeConfigRule::IDENTIFIER_REQUIRED;
+
+  // For video, recommend remote attestation if HW_SECURE_ALL is available,
+  // because it enables hardware accelerated decoding.
+  // TODO(sandersd): Only do this when hardware accelerated decoding is
+  // available for the requested codecs.
+  if (media_type == EmeMediaType::VIDEO &&
+      max_robustness == EmeRobustness::HW_SECURE_ALL) {
+    return EmeConfigRule::IDENTIFIER_RECOMMENDED;
+  }
+#elif defined(OS_ANDROID)
+  // Require hardware secure codecs when SW_SECURE_DECODE or above is specified.
+  if (robustness >= EmeRobustness::SW_SECURE_DECODE) {
+    return EmeConfigRule::HW_SECURE_CODECS_REQUIRED;
+  }
+#endif  // defined(OS_CHROMEOS)
+
+  return EmeConfigRule::SUPPORTED;
+}
+
+EmeSessionTypeSupport
+WidevineKeySystemProperties::GetPersistentLicenseSessionSupport() const {
+  return persistent_license_support_;
+}
+
+EmeSessionTypeSupport
+WidevineKeySystemProperties::GetPersistentReleaseMessageSessionSupport() const {
+  return persistent_release_message_support_;
+}
+
+EmeFeatureSupport WidevineKeySystemProperties::GetPersistentStateSupport()
+    const {
+  return persistent_state_support_;
+}
+
+EmeFeatureSupport WidevineKeySystemProperties::GetDistinctiveIdentifierSupport()
+    const {
+  return distinctive_identifier_support_;
+}
+
+#if defined(ENABLE_PEPPER_CDMS)
+std::string WidevineKeySystemProperties::GetPepperType() const {
+  return kWidevineCdmPluginMimeType;
+}
+#endif
+
+}  // namespace cdm
+
+#endif  // WIDEVINE_CDM_AVAILABLE
diff --git a/components/cdm/renderer/widevine_key_system_properties.h b/components/cdm/renderer/widevine_key_system_properties.h
new file mode 100644
index 0000000..c936c62
--- /dev/null
+++ b/components/cdm/renderer/widevine_key_system_properties.h
@@ -0,0 +1,66 @@
+// 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_CDM_RENDERER_WIDEVINE_KEY_SYSTEM_PROPERTIES_H_
+#define COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEM_PROPERTIES_H_
+
+#include "build/build_config.h"
+#include "media/base/key_system_properties.h"
+
+namespace cdm {
+
+// Implementation of KeySystemProperties for Widevine key system.
+class WidevineKeySystemProperties : public media::KeySystemProperties {
+ public:
+  WidevineKeySystemProperties(
+      media::SupportedCodecs supported_codecs,
+#if defined(OS_ANDROID)
+      media::SupportedCodecs supported_secure_codecs,
+#endif  // defined(OS_ANDROID)
+      media::EmeRobustness max_audio_robustness,
+      media::EmeRobustness max_video_robustness,
+      media::EmeSessionTypeSupport persistent_license_support,
+      media::EmeSessionTypeSupport persistent_release_message_support,
+      media::EmeFeatureSupport persistent_state_support,
+      media::EmeFeatureSupport distinctive_identifier_support);
+
+  std::string GetKeySystemName() const override;
+  bool IsSupportedInitDataType(
+      media::EmeInitDataType init_data_type) const override;
+
+  media::SupportedCodecs GetSupportedCodecs() const override;
+#if defined(OS_ANDROID)
+  media::SupportedCodecs GetSupportedSecureCodecs() const override;
+#endif
+
+  media::EmeConfigRule GetRobustnessConfigRule(
+      media::EmeMediaType media_type,
+      const std::string& requested_robustness) const override;
+  media::EmeSessionTypeSupport GetPersistentLicenseSessionSupport()
+      const override;
+  media::EmeSessionTypeSupport GetPersistentReleaseMessageSessionSupport()
+      const override;
+  media::EmeFeatureSupport GetPersistentStateSupport() const override;
+  media::EmeFeatureSupport GetDistinctiveIdentifierSupport() const override;
+
+#if defined(ENABLE_PEPPER_CDMS)
+  std::string GetPepperType() const override;
+#endif
+
+ private:
+  const media::SupportedCodecs supported_codecs_;
+#if defined(OS_ANDROID)
+  const media::SupportedCodecs supported_secure_codecs_;
+#endif  // defined(OS_ANDROID)
+  const media::EmeRobustness max_audio_robustness_;
+  const media::EmeRobustness max_video_robustness_;
+  const media::EmeSessionTypeSupport persistent_license_support_;
+  const media::EmeSessionTypeSupport persistent_release_message_support_;
+  const media::EmeFeatureSupport persistent_state_support_;
+  const media::EmeFeatureSupport distinctive_identifier_support_;
+};
+
+}  // namespace cdm
+
+#endif  // COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEM_PROPERTIES_H_
diff --git a/components/cdm/renderer/widevine_key_systems.cc b/components/cdm/renderer/widevine_key_systems.cc
deleted file mode 100644
index 5120d8b..0000000
--- a/components/cdm/renderer/widevine_key_systems.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/cdm/renderer/widevine_key_systems.h"
-
-#include <stddef.h>
-
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "build/build_config.h"
-#include "media/base/eme_constants.h"
-
-#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
-
-#if defined(WIDEVINE_CDM_AVAILABLE)
-
-using media::KeySystemInfo;
-using media::SupportedCodecs;
-
-namespace cdm {
-
-void AddWidevineWithCodecs(
-    SupportedCodecs supported_codecs,
-#if defined(OS_ANDROID)
-    SupportedCodecs supported_secure_codecs,
-#endif  // defined(OS_ANDROID)
-    media::EmeRobustness max_audio_robustness,
-    media::EmeRobustness max_video_robustness,
-    media::EmeSessionTypeSupport persistent_license_support,
-    media::EmeSessionTypeSupport persistent_release_message_support,
-    media::EmeFeatureSupport persistent_state_support,
-    media::EmeFeatureSupport distinctive_identifier_support,
-    std::vector<KeySystemInfo>* concrete_key_systems) {
-  KeySystemInfo info;
-  info.key_system = kWidevineKeySystem;
-
-  // TODO(xhwang): A container or an initDataType may be supported even though
-  // there are no codecs supported in that container. Fix this when we support
-  // initDataType.
-  info.supported_codecs = supported_codecs;
-#if defined(OS_ANDROID)
-  info.supported_secure_codecs = supported_secure_codecs;
-#endif  // defined(OS_ANDROID)
-
-  // Here we assume that support for a container imples support for the
-  // associated initialization data type. KeySystems handles validating
-  // |init_data_type| x |container| pairings.
-  if (supported_codecs & media::EME_CODEC_WEBM_ALL)
-    info.supported_init_data_types |= media::kInitDataTypeMaskWebM;
-#if defined(USE_PROPRIETARY_CODECS)
-  if (supported_codecs & media::EME_CODEC_MP4_ALL)
-    info.supported_init_data_types |= media::kInitDataTypeMaskCenc;
-#endif  // defined(USE_PROPRIETARY_CODECS)
-
-  info.max_audio_robustness = max_audio_robustness;
-  info.max_video_robustness = max_video_robustness;
-  info.persistent_license_support = persistent_license_support;
-  info.persistent_release_message_support = persistent_release_message_support;
-  info.persistent_state_support = persistent_state_support;
-  info.distinctive_identifier_support = distinctive_identifier_support;
-
-#if defined(ENABLE_PEPPER_CDMS)
-  info.pepper_type = kWidevineCdmPluginMimeType;
-#endif  // defined(ENABLE_PEPPER_CDMS)
-
-  concrete_key_systems->push_back(info);
-}
-
-}  // namespace cdm
-
-#endif  // defined(WIDEVINE_CDM_AVAILABLE)
diff --git a/components/cdm/renderer/widevine_key_systems.h b/components/cdm/renderer/widevine_key_systems.h
deleted file mode 100644
index e50f7e6..0000000
--- a/components/cdm/renderer/widevine_key_systems.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEMS_H_
-#define COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEMS_H_
-
-#include <vector>
-
-#include "build/build_config.h"
-#include "media/base/key_system_info.h"
-
-namespace cdm {
-
-void AddWidevineWithCodecs(
-    media::SupportedCodecs supported_codecs,
-#if defined(OS_ANDROID)
-    media::SupportedCodecs supported_secure_codecs,
-#endif  // defined(OS_ANDROID)
-    media::EmeRobustness max_audio_robustness,
-    media::EmeRobustness max_video_robustness,
-    media::EmeSessionTypeSupport persistent_license_support,
-    media::EmeSessionTypeSupport persistent_release_message_support,
-    media::EmeFeatureSupport persistent_state_support,
-    media::EmeFeatureSupport distinctive_identifier_support,
-    std::vector<media::KeySystemInfo>* concrete_key_systems);
-
-}  // namespace cdm
-
-#endif  // COMPONENTS_CDM_RENDERER_WIDEVINE_KEY_SYSTEMS_H_
diff --git a/components/component_updater/component_updater_paths.cc b/components/component_updater/component_updater_paths.cc
index 697d8def..510725b 100644
--- a/components/component_updater/component_updater_paths.cc
+++ b/components/component_updater/component_updater_paths.cc
@@ -50,6 +50,9 @@
     case DIR_CERT_TRANS_TREE_STATES:
       cur = cur.Append(FILE_PATH_LITERAL("CertificateTransparency"));
       break;
+    case DIR_ORIGIN_TRIAL_KEYS:
+      cur = cur.Append(FILE_PATH_LITERAL("OriginTrials"));
+      break;
     default:
       return false;
   }
diff --git a/components/component_updater/component_updater_paths.h b/components/component_updater/component_updater_paths.h
index 994353ce..23f7b53 100644
--- a/components/component_updater/component_updater_paths.h
+++ b/components/component_updater/component_updater_paths.h
@@ -20,6 +20,8 @@
   DIR_COMPONENT_EV_WHITELIST,       // EV whitelist for CT files.
   DIR_SUPERVISED_USER_WHITELISTS,   // Supervised user whitelists.
   DIR_CERT_TRANS_TREE_STATES,       // Signed Tree Heads for CT logs.
+  DIR_ORIGIN_TRIAL_KEYS,            // Public keys and revoked tokens for origin
+                                    // trials.
   PATH_END
 };
 
diff --git a/components/components.gyp b/components/components.gyp
index 2e19833..0348270f 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -41,6 +41,7 @@
     'guest_view.gypi',
     'handoff.gypi',
     'history.gypi',
+    'image_fetcher.gypi',
     'infobars.gypi',
     'invalidation.gypi',
     'json_schema.gypi',
@@ -55,6 +56,7 @@
     'net_log.gypi',
     'network_time.gypi',
     'ntp_snippets.gypi',
+    'ntp_tiles.gypi',
     'offline_pages.gypi',
     'omnibox.gypi',
     'onc.gypi',
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 686d38be..ae48eb20 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -1095,6 +1095,7 @@
         'components.gyp:history_core_browser',
         'components.gyp:history_core_common',
         'components.gyp:history_core_test_support',
+        'components.gyp:image_fetcher',
         'components.gyp:instance_id_test_support',
         'components.gyp:invalidation_impl',
         'components.gyp:invalidation_test_support',
diff --git a/components/cronet.gypi b/components/cronet.gypi
index 1f1bb39..228057b4 100644
--- a/components/cronet.gypi
+++ b/components/cronet.gypi
@@ -43,7 +43,7 @@
           'target_name': 'network_quality_observations_java',
           'type': 'none',
           'variables': {
-            'source_file': '../net/base/network_quality_estimator.h',
+            'source_file': '../net/nqe/network_quality_estimator.h',
           },
           'includes': [ '../build/android/java_cpp_enum.gypi' ],
         },
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index a6d42bd..f59c54e 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -43,7 +43,7 @@
 
 java_cpp_enum("network_quality_observations_java") {
   sources = [
-    "//net/base/network_quality_estimator.h",
+    "//net/nqe/network_quality_estimator.h",
   ]
 }
 
diff --git a/components/cronet/android/cronet_test_instrumentation_apk.isolate b/components/cronet/android/cronet_test_instrumentation_apk.isolate
index be10039..984c8fb6 100644
--- a/components/cronet/android/cronet_test_instrumentation_apk.isolate
+++ b/components/cronet/android/cronet_test_instrumentation_apk.isolate
@@ -3,16 +3,12 @@
 # found in the LICENSE file.
 
 {
-  'conditions': [
-    ['OS=="android"', {
-      'variables': {
-        'files': [
-          '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.crt',
-          '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.key',
-          '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.key.pkcs8',
-          '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.key.sct',
-        ],
-      },
-    }],
-  ],
+  'variables': {
+    'files': [
+      '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.crt',
+      '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.key',
+      '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.key.pkcs8',
+      '<(DEPTH)/net/data/ssl/certificates/quic_test.example.com.key.sct',
+    ],
+  },
 }
diff --git a/components/cronet/android/cronet_url_request_context_adapter.cc b/components/cronet/android/cronet_url_request_context_adapter.cc
index e8eae51d..cb760e7 100644
--- a/components/cronet/android/cronet_url_request_context_adapter.cc
+++ b/components/cronet/android/cronet_url_request_context_adapter.cc
@@ -36,7 +36,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/prefs/pref_service_factory.h"
 #include "jni/CronetUrlRequestContext_jni.h"
-#include "net/base/external_estimate_provider.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_delegate_impl.h"
@@ -46,6 +45,7 @@
 #include "net/http/http_auth_handler_factory.h"
 #include "net/http/http_server_properties_manager.h"
 #include "net/log/write_to_file_net_log_observer.h"
+#include "net/nqe/external_estimate_provider.h"
 #include "net/proxy/proxy_config_service_android.h"
 #include "net/proxy/proxy_service.h"
 #include "net/sdch/sdch_owner.h"
diff --git a/components/cronet/android/cronet_url_request_context_adapter.h b/components/cronet/android/cronet_url_request_context_adapter.h
index 582ae3ab..7e2a3e14 100644
--- a/components/cronet/android/cronet_url_request_context_adapter.h
+++ b/components/cronet/android/cronet_url_request_context_adapter.h
@@ -18,7 +18,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread.h"
 #include "components/prefs/json_pref_store.h"
-#include "net/base/network_quality_estimator.h"
+#include "net/nqe/network_quality_estimator.h"
 
 class PrefService;
 
diff --git a/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java b/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java
index 3522c6b..0ce0b5430 100644
--- a/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java
+++ b/components/cronet/android/java/src/org/chromium/net/CronetLibraryLoader.java
@@ -34,9 +34,7 @@
             if (sInitTaskPosted) {
                 return;
             }
-            ContextUtils.initApplicationContext(context.getApplicationContext());
             builder.loadLibrary();
-            ContextUtils.initApplicationContextForNative();
             if (!Version.CRONET_VERSION.equals(nativeGetCronetVersion())) {
                 throw new RuntimeException(String.format(
                       "Expected Cronet version number %s, "
@@ -46,9 +44,9 @@
             }
             Log.i(TAG, "Cronet version: %s, arch: %s",
                     Version.CRONET_VERSION, System.getProperty("os.arch"));
+            ContextUtils.initApplicationContext(context.getApplicationContext());
             // Init native Chromium CronetEngine on Main UI thread.
             Runnable task = new Runnable() {
-                @Override
                 public void run() {
                     initOnMainThread(context);
                 }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
index 0e220e26..5dba044 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
@@ -43,7 +43,6 @@
                                         .put("connection_options", "PACE,IW10,FOO,DEADBEEF")
                                         .put("host_whitelist", "test.example.com")
                                         .put("max_server_configs_stored_in_properties", 2)
-                                        .put("delay_tcp_race", true)
                                         .put("max_number_of_lossy_connections", 10)
                                         .put("packet_loss_threshold", 0.5)
                                         .put("idle_connection_timeout_seconds", 300)
diff --git a/components/cronet/tools/cr_cronet.py b/components/cronet/tools/cr_cronet.py
index 690851e..c852077 100755
--- a/components/cronet/tools/cr_cronet.py
+++ b/components/cronet/tools/cr_cronet.py
@@ -62,6 +62,8 @@
                                'stack',
                                'debug',
                                'build-debug'])
+  parser.add_argument('-d', '--out_dir', action='store',
+                      help='name of the build directory')
   parser.add_argument('-i', '--iphoneos', action='store_true',
                       help='build for physical iphone')
   parser.add_argument('-r', '--release', action='store_true',
@@ -92,13 +94,17 @@
       'use_errorprone_java_compiler=true use_platform_icu_alternatives=true '+ \
       'disable_brotli_filter=true'
 
-  out_dir = 'out/Debug' + out_dir_suffix
-  release_arg = ''
   extra_options = ' '.join(extra_options_list)
   if options.release:
     out_dir = 'out/Release' + out_dir_suffix
     release_arg = ' --release'
     gn_args += ' is_debug=false '
+  else:
+    out_dir = 'out/Debug' + out_dir_suffix
+    release_arg = ''
+
+  if options.out_dir:
+    out_dir = options.out_dir
 
   if (options.command=='gyp'):
     return run (gyp_defines + ' gclient runhooks')
diff --git a/components/cronet/url_request_context_config.cc b/components/cronet/url_request_context_config.cc
index 570173b..dae813d 100644
--- a/components/cronet/url_request_context_config.cc
+++ b/components/cronet/url_request_context_config.cc
@@ -34,7 +34,6 @@
     "store_server_configs_in_properties";
 const char kQuicMaxServerConfigsStoredInProperties[] =
     "max_server_configs_stored_in_properties";
-const char kQuicDelayTcpRace[] = "delay_tcp_race";
 const char kQuicMaxNumberOfLossyConnections[] =
     "max_number_of_lossy_connections";
 const char kQuicPacketLossThreshold[] = "packet_loss_threshold";
@@ -109,11 +108,6 @@
           static_cast<size_t>(quic_max_server_configs_stored_in_properties));
     }
 
-    bool quic_delay_tcp_race = false;
-    if (quic_args->GetBoolean(kQuicDelayTcpRace, &quic_delay_tcp_race)) {
-      context_builder->set_quic_delay_tcp_race(quic_delay_tcp_race);
-    }
-
     int quic_max_number_of_lossy_connections = 0;
     if (quic_args->GetInteger(kQuicMaxNumberOfLossyConnections,
                               &quic_max_number_of_lossy_connections)) {
diff --git a/components/cronet/url_request_context_config_unittest.cc b/components/cronet/url_request_context_config_unittest.cc
index c129a8fe..cd114af 100644
--- a/components/cronet/url_request_context_config_unittest.cc
+++ b/components/cronet/url_request_context_config_unittest.cc
@@ -39,7 +39,6 @@
       "fake agent",
       // JSON encoded experimental options.
       "{\"QUIC\":{\"max_server_configs_stored_in_properties\":2,"
-      "\"delay_tcp_race\":true,"
       "\"max_number_of_lossy_connections\":10,"
       "\"prefer_aes\":true,"
       "\"user_agent_id\":\"Custom QUIC UAID\","
@@ -81,9 +80,6 @@
   // Check max_server_configs_stored_in_properties.
   EXPECT_EQ(2u, params->quic_max_server_configs_stored_in_properties);
 
-  // Check delay_tcp_race.
-  EXPECT_TRUE(params->quic_delay_tcp_race);
-
   // Check prefer_aes.
   EXPECT_TRUE(params->quic_prefer_aes);
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index 2c655ca..581006c7 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -27,7 +27,7 @@
 #include "net/base/host_port_pair.h"
 #include "net/base/load_flags.h"
 #include "net/base/network_change_notifier.h"
-#include "net/base/network_quality_estimator.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_server.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_fetcher_delegate.h"
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index 37d4750..51ef41f 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -33,11 +33,11 @@
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
 #include "components/variations/variations_associated_data.h"
-#include "net/base/external_estimate_provider.h"
 #include "net/base/load_flags.h"
-#include "net/base/network_quality_estimator.h"
 #include "net/http/http_status_code.h"
 #include "net/log/test_net_log.h"
+#include "net/nqe/external_estimate_provider.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_server.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_request_test_util.h"
diff --git a/components/dom_distiller.gypi b/components/dom_distiller.gypi
index 8d0bc61..decd4220 100644
--- a/components/dom_distiller.gypi
+++ b/components/dom_distiller.gypi
@@ -166,6 +166,7 @@
             '../net/net.gyp:net',
             '../skia/skia.gyp:skia',
             '../sync/sync.gyp:sync',
+            '../ui/display/display.gyp:display',
             '../ui/gfx/gfx.gyp:gfx',
             '../url/url.gyp:url_lib',
             'components_resources.gyp:components_resources',
diff --git a/components/dom_distiller/content/browser/BUILD.gn b/components/dom_distiller/content/browser/BUILD.gn
index 2494342..e306568f 100644
--- a/components/dom_distiller/content/browser/BUILD.gn
+++ b/components/dom_distiller/content/browser/BUILD.gn
@@ -41,6 +41,7 @@
     "//sync",
     "//third_party/WebKit/public:blink_headers",
     "//ui/base",
+    "//ui/display",
     "//ui/gfx",
     "//url",
   ]
diff --git a/components/dom_distiller/content/browser/DEPS b/components/dom_distiller/content/browser/DEPS
index ef8ad28..f88ee87 100644
--- a/components/dom_distiller/content/browser/DEPS
+++ b/components/dom_distiller/content/browser/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "+mojo/public",
+  "+ui/display",
 ]
diff --git a/components/dom_distiller/content/browser/distiller_page_web_contents.cc b/components/dom_distiller/content/browser/distiller_page_web_contents.cc
index 7f1c7f9..156f0e3 100644
--- a/components/dom_distiller/content/browser/distiller_page_web_contents.cc
+++ b/components/dom_distiller/content/browser/distiller_page_web_contents.cc
@@ -21,7 +21,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 #include "url/gurl.h"
 
 namespace dom_distiller {
@@ -144,7 +144,7 @@
   // in the executed domdistiller.js won't be 0.
   if (size.IsEmpty()) {
     DVLOG(1) << "Using fullscreen as default RenderView size";
-    size = gfx::Screen::GetScreen()->GetPrimaryDisplay().size();
+    size = display::Screen::GetScreen()->GetPrimaryDisplay().size();
   }
   return size;
 }
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc
index a087772..3a84ddb 100644
--- a/components/error_page/common/localized_error.cc
+++ b/components/error_page/common/localized_error.cc
@@ -59,7 +59,7 @@
   SUGGEST_DNS_CONFIG                        = 1 << 2,
   SUGGEST_FIREWALL_CONFIG                   = 1 << 3,
   SUGGEST_PROXY_CONFIG                      = 1 << 4,
-  SUGGEST_DISABLE_EXTENSION                 = 1 << 5,
+  SUGGEST_DISABLE_EXTENSION_STANDALONE      = 1 << 5,
   SUGGEST_LEARNMORE                         = 1 << 6,
   // Unprefixed suggestion which occurs in a list.
   SUGGEST_CONTACT_ADMINISTRATOR             = 1 << 7,
@@ -217,7 +217,7 @@
    IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING,
    IDS_ERRORPAGES_SUMMARY_TOO_MANY_REDIRECTS,
    IDS_ERRORPAGES_DETAILS_TOO_MANY_REDIRECTS,
-   SUGGEST_RELOAD | SUGGEST_LEARNMORE,
+   SUGGEST_RELOAD | SUGGEST_LEARNMORE_STANDALONE,
   },
   {net::ERR_EMPTY_RESPONSE,
    IDS_ERRORPAGES_TITLE_LOAD_FAILED,
@@ -266,7 +266,7 @@
    IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION,
    IDS_ERRORPAGES_SUMMARY_INVALID_RESPONSE,
    IDS_ERRORPAGES_DETAILS_SSL_PROTOCOL_ERROR,
-   SUGGEST_RELOAD | SUGGEST_LEARNMORE,
+   SUGGEST_RELOAD | SUGGEST_LEARNMORE_STANDALONE,
   },
   {net::ERR_BAD_SSL_CLIENT_AUTH_CERT,
    IDS_ERRORPAGES_TITLE_LOAD_FAILED,
@@ -294,14 +294,14 @@
    IDS_ERRORPAGES_HEADING_NOT_AVAILABLE,
    IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE,
    IDS_ERRORPAGES_DETAILS_TEMPORARILY_THROTTLED,
-   SUGGEST_DISABLE_EXTENSION,
+   SUGGEST_DISABLE_EXTENSION_STANDALONE,
   },
   {net::ERR_BLOCKED_BY_CLIENT,
    IDS_ERRORPAGES_TITLE_BLOCKED,
    IDS_ERRORPAGES_HEADING_BLOCKED,
    IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION,
    IDS_ERRORPAGES_DETAILS_BLOCKED_BY_EXTENSION,
-   SUGGEST_RELOAD | SUGGEST_DISABLE_EXTENSION,
+   SUGGEST_RELOAD | SUGGEST_DISABLE_EXTENSION_STANDALONE,
   },
   {net::ERR_NETWORK_CHANGED,
    IDS_ERRORPAGES_TITLE_LOAD_FAILED,
@@ -623,6 +623,8 @@
 
 // Creates a list of suggestions that a user may try to resolve a particular
 // network error. Appears above the fold underneath heading and intro paragraph.
+// Note that the SUGGEST_RELOAD suggestion isn't shown in the list, only as a
+// reload button.
 void GetSuggestionsSummaryList(int error_code,
                                base::DictionaryValue* error_strings,
                                int suggestions,
@@ -660,11 +662,17 @@
 
   if (suggestions & SUGGEST_LEARNMORE_STANDALONE) {
     DCHECK(suggestions_summary_list->empty());
-    DCHECK(!(suggestions & ~SUGGEST_LEARNMORE_STANDALONE));
     AddLinkedSuggestionToList(error_code, locale, suggestions_summary_list);
     return;
   }
 
+  if (suggestions & SUGGEST_DISABLE_EXTENSION_STANDALONE) {
+    DCHECK(suggestions_summary_list->empty());
+    AddSingleEntryDictionaryToList(suggestions_summary_list, "summary",
+        IDS_ERRORPAGES_SUGGESTION_DISABLE_EXTENSION_SUMMARY, false);
+    return;
+  }
+
   if (suggestions & SUGGEST_CHECK_CONNECTION) {
     AddSingleEntryDictionaryToList(suggestions_summary_list, "summary",
         IDS_ERRORPAGES_SUGGESTION_CHECK_CONNECTION_SUMMARY, false);
@@ -709,30 +717,16 @@
         IDS_ERRORPAGES_SUGGESTION_CHECKING_SIGNAL_SUMMARY, false);
 #else
     AddSingleEntryDictionaryToList(suggestions_summary_list, "summary",
-        IDS_ERRORPAGES_SUGGESTION_CHECK_CABLES_SUMMARY, false);
-    AddSingleEntryDictionaryToList(suggestions_summary_list, "summary",
-        IDS_ERRORPAGES_SUGGESTION_RESET_HARDWARE_SUMMARY, false);
+        IDS_ERRORPAGES_SUGGESTION_CHECK_HARDWARE_SUMMARY, false);
     AddSingleEntryDictionaryToList(suggestions_summary_list, "summary",
         IDS_ERRORPAGES_SUGGESTION_CHECK_WIFI_SUMMARY, false);
 #endif
   }
 
-  if (suggestions & SUGGEST_DISABLE_EXTENSION) {
-    AddSingleEntryDictionaryToList(suggestions_summary_list, "summary",
-        IDS_ERRORPAGES_SUGGESTION_DISABLE_EXTENSION_SUMMARY, false);
-  }
-
   if (suggestions & SUGGEST_LEARNMORE) {
     AddLinkedSuggestionToList(error_code, locale, suggestions_summary_list);
   }
 
-  // Only add a explicit reload suggestion if there are other suggestions.
-  // Otherwise rely on the reload button being used.
-  if (!suggestions_summary_list->empty() && (suggestions & SUGGEST_RELOAD)) {
-    AddSingleEntryDictionaryToList(suggestions_summary_list, "summary",
-        IDS_ERRORPAGES_SUGGESTION_RELOAD_SUMMARY, true);
-  }
-
   // Add list prefix header.
   error_strings->SetString("suggestionsSummaryListHeader",
       l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_LIST_HEADER));
diff --git a/components/error_page_strings.grdp b/components/error_page_strings.grdp
index 50ed4f8..1d7ae286 100644
--- a/components/error_page_strings.grdp
+++ b/components/error_page_strings.grdp
@@ -500,8 +500,8 @@
   <message name="IDS_ERRORPAGES_SUGGESTION_LEARNMORE_SUMMARY" desc="When a webpage fails to load, we provide a link to the help center to learn more about the failure.">
     <ph name="BEGIN_LINK">&lt;a jsvalues="href:learnMoreUrl"&gt;</ph>Learn more<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph> about this problem.
   </message>
-  <message name="IDS_ERRORPAGES_SUGGESTION_CLEAR_COOKIES_SUMMARY" desc="The message displayed in a list of suggestions following a network error suggesting the user could try clearing their cookies. We also provide a link to the help center to learn more about the failure. The suggestions list is prefixed with 'Try:'.">
-    <ph name="BEGIN_LINK">&lt;a jsvalues="href:learnMoreUrl"&gt;</ph>Clearing your cookies<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>
+  <message name="IDS_ERRORPAGES_SUGGESTION_CLEAR_COOKIES_SUMMARY" desc="The message displayed following a network error suggesting the user could try clearing their cookies. We also provide a link to the help center to learn more about the failure.">
+    <ph name="BEGIN_LINK">&lt;a jsvalues="href:learnMoreUrl"&gt;</ph>Try clearing your cookies<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex>.</ph>
   </message>
   <if expr="is_ios or is_android">
     <message name="IDS_ERRORPAGES_SUGGESTION_TURN_OFF_AIRPLANE_SUMMARY" desc="When a page fails to load and the device is offline, we provide a suggestion that the user try turning off airplane mode. The suggestions list is prefixed with 'Try:'.">
@@ -514,11 +514,8 @@
       Checking the signal in your area
     </message>
   </if>
-  <message name="IDS_ERRORPAGES_SUGGESTION_CHECK_CABLES_SUMMARY" desc="The message displayed in a list of suggestions following a network error suggesting to check the network cables or router. The suggestions list is prefixed with 'Try:'.">
-    Checking the network cable or router
-  </message>
-  <message name="IDS_ERRORPAGES_SUGGESTION_RESET_HARDWARE_SUMMARY" desc="The message displayed in a list of suggestions following a network error suggesting to the reset the modem or router. The suggestions list is prefixed with 'Try:'.">
-    Resetting the modem or router
+  <message name="IDS_ERRORPAGES_SUGGESTION_CHECK_HARDWARE_SUMMARY" desc="The message displayed in a list of suggestions following a network error suggesting to check the network cables, modem, and router. The suggestions list is prefixed with 'Try:'.">
+    Checking the network cables, modem, and router
   </message>
   <message name="IDS_ERRORPAGES_SUGGESTION_CHECK_WIFI_SUMMARY" desc="The message displayed in a list of suggestions following a network error suggesting to the user to reconnect to Wi-Fi. The suggestions list is prefixed with 'Try:'.">
     Reconnecting to Wi-Fi
@@ -529,11 +526,8 @@
   <message name="IDS_ERRORPAGES_SUGGESTION_COMPLETE_SETUP_SUMMARY" desc="The message displayed asking the user to sign out and complete their device setup.">
     Sign out and complete setup
   </message>
-  <message name="IDS_ERRORPAGES_SUGGESTION_DISABLE_EXTENSION_SUMMARY" desc="When a page fails to load, we provide a suggestion that the user try disabling the extension that's blocking it. The suggestions list is prefixed with 'Try:'.">
-    Disabling your extensions
-  </message>
-  <message name="IDS_ERRORPAGES_SUGGESTION_RELOAD_SUMMARY" desc="The message displayed in a list of suggestions following a network error, suggesting the user should try reload the page. The suggestions list is prefixed with 'Try:'.">
-    Reloading the page
+  <message name="IDS_ERRORPAGES_SUGGESTION_DISABLE_EXTENSION_SUMMARY" desc="When a page fails to load, we provide a suggestion that the user try disabling the extension that's blocking it.">
+    Try disabling your extensions.
   </message>
   <message name="IDS_ERRORPAGES_SUGGESTION_GOOGLE_SEARCH_SUMMARY" desc="When a page fails to load, sometimes we suggest a specific Google search.">
     Search Google for <ph name="LINK">&lt;a jsvalues="href:searchUrl;.jstdata:$this" onclick="linkClicked(this.jstdata)" jscontent="searchTerms" id="search-link"&gt;<ex>Example search terms</ex>&lt;/a&gt;</ph>
diff --git a/components/exo.gypi b/components/exo.gypi
index 2fdd52f3..37ccc7d 100644
--- a/components/exo.gypi
+++ b/components/exo.gypi
@@ -75,6 +75,7 @@
             '../third_party/wayland-protocols/wayland-protocols.gyp:xdg_shell_protocol',
             '../third_party/wayland/wayland.gyp:wayland_server',
             '../ui/events/events.gyp:dom_keycode_converter',
+            '../ui/display/display.gyp:display',
             '../ui/events/events.gyp:events_base',
             '../ui/views/views.gyp:views',
             'exo',
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index fe88b96..5ad216ab 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -21,7 +21,6 @@
 
 #include "ash/display/display_info.h"
 #include "ash/display/display_manager.h"
-#include "ash/display/screen_ash.h"
 #include "ash/shell.h"
 #include "base/bind.h"
 #include "base/cancelable_callback.h"
@@ -47,8 +46,9 @@
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/aura/window_property.h"
 #include "ui/base/hit_test.h"
+#include "ui/display/display_observer.h"
+#include "ui/display/screen.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
-#include "ui/gfx/display_observer.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_observer.h"
 
@@ -939,37 +939,37 @@
 ////////////////////////////////////////////////////////////////////////////////
 // wl_output_interface:
 
-wl_output_transform OutputTransform(gfx::Display::Rotation rotation) {
+wl_output_transform OutputTransform(display::Display::Rotation rotation) {
   switch (rotation) {
-    case gfx::Display::ROTATE_0:
+    case display::Display::ROTATE_0:
       return WL_OUTPUT_TRANSFORM_NORMAL;
-    case gfx::Display::ROTATE_90:
+    case display::Display::ROTATE_90:
       return WL_OUTPUT_TRANSFORM_90;
-    case gfx::Display::ROTATE_180:
+    case display::Display::ROTATE_180:
       return WL_OUTPUT_TRANSFORM_180;
-    case gfx::Display::ROTATE_270:
+    case display::Display::ROTATE_270:
       return WL_OUTPUT_TRANSFORM_270;
   }
   NOTREACHED();
   return WL_OUTPUT_TRANSFORM_NORMAL;
 }
 
-class WaylandDisplayObserver : public gfx::DisplayObserver {
+class WaylandDisplayObserver : public display::DisplayObserver {
  public:
-  WaylandDisplayObserver(const gfx::Display& display,
+  WaylandDisplayObserver(const display::Display& display,
                          wl_resource* output_resource)
       : display_id_(display.id()), output_resource_(output_resource) {
-    gfx::Screen::GetScreen()->AddObserver(this);
+    display::Screen::GetScreen()->AddObserver(this);
     SendDisplayMetrics(display);
   }
   ~WaylandDisplayObserver() override {
-    gfx::Screen::GetScreen()->RemoveObserver(this);
+    display::Screen::GetScreen()->RemoveObserver(this);
   }
 
-  // Overridden from gfx::DisplayObserver:
-  void OnDisplayAdded(const gfx::Display& new_display) override {}
-  void OnDisplayRemoved(const gfx::Display& new_display) override {}
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  // Overridden from display::DisplayObserver:
+  void OnDisplayAdded(const display::Display& new_display) override {}
+  void OnDisplayRemoved(const display::Display& new_display) override {}
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override {
     if (display.id() != display_id_)
       return;
@@ -982,7 +982,7 @@
   }
 
  private:
-  void SendDisplayMetrics(const gfx::Display& display) {
+  void SendDisplayMetrics(const display::Display& display) {
     const ash::DisplayInfo& info =
         ash::Shell::GetInstance()->display_manager()->GetDisplayInfo(
             display.id());
@@ -1031,9 +1031,9 @@
       client, &wl_output_interface, std::min(version, output_version), id);
 
   // TODO(reveman): Multi-display support.
-  const gfx::Display& display = ash::Shell::GetInstance()
-                                    ->display_manager()
-                                    ->GetPrimaryDisplayCandidate();
+  const display::Display& display = ash::Shell::GetInstance()
+                                        ->display_manager()
+                                        ->GetPrimaryDisplayCandidate();
 
   SetImplementation(
       resource, nullptr,
diff --git a/components/font_service/public/cpp/font_service_thread.cc b/components/font_service/public/cpp/font_service_thread.cc
index 36ca646d..810d2c72 100644
--- a/components/font_service/public/cpp/font_service_thread.cc
+++ b/components/font_service/public/cpp/font_service_thread.cc
@@ -104,6 +104,7 @@
   style->width = requested_style.width();
   style->slant = static_cast<TypefaceSlant>(requested_style.slant());
 
+  pending_waitable_events_.insert(done_event);
   font_service_->MatchFamilyName(
       mojo::String(family_name), std::move(style),
       base::Bind(&FontServiceThread::OnMatchFamilyNameComplete, this,
@@ -121,6 +122,7 @@
     mojo::String family_name,
     TypefaceStylePtr style) {
   DCHECK_EQ(GetThreadId(), base::PlatformThread::CurrentId());
+  pending_waitable_events_.erase(done_event);
 
   *out_valid = font_identity;
   if (font_identity) {
diff --git a/components/image_fetcher.gypi b/components/image_fetcher.gypi
new file mode 100644
index 0000000..2b9c9a7
--- /dev/null
+++ b/components/image_fetcher.gypi
@@ -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.
+
+{
+  'targets': [
+    {
+      # GN version: //components/image_fetcher
+      'target_name': 'image_fetcher',
+      'type': 'none',
+      'include_dirs': [
+        '..',
+      ],
+      'dependencies': [
+        '../base/base.gyp:base',
+        '../url/url.gyp:url_lib',
+      ],
+      'sources': [
+        'image_fetcher/image_fetcher.h',
+        'image_fetcher/image_fetcher_delegate.h',
+      ]
+    },
+  ],
+}
diff --git a/components/image_fetcher/BUILD.gn b/components/image_fetcher/BUILD.gn
new file mode 100644
index 0000000..ffb753a
--- /dev/null
+++ b/components/image_fetcher/BUILD.gn
@@ -0,0 +1,15 @@
+# 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.
+
+source_set("image_fetcher") {
+  sources = [
+    "image_fetcher.h",
+    "image_fetcher_delegate.h",
+  ]
+
+  public_deps = [
+    "//base",
+    "//url",
+  ]
+}
diff --git a/components/image_fetcher/DEPS b/components/image_fetcher/DEPS
new file mode 100644
index 0000000..674b34df
--- /dev/null
+++ b/components/image_fetcher/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+url",
+]
diff --git a/components/image_fetcher/OWNERS b/components/image_fetcher/OWNERS
new file mode 100644
index 0000000..f5f61960
--- /dev/null
+++ b/components/image_fetcher/OWNERS
@@ -0,0 +1,2 @@
+mathp@chromium.org
+treib@chromium.org
diff --git a/components/suggestions/image_fetcher.h b/components/image_fetcher/image_fetcher.h
similarity index 71%
rename from components/suggestions/image_fetcher.h
rename to components/image_fetcher/image_fetcher.h
index acb65d42..e2969304 100644
--- a/components/suggestions/image_fetcher.h
+++ b/components/image_fetcher/image_fetcher.h
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_H_
-#define COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_H_
+#ifndef COMPONENTS_IMAGE_FETCHER_IMAGE_FETCHER_H_
+#define COMPONENTS_IMAGE_FETCHER_IMAGE_FETCHER_H_
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "components/suggestions/image_fetcher_delegate.h"
+#include "components/image_fetcher/image_fetcher_delegate.h"
 #include "url/gurl.h"
 
 class SkBitmap;
 
-namespace suggestions {
+namespace image_fetcher {
 
 // A class used to fetch server images.
 class ImageFetcher {
@@ -30,6 +30,6 @@
   DISALLOW_COPY_AND_ASSIGN(ImageFetcher);
 };
 
-}  // namespace suggestions
+}  // namespace image_fetcher
 
-#endif  // COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_H_
+#endif  // COMPONENTS_IMAGE_FETCHER_IMAGE_FETCHER_H_
diff --git a/components/suggestions/image_fetcher_delegate.h b/components/image_fetcher/image_fetcher_delegate.h
similarity index 73%
rename from components/suggestions/image_fetcher_delegate.h
rename to components/image_fetcher/image_fetcher_delegate.h
index d9ddec48..0256516 100644
--- a/components/suggestions/image_fetcher_delegate.h
+++ b/components/image_fetcher/image_fetcher_delegate.h
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_DELEGATE_H_
-#define COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_DELEGATE_H_
+#ifndef COMPONENTS_IMAGE_FETCHER_IMAGE_FETCHER_DELEGATE_H_
+#define COMPONENTS_IMAGE_FETCHER_IMAGE_FETCHER_DELEGATE_H_
 
 #include "base/macros.h"
 
 class GURL;
 class SkBitmap;
 
-namespace suggestions {
+namespace image_fetcher {
 
 class ImageFetcherDelegate {
  public:
@@ -27,6 +27,6 @@
   DISALLOW_COPY_AND_ASSIGN(ImageFetcherDelegate);
 };
 
-}  // namespace suggestions
+}  // namespace image_fetcher
 
-#endif  // COMPONENTS_SUGGESTIONS_IMAGE_FETCHER_DELEGATE_H_
+#endif  // COMPONENTS_IMAGE_FETCHER_IMAGE_FETCHER_DELEGATE_H_
diff --git a/components/metrics.gypi b/components/metrics.gypi
index 185ee54e..50eade56 100644
--- a/components/metrics.gypi
+++ b/components/metrics.gypi
@@ -142,6 +142,7 @@
       ],
       'dependencies': [
         '../base/base.gyp:base',
+        '../ui/display/display.gyp:display',
         '../ui/gfx/gfx.gyp:gfx',
         'metrics',
       ],
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index 4e7c29b8..3ce78de 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -216,6 +216,7 @@
   ]
   deps = [
     "//base",
+    "//ui/display",
     "//ui/gfx",
     "//ui/gfx/geometry",
   ]
diff --git a/components/metrics/ui/DEPS b/components/metrics/ui/DEPS
index b273ae3..e141313 100644
--- a/components/metrics/ui/DEPS
+++ b/components/metrics/ui/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
+  "+ui/display",
   "+ui/gfx",
 ]
diff --git a/components/metrics/ui/screen_info_metrics_provider.cc b/components/metrics/ui/screen_info_metrics_provider.cc
index 3d31e98..8c4b0dcd 100644
--- a/components/metrics/ui/screen_info_metrics_provider.cc
+++ b/components/metrics/ui/screen_info_metrics_provider.cc
@@ -6,7 +6,7 @@
 
 #include "build/build_config.h"
 #include "components/metrics/proto/system_profile.pb.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
 
 namespace metrics {
 
@@ -78,15 +78,17 @@
 }
 
 gfx::Size ScreenInfoMetricsProvider::GetScreenSize() const {
-  return gfx::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel();
+  return display::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel();
 }
 
 float ScreenInfoMetricsProvider::GetScreenDeviceScaleFactor() const {
-  return gfx::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+  return display::Screen::GetScreen()
+      ->GetPrimaryDisplay()
+      .device_scale_factor();
 }
 
 int ScreenInfoMetricsProvider::GetScreenCount() const {
-  return gfx::Screen::GetScreen()->GetNumDisplays();
+  return display::Screen::GetScreen()->GetNumDisplays();
 }
 
 }  // namespace metrics
diff --git a/components/mus/DEPS b/components/mus/DEPS
index cc7b362..82b5d958 100644
--- a/components/mus/DEPS
+++ b/components/mus/DEPS
@@ -1,7 +1,6 @@
 include_rules = [
   "+cc",
   "+components/resource_provider",
-  "+components/gpu",
   "+ipc",
   "+mojo/common",
   "+mojo/converters",
diff --git a/components/mus/gles2/command_buffer_impl.cc b/components/mus/gles2/command_buffer_impl.cc
index 20018b11..86fb239 100644
--- a/components/mus/gles2/command_buffer_impl.cc
+++ b/components/mus/gles2/command_buffer_impl.cc
@@ -137,7 +137,12 @@
   NOTIMPLEMENTED();
 }
 
-void CommandBufferImpl::ProduceFrontBuffer(const gpu::Mailbox& mailbox) {
+void CommandBufferImpl::TakeFrontBuffer(const gpu::Mailbox& mailbox) {
+  NOTIMPLEMENTED();
+}
+
+void CommandBufferImpl::ReturnFrontBuffer(const gpu::Mailbox& mailbox,
+                                          bool is_lost) {
   NOTIMPLEMENTED();
 }
 
diff --git a/components/mus/gles2/command_buffer_impl.h b/components/mus/gles2/command_buffer_impl.h
index d03cdf14..69f3a20 100644
--- a/components/mus/gles2/command_buffer_impl.h
+++ b/components/mus/gles2/command_buffer_impl.h
@@ -67,7 +67,8 @@
       uint32_t client_texture_id,
       const mojom::CommandBuffer::CreateStreamTextureCallback& callback
       ) override;
-  void ProduceFrontBuffer(const gpu::Mailbox& mailbox) override;
+  void TakeFrontBuffer(const gpu::Mailbox& mailbox) override;
+  void ReturnFrontBuffer(const gpu::Mailbox& mailbox, bool is_lost) override;
   void SignalQuery(uint32_t query, uint32_t signal_id) override;
   void SignalSyncToken(const gpu::SyncToken& sync_token,
                        uint32_t signal_id) override;
diff --git a/components/mus/gles2/command_buffer_local.cc b/components/mus/gles2/command_buffer_local.cc
index 177c610..57359ebf 100644
--- a/components/mus/gles2/command_buffer_local.cc
+++ b/components/mus/gles2/command_buffer_local.cc
@@ -334,12 +334,6 @@
   NOTIMPLEMENTED();
 }
 
-bool CommandBufferLocal::IsGpuChannelLost() {
-  DCHECK(CalledOnValidThread());
-  // This is only possible for out-of-process command buffers.
-  return false;
-}
-
 void CommandBufferLocal::EnsureWorkVisible() {
   // This is only relevant for out-of-process command buffers.
 }
diff --git a/components/mus/gles2/command_buffer_local.h b/components/mus/gles2/command_buffer_local.h
index d1e9f04..b0e077e3 100644
--- a/components/mus/gles2/command_buffer_local.h
+++ b/components/mus/gles2/command_buffer_local.h
@@ -88,7 +88,6 @@
                                      unsigned usage) override;
   void SignalQuery(uint32_t query_id, const base::Closure& callback) override;
   void SetLock(base::Lock*) override;
-  bool IsGpuChannelLost() override;
   void EnsureWorkVisible() override;
   gpu::CommandBufferNamespace GetNamespaceID() const override;
   gpu::CommandBufferId GetCommandBufferID() const override;
diff --git a/components/mus/gpu/BUILD.gn b/components/mus/gpu/BUILD.gn
index 0bcf1fc..a251efa 100644
--- a/components/mus/gpu/BUILD.gn
+++ b/components/mus/gpu/BUILD.gn
@@ -2,16 +2,54 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//mojo/public/mojo_application_manifest.gni")
+import("//testing/test.gni")
+
 source_set("gpu") {
   output_name = "mus_gpu"
 
   sources = [
     "gpu_service_mus.cc",
     "gpu_service_mus.h",
+    "gpu_type_converters.cc",
+    "gpu_type_converters.h",
   ]
 
   deps = [
+    "//components/mus/public/interfaces",
     "//gpu/ipc/common",
     "//gpu/ipc/service",
+    "//ipc",
+    "//mojo/platform_handle:platform_handle",
   ]
 }
+
+group("tests") {
+  testonly = true
+  deps = [
+    ":mus_gpu_unittests",
+  ]
+}
+
+test("mus_gpu_unittests") {
+  sources = [
+    "gpu_type_converters_unittest.cc",
+  ]
+
+  deps = [
+    ":gpu",
+    "//base",
+    "//ipc",
+    "//services/shell/public/cpp/test:run_all_shelltests",
+    "//testing/gtest",
+  ]
+
+  data_deps = [
+    ":mus_gpu_unittests_app_manifest",
+  ]
+}
+
+mojo_application_manifest("mus_gpu_unittests_app_manifest") {
+  application_name = "mus_gpu_unittests_app"
+  source = "mus_gpu_unittests_app_manifest.json"
+}
diff --git a/components/mus/gpu/DEPS b/components/mus/gpu/DEPS
index 9846e4a87..812e2aa1 100644
--- a/components/mus/gpu/DEPS
+++ b/components/mus/gpu/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+gpu/ipc/common",
   "+gpu/ipc/service",
+  "+mojo/platform_handle",
 ]
diff --git a/components/mus/gpu/gpu_type_converters.cc b/components/mus/gpu/gpu_type_converters.cc
new file mode 100644
index 0000000..ddeed608
--- /dev/null
+++ b/components/mus/gpu/gpu_type_converters.cc
@@ -0,0 +1,53 @@
+// 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/gpu/gpu_type_converters.h"
+
+#include "ipc/ipc_channel_handle.h"
+#include "mojo/platform_handle/platform_handle_functions.h"
+
+namespace mojo {
+
+// static
+mus::mojom::ChannelHandlePtr
+TypeConverter<mus::mojom::ChannelHandlePtr, IPC::ChannelHandle>::Convert(
+    const IPC::ChannelHandle& handle) {
+  mus::mojom::ChannelHandlePtr result = mus::mojom::ChannelHandle::New();
+  result->name = handle.name;
+#if defined(OS_WIN)
+  // On windows, a pipe handle Will NOT be marshalled over IPC.
+  DCHECK(handle.pipe.handle == NULL);
+#else
+  MojoPlatformHandle platform_handle =
+      handle.socket.fd == -1 ? -1 : dup(handle.socket.fd);
+  MojoHandle mojo_handle = MOJO_HANDLE_INVALID;
+  if (platform_handle != -1) {
+    MojoResult create_result =
+        MojoCreatePlatformHandleWrapper(platform_handle, &mojo_handle);
+    if (create_result == MOJO_RESULT_OK)
+      result->socket.reset(mojo::Handle(mojo_handle));
+  }
+#endif
+  return result;
+}
+
+// static
+IPC::ChannelHandle
+TypeConverter<IPC::ChannelHandle, mus::mojom::ChannelHandlePtr>::Convert(
+    const mus::mojom::ChannelHandlePtr& handle) {
+  if (handle.is_null())
+    return IPC::ChannelHandle();
+#if defined(OS_WIN)
+  // On windows, a pipe handle Will NOT be marshalled over IPC.
+  DCHECK(!handle->socket.is_valid());
+  return IPC::ChannelHandle(handle->name);
+#else
+  MojoPlatformHandle platform_handle = -1;
+  MojoExtractPlatformHandle(handle->socket.release().value(), &platform_handle);
+  return IPC::ChannelHandle(handle->name,
+                            base::FileDescriptor(platform_handle, true));
+#endif
+}
+
+}  // namespace mojo
diff --git a/components/mus/gpu/gpu_type_converters.h b/components/mus/gpu/gpu_type_converters.h
new file mode 100644
index 0000000..6de95fd
--- /dev/null
+++ b/components/mus/gpu/gpu_type_converters.h
@@ -0,0 +1,29 @@
+// 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_GPU_GPU_TYPE_CONVERTERS_H_
+#define COMPONENTS_MUS_GPU_GPU_TYPE_CONVERTERS_H_
+
+#include "components/mus/public/interfaces/channel_handle.mojom.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+
+namespace IPC {
+struct ChannelHandle;
+}
+
+namespace mojo {
+
+template <>
+struct TypeConverter<mus::mojom::ChannelHandlePtr, IPC::ChannelHandle> {
+  static mus::mojom::ChannelHandlePtr Convert(const IPC::ChannelHandle& handle);
+};
+
+template <>
+struct TypeConverter<IPC::ChannelHandle, mus::mojom::ChannelHandlePtr> {
+  static IPC::ChannelHandle Convert(const mus::mojom::ChannelHandlePtr& handle);
+};
+
+}  // namespace mojo
+
+#endif  // COMPONENTS_MUS_GPU_GPU_TYPE_CONVERTERS_H_
diff --git a/components/mus/gpu/gpu_type_converters_unittest.cc b/components/mus/gpu/gpu_type_converters_unittest.cc
new file mode 100644
index 0000000..14722dc
--- /dev/null
+++ b/components/mus/gpu/gpu_type_converters_unittest.cc
@@ -0,0 +1,57 @@
+// 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 <string>
+
+#include "base/files/scoped_file.h"
+#include "components/mus/gpu/gpu_type_converters.h"
+#include "build/build_config.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_channel_handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Test for mojo TypeConverter of mus::mojom::ChannelHandle.
+TEST(MusGpuTypeConvertersTest, ChannelHandle) {
+  {
+    const std::string channel_name = "test_channel_name";
+    IPC::ChannelHandle handle(channel_name);
+
+    mus::mojom::ChannelHandlePtr mojo_handle =
+        mus::mojom::ChannelHandle::From(handle);
+    ASSERT_EQ(mojo_handle->name, channel_name);
+    EXPECT_FALSE(mojo_handle->socket.is_valid());
+
+    handle = mojo_handle.To<IPC::ChannelHandle>();
+    ASSERT_EQ(handle.name, channel_name);
+#if defined(OS_POSIX)
+    ASSERT_EQ(handle.socket.fd, -1);
+#endif
+  }
+
+#if defined(OS_POSIX)
+  {
+    const std::string channel_name = "test_channel_name";
+    int fd1 = -1;
+    int fd2 = -1;
+    bool result = IPC::SocketPair(&fd1, &fd2);
+    EXPECT_TRUE(result);
+
+    base::ScopedFD scoped_fd1(fd1);
+    base::ScopedFD scoped_fd2(fd2);
+    IPC::ChannelHandle handle(channel_name,
+                              base::FileDescriptor(scoped_fd1.get(), false));
+
+    mus::mojom::ChannelHandlePtr mojo_handle =
+        mus::mojom::ChannelHandle::From(handle);
+    ASSERT_EQ(mojo_handle->name, channel_name);
+    EXPECT_TRUE(mojo_handle->socket.is_valid());
+
+    handle = mojo_handle.To<IPC::ChannelHandle>();
+    ASSERT_EQ(handle.name, channel_name);
+    ASSERT_NE(handle.socket.fd, -1);
+    EXPECT_TRUE(handle.socket.auto_close);
+    base::ScopedFD socped_fd3(handle.socket.fd);
+  }
+#endif
+}
diff --git a/components/mus/gpu/mus_gpu_unittests_app_manifest.json b/components/mus/gpu/mus_gpu_unittests_app_manifest.json
new file mode 100644
index 0000000..7138517
--- /dev/null
+++ b/components/mus/gpu/mus_gpu_unittests_app_manifest.json
@@ -0,0 +1,5 @@
+{
+  "name": "mojo:mus_gpu_unittests_app",
+  "display_name": "Mus GPU Unittests",
+  "capabilities": { "*": [ "*" ] }
+}
diff --git a/components/mus/public/cpp/event_matcher_util.h b/components/mus/public/cpp/event_matcher_util.h
index c4584fe..d2977f1 100644
--- a/components/mus/public/cpp/event_matcher_util.h
+++ b/components/mus/public/cpp/event_matcher_util.h
@@ -5,8 +5,8 @@
 #ifndef COMPONENTS_MUS_PUBLIC_CPP_EVENT_MATCHER_UTIL_H_
 #define COMPONENTS_MUS_PUBLIC_CPP_EVENT_MATCHER_UTIL_H_
 
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/public/interfaces/input_event_constants.mojom.h"
-#include "components/mus/public/interfaces/input_event_matcher.mojom.h"
 #include "components/mus/public/interfaces/input_key_codes.mojom.h"
 
 namespace mus {
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.cc b/components/mus/public/cpp/lib/window_tree_client_impl.cc
index ec57bf6..5c5f5a3 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.cc
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.cc
@@ -131,7 +131,9 @@
       binding_(this),
       tree_(nullptr),
       delete_on_no_roots_(true),
-      in_destructor_(false) {
+      in_destructor_(false),
+      cursor_location_memory_(nullptr),
+      weak_factory_(this) {
   // Allow for a null request in tests.
   if (request.is_pending())
     binding_.Bind(std::move(request));
@@ -177,6 +179,10 @@
   factory->CreateWindowTree(GetProxy(&tree_ptr_),
                             binding_.CreateInterfacePtrAndBind());
   tree_ = tree_ptr_.get();
+
+  tree_ptr_->GetCursorLocationMemory(
+      base::Bind(&WindowTreeClientImpl::OnReceivedCursorLocationMemory,
+                 weak_factory_.GetWeakPtr()));
 }
 
 void WindowTreeClientImpl::WaitForEmbed() {
@@ -529,6 +535,21 @@
   }
 }
 
+void WindowTreeClientImpl::OnReceivedCursorLocationMemory(
+    mojo::ScopedSharedBufferHandle handle) {
+  cursor_location_handle_ = std::move(handle);
+  MojoResult result = mojo::MapBuffer(
+      cursor_location_handle_.get(), 0,
+      sizeof(base::subtle::Atomic32),
+      reinterpret_cast<void**>(&cursor_location_memory_),
+      MOJO_MAP_BUFFER_FLAG_NONE);
+  if (result != MOJO_RESULT_OK) {
+    NOTREACHED();
+    return;
+  }
+  DCHECK(cursor_location_memory_);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // WindowTreeClientImpl, WindowTreeConnection implementation:
 
@@ -551,6 +572,17 @@
   SetFocus(nullptr);
 }
 
+gfx::Point WindowTreeClientImpl::GetCursorScreenPoint() {
+  // We raced initialization. Return (0, 0).
+  if (!cursor_location_memory_)
+    return gfx::Point();
+
+  base::subtle::Atomic32 location =
+      base::subtle::NoBarrier_Load(cursor_location_memory_);
+  return gfx::Point(static_cast<int16_t>(location >> 16),
+                    static_cast<int16_t>(location & 0xFFFF));
+}
+
 void WindowTreeClientImpl::SetEventObserver(mojom::EventMatcherPtr matcher) {
   if (matcher.is_null()) {
     has_event_observer_ = false;
diff --git a/components/mus/public/cpp/lib/window_tree_client_impl.h b/components/mus/public/cpp/lib/window_tree_client_impl.h
index 491d589..bef02578 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.h
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.h
@@ -10,7 +10,9 @@
 #include <map>
 #include <set>
 
+#include "base/atomicops.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "components/mus/common/types.h"
 #include "components/mus/public/cpp/window.h"
@@ -162,11 +164,14 @@
                    Id focused_window_id,
                    bool drawn);
 
+  void OnReceivedCursorLocationMemory(mojo::ScopedSharedBufferHandle handle);
+
   // Overridden from WindowTreeConnection:
   void SetDeleteOnNoRoots(bool value) override;
   const std::set<Window*>& GetRoots() override;
   Window* GetFocusedWindow() override;
   void ClearFocus() override;
+  gfx::Point GetCursorScreenPoint() override;
   void SetEventObserver(mojom::EventMatcherPtr matcher) override;
   Window* NewWindow(const Window::SharedProperties* properties) override;
   Window* NewTopLevelWindow(
@@ -294,6 +299,14 @@
 
   bool in_destructor_;
 
+  // A handle to shared memory that is one 32 bit integer long. The window
+  // server uses this to let us synchronously read the cursor location.
+  mojo::ScopedSharedBufferHandle cursor_location_handle_;
+
+  // The one int in |cursor_location_handle_|. When we read from this
+  // location, we must always read from it atomically.
+  base::subtle::Atomic32* cursor_location_memory_;
+
   base::ObserverList<WindowTreeConnectionObserver> observers_;
 
   std::unique_ptr<mojo::AssociatedBinding<mojom::WindowManager>>
@@ -305,6 +318,8 @@
   // Monotonically increasing ID for event observers.
   uint32_t event_observer_id_ = 0u;
 
+  base::WeakPtrFactory<WindowTreeClientImpl> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl);
 };
 
diff --git a/components/mus/public/cpp/tests/test_window_tree.cc b/components/mus/public/cpp/tests/test_window_tree.cc
index 96e5351..d73b4c8 100644
--- a/components/mus/public/cpp/tests/test_window_tree.cc
+++ b/components/mus/public/cpp/tests/test_window_tree.cc
@@ -155,4 +155,9 @@
 void TestWindowTree::GetWindowManagerClient(
     mojo::AssociatedInterfaceRequest<mojom::WindowManagerClient> internal) {}
 
+void TestWindowTree::GetCursorLocationMemory(
+    const GetCursorLocationMemoryCallback& callback) {
+  callback.Run(mojo::ScopedSharedBufferHandle());
+}
+
 }  // namespace mus
diff --git a/components/mus/public/cpp/tests/test_window_tree.h b/components/mus/public/cpp/tests/test_window_tree.h
index b3f08cd..7e007bf 100644
--- a/components/mus/public/cpp/tests/test_window_tree.h
+++ b/components/mus/public/cpp/tests/test_window_tree.h
@@ -97,6 +97,8 @@
   void GetWindowManagerClient(
       mojo::AssociatedInterfaceRequest<mojom::WindowManagerClient> internal)
       override;
+  void GetCursorLocationMemory(const GetCursorLocationMemoryCallback& callback)
+      override;
 
   bool got_change_;
   uint32_t change_id_;
diff --git a/components/mus/public/cpp/window_manager_delegate.h b/components/mus/public/cpp/window_manager_delegate.h
index 11b262c..c37a133 100644
--- a/components/mus/public/cpp/window_manager_delegate.h
+++ b/components/mus/public/cpp/window_manager_delegate.h
@@ -12,7 +12,7 @@
 #include <vector>
 
 #include "base/callback_forward.h"
-#include "components/mus/public/interfaces/input_event_matcher.mojom.h"
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/public/interfaces/input_events.mojom.h"
 #include "components/mus/public/interfaces/window_manager_constants.mojom.h"
 
diff --git a/components/mus/public/cpp/window_tree_connection.h b/components/mus/public/cpp/window_tree_connection.h
index b4b2351..f9ec3ccc 100644
--- a/components/mus/public/cpp/window_tree_connection.h
+++ b/components/mus/public/cpp/window_tree_connection.h
@@ -16,6 +16,10 @@
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 
+namespace gfx {
+class Point;
+}
+
 namespace shell {
 class Connector;
 }
@@ -78,6 +82,10 @@
   // Sets focus to null. This does nothing if focus is currently null.
   virtual void ClearFocus() = 0;
 
+  // Returns the current location of the mouse on screen. Note: this method may
+  // race the asynchronous initialization; but in that case we return (0, 0).
+  virtual gfx::Point GetCursorScreenPoint() = 0;
+
   // See description in window_tree.mojom. When an existing event observer is
   // updated or cleared then any future events from the server for that observer
   // will be ignored.
diff --git a/components/mus/public/interfaces/BUILD.gn b/components/mus/public/interfaces/BUILD.gn
index f31b08b3..0434441 100644
--- a/components/mus/public/interfaces/BUILD.gn
+++ b/components/mus/public/interfaces/BUILD.gn
@@ -7,13 +7,14 @@
 mojom("interfaces") {
   sources = [
     "accelerator_registrar.mojom",
+    "channel_handle.mojom",
     "command_buffer.mojom",
     "compositor_frame.mojom",
     "cursor.mojom",
     "display.mojom",
+    "event_matcher.mojom",
     "gpu.mojom",
     "input_event_constants.mojom",
-    "input_event_matcher.mojom",
     "input_events.mojom",
     "input_key_codes.mojom",
     "mus_constants.mojom",
@@ -34,7 +35,7 @@
   ]
 
   deps = [
-    "//gpu/command_buffer/common:interfaces",
+    "//gpu/ipc/common:interfaces",
     "//ui/mojo/geometry:interfaces",
     "//ui/mojo/ime:interfaces",
   ]
diff --git a/components/mus/public/interfaces/accelerator_registrar.mojom b/components/mus/public/interfaces/accelerator_registrar.mojom
index ba210ec..84d5990 100644
--- a/components/mus/public/interfaces/accelerator_registrar.mojom
+++ b/components/mus/public/interfaces/accelerator_registrar.mojom
@@ -4,7 +4,7 @@
 
 module mus.mojom;
 
-import "components/mus/public/interfaces/input_event_matcher.mojom";
+import "components/mus/public/interfaces/event_matcher.mojom";
 import "components/mus/public/interfaces/input_events.mojom";
 
 interface AcceleratorHandler {
diff --git a/components/mus/public/interfaces/channel_handle.mojom b/components/mus/public/interfaces/channel_handle.mojom
new file mode 100644
index 0000000..d78a53f5
--- /dev/null
+++ b/components/mus/public/interfaces/channel_handle.mojom
@@ -0,0 +1,13 @@
+// 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 mus.mojom;
+
+// See IPC::ChannelHandle in src/ipc/ipc_channel_handle.h
+struct ChannelHandle {
+  string name;
+
+  // On POSIX, it is one endpoint of a socket pair. On Windows, it is not used.
+  handle socket;
+};
diff --git a/components/mus/public/interfaces/command_buffer.mojom b/components/mus/public/interfaces/command_buffer.mojom
index 8b08256..f8c3899 100644
--- a/components/mus/public/interfaces/command_buffer.mojom
+++ b/components/mus/public/interfaces/command_buffer.mojom
@@ -4,10 +4,10 @@
 
 module mus.mojom;
 
-import "gpu/command_buffer/common/capabilities.mojom";
-import "gpu/command_buffer/common/command_buffer.mojom";
-import "gpu/command_buffer/common/mailbox.mojom";
-import "gpu/command_buffer/common/sync_token.mojom";
+import "gpu/ipc/common/capabilities.mojom";
+import "gpu/ipc/common/command_buffer.mojom";
+import "gpu/ipc/common/mailbox.mojom";
+import "gpu/ipc/common/sync_token.mojom";
 import "ui/mojo/geometry/geometry.mojom";
 
 struct CommandBufferInitializeResult {
@@ -51,7 +51,8 @@
   DestroyImage(int32 id);
   CreateStreamTexture(uint32 client_texture_id)
       => (int32 stream_id, bool succeeded);
-  ProduceFrontBuffer(gpu.mojom.Mailbox mailbox);
+  TakeFrontBuffer(gpu.mojom.Mailbox mailbox);
+  ReturnFrontBuffer(gpu.mojom.Mailbox mailbox, bool is_lost);
   SignalQuery(uint32 query, uint32 signal_id);
   SignalSyncToken(gpu.mojom.SyncToken sync_token, uint32 signal_id);
   WaitForGetOffsetInRange(int32 start, int32 end)
diff --git a/components/mus/public/interfaces/compositor_frame.mojom b/components/mus/public/interfaces/compositor_frame.mojom
index aaab87a4..014145b 100644
--- a/components/mus/public/interfaces/compositor_frame.mojom
+++ b/components/mus/public/interfaces/compositor_frame.mojom
@@ -6,8 +6,8 @@
 
 import "components/mus/public/interfaces/quads.mojom";
 import "ui/mojo/geometry/geometry.mojom";
-import "gpu/command_buffer/common/mailbox_holder.mojom";
-import "gpu/command_buffer/common/sync_token.mojom";
+import "gpu/ipc/common/mailbox_holder.mojom";
+import "gpu/ipc/common/sync_token.mojom";
 
 enum ResourceFormat {
   RGBA_8888,
diff --git a/components/mus/public/interfaces/input_event_matcher.mojom b/components/mus/public/interfaces/event_matcher.mojom
similarity index 100%
rename from components/mus/public/interfaces/input_event_matcher.mojom
rename to components/mus/public/interfaces/event_matcher.mojom
diff --git a/components/mus/public/interfaces/window_manager.mojom b/components/mus/public/interfaces/window_manager.mojom
index 1a6eba3..20e0c74 100644
--- a/components/mus/public/interfaces/window_manager.mojom
+++ b/components/mus/public/interfaces/window_manager.mojom
@@ -4,7 +4,7 @@
 
 module mus.mojom;
 
-import "components/mus/public/interfaces/input_event_matcher.mojom";
+import "components/mus/public/interfaces/event_matcher.mojom";
 import "components/mus/public/interfaces/input_events.mojom";
 import "components/mus/public/interfaces/window_manager_constants.mojom";
 import "ui/mojo/geometry/geometry.mojom";
diff --git a/components/mus/public/interfaces/window_tree.mojom b/components/mus/public/interfaces/window_tree.mojom
index f899c62..e4855ba 100644
--- a/components/mus/public/interfaces/window_tree.mojom
+++ b/components/mus/public/interfaces/window_tree.mojom
@@ -6,8 +6,8 @@
 
 import "components/mus/public/interfaces/compositor_frame.mojom";
 import "components/mus/public/interfaces/cursor.mojom";
+import "components/mus/public/interfaces/event_matcher.mojom";
 import "components/mus/public/interfaces/input_events.mojom";
-import "components/mus/public/interfaces/input_event_matcher.mojom";
 import "components/mus/public/interfaces/mus_constants.mojom";
 import "components/mus/public/interfaces/surface_id.mojom";
 import "components/mus/public/interfaces/window_manager.mojom";
@@ -260,6 +260,11 @@
 
   // See description of WindowManager for details.
   GetWindowManagerClient(associated WindowManagerClient& internal);
+
+  // Returns a shared memory segment that contains two 16-bit ints packed into a
+  // single Atomic32, which represent the current location of the mouse cursor
+  // where the location is (x << 16) | y.
+  GetCursorLocationMemory() => (handle<shared_buffer> cursor_buffer);
 };
 
 // Changes to windows are not sent to the connection that originated the
diff --git a/components/mus/ws/BUILD.gn b/components/mus/ws/BUILD.gn
index a5eb3ec..a524b21b 100644
--- a/components/mus/ws/BUILD.gn
+++ b/components/mus/ws/BUILD.gn
@@ -103,6 +103,7 @@
     "//services/shell/public/interfaces",
     "//services/tracing/public/cpp",
     "//ui/base",
+    "//ui/display",
     "//ui/events",
     "//ui/events/platform",
     "//ui/gfx",
diff --git a/components/mus/ws/accelerator.h b/components/mus/ws/accelerator.h
index 91fd8938..31051fb 100644
--- a/components/mus/ws/accelerator.h
+++ b/components/mus/ws/accelerator.h
@@ -9,7 +9,7 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "components/mus/public/interfaces/input_event_matcher.mojom.h"
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/ws/event_matcher.h"
 
 namespace ui {
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc
index 69d7fa155..ecc2deb 100644
--- a/components/mus/ws/event_dispatcher.cc
+++ b/components/mus/ws/event_dispatcher.cc
@@ -108,6 +108,10 @@
   DCHECK(pointer_targets_.empty());
   mouse_pointer_last_location_ = screen_location;
   UpdateCursorProviderByLastKnownLocation();
+  // Write our initial location back to our shared screen coordinate. This
+  // shouldn't cause problems because we already read the cursor before we
+  // process any events in views during window construction.
+  delegate_->OnMouseCursorLocationChanged(screen_location);
 }
 
 bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
@@ -241,8 +245,10 @@
   const bool is_mouse_event =
       event.IsMousePointerEvent() || event.IsMouseWheelEvent();
 
-  if (is_mouse_event)
+  if (is_mouse_event) {
     mouse_pointer_last_location_ = event.location();
+    delegate_->OnMouseCursorLocationChanged(event.root_location());
+  }
 
   // Release capture on pointer up. For mouse we only release if there are
   // no buttons down.
diff --git a/components/mus/ws/event_dispatcher.h b/components/mus/ws/event_dispatcher.h
index bc0e9483..19b39b2 100644
--- a/components/mus/ws/event_dispatcher.h
+++ b/components/mus/ws/event_dispatcher.h
@@ -12,7 +12,7 @@
 
 #include "base/macros.h"
 #include "cc/surfaces/surface_id.h"
-#include "components/mus/public/interfaces/input_event_matcher.mojom.h"
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/ws/server_window_observer.h"
 #include "ui/gfx/geometry/rect_f.h"
 
diff --git a/components/mus/ws/event_dispatcher_delegate.h b/components/mus/ws/event_dispatcher_delegate.h
index c377d1be..aa92791 100644
--- a/components/mus/ws/event_dispatcher_delegate.h
+++ b/components/mus/ws/event_dispatcher_delegate.h
@@ -35,6 +35,8 @@
   // ReleaseNativeCapture is invoked if appropriate.
   virtual void OnServerWindowCaptureLost(ServerWindow* window) = 0;
 
+  virtual void OnMouseCursorLocationChanged(const gfx::Point& point) = 0;
+
   // |in_nonclient_area| is true if the event occurred in the non-client area.
   virtual void DispatchInputEventToWindow(ServerWindow* target,
                                           bool in_nonclient_area,
diff --git a/components/mus/ws/event_dispatcher_unittest.cc b/components/mus/ws/event_dispatcher_unittest.cc
index 740c1dd..bbf68554 100644
--- a/components/mus/ws/event_dispatcher_unittest.cc
+++ b/components/mus/ws/event_dispatcher_unittest.cc
@@ -96,6 +96,7 @@
   void OnServerWindowCaptureLost(ServerWindow* window) override {
     lost_capture_window_ = window;
   }
+  void OnMouseCursorLocationChanged(const gfx::Point& point) override {}
   void DispatchInputEventToWindow(ServerWindow* target,
                                   bool in_nonclient_area,
                                   const ui::Event& event,
diff --git a/components/mus/ws/event_matcher.h b/components/mus/ws/event_matcher.h
index be3794e..eedbf1c 100644
--- a/components/mus/ws/event_matcher.h
+++ b/components/mus/ws/event_matcher.h
@@ -8,8 +8,8 @@
 #include <stdint.h>
 
 #include "base/macros.h"
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/public/interfaces/input_event_constants.mojom.h"
-#include "components/mus/public/interfaces/input_event_matcher.mojom.h"
 #include "components/mus/public/interfaces/input_key_codes.mojom.h"
 #include "ui/events/event.h"
 #include "ui/gfx/geometry/rect_f.h"
diff --git a/components/mus/ws/event_matcher_unittest.cc b/components/mus/ws/event_matcher_unittest.cc
index ae9bb15..e4e3b17 100644
--- a/components/mus/ws/event_matcher_unittest.cc
+++ b/components/mus/ws/event_matcher_unittest.cc
@@ -5,7 +5,7 @@
 #include "components/mus/ws/event_matcher.h"
 
 #include "base/time/time.h"
-#include "components/mus/public/interfaces/input_event_matcher.mojom.h"
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/public/interfaces/input_key_codes.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event.h"
diff --git a/components/mus/ws/platform_display.cc b/components/mus/ws/platform_display.cc
index 116d1f3..2da8018f 100644
--- a/components/mus/ws/platform_display.cc
+++ b/components/mus/ws/platform_display.cc
@@ -32,9 +32,9 @@
 #include "services/shell/public/cpp/connector.h"
 #include "third_party/skia/include/core/SkXfermode.h"
 #include "ui/base/cursor/cursor_loader.h"
+#include "ui/display/display.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
-#include "ui/gfx/display.h"
 #include "ui/platform_window/platform_ime_controller.h"
 #include "ui/platform_window/platform_window.h"
 
@@ -316,8 +316,8 @@
 
 void DefaultPlatformDisplay::UpdateMetrics(const gfx::Size& size,
                                            float device_pixel_ratio) {
-  if (gfx::Display::HasForceDeviceScaleFactor())
-    device_pixel_ratio = gfx::Display::GetForcedDeviceScaleFactor();
+  if (display::Display::HasForceDeviceScaleFactor())
+    device_pixel_ratio = display::Display::GetForcedDeviceScaleFactor();
   if (metrics_.size_in_pixels.To<gfx::Size>() == size &&
       metrics_.device_pixel_ratio == device_pixel_ratio)
     return;
diff --git a/components/mus/ws/user_display_manager.cc b/components/mus/ws/user_display_manager.cc
index e54e9b7..979a5d42 100644
--- a/components/mus/ws/user_display_manager.cc
+++ b/components/mus/ws/user_display_manager.cc
@@ -13,7 +13,10 @@
 
 UserDisplayManager::UserDisplayManager(ws::DisplayManager* display_manager,
                                        const UserId& user_id)
-    : display_manager_(display_manager), user_id_(user_id) {
+    : display_manager_(display_manager),
+      user_id_(user_id),
+      current_cursor_location_(0),
+      cursor_location_memory_(nullptr) {
   for (const WindowManagerState* wms : GetWindowManagerStatesForUser()) {
     if (wms->got_frame_decoration_values()) {
       got_valid_frame_decorations_ = true;
@@ -62,6 +65,54 @@
     test_observer_->OnDisplayRemoved(display->id());
 }
 
+void UserDisplayManager::OnMouseCursorLocationChanged(const gfx::Point& point) {
+  current_cursor_location_ =
+      static_cast<base::subtle::Atomic32>(
+          (point.x() & 0xFFFF) << 16 | (point.y() & 0xFFFF));
+  if (cursor_location_memory_) {
+    base::subtle::NoBarrier_Store(cursor_location_memory_,
+                                  current_cursor_location_);
+  }
+}
+
+mojo::ScopedSharedBufferHandle UserDisplayManager::GetCursorLocationMemory() {
+  if (!cursor_location_memory_) {
+    // Create our shared memory segment to share the cursor state with our
+    // window clients.
+    MojoResult result = mojo::CreateSharedBuffer(nullptr,
+                                                 sizeof(base::subtle::Atomic32),
+                                                 &cursor_location_handle_);
+    if (result != MOJO_RESULT_OK)
+      return mojo::ScopedSharedBufferHandle();
+    DCHECK(cursor_location_handle_.is_valid());
+
+    result = mojo::MapBuffer(cursor_location_handle_.get(), 0,
+                             sizeof(base::subtle::Atomic32),
+                             reinterpret_cast<void**>(&cursor_location_memory_),
+                             MOJO_MAP_BUFFER_FLAG_NONE);
+    if (result != MOJO_RESULT_OK)
+      return mojo::ScopedSharedBufferHandle();
+    DCHECK(cursor_location_memory_);
+
+    base::subtle::NoBarrier_Store(cursor_location_memory_,
+                                  current_cursor_location_);
+  }
+
+  mojo::ScopedSharedBufferHandle duped;
+  MojoDuplicateBufferHandleOptions options = {
+    sizeof(MojoDuplicateBufferHandleOptions),
+    MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY
+  };
+  MojoResult result = mojo::DuplicateBuffer(cursor_location_handle_.get(),
+                                            &options, &duped);
+  if (result != MOJO_RESULT_OK)
+    return mojo::ScopedSharedBufferHandle();
+  DCHECK(duped.is_valid());
+
+  return duped;
+}
+
+
 std::set<const WindowManagerState*>
 UserDisplayManager::GetWindowManagerStatesForUser() const {
   std::set<const WindowManagerState*> result;
diff --git a/components/mus/ws/user_display_manager.h b/components/mus/ws/user_display_manager.h
index c17a7c6..65c1787f 100644
--- a/components/mus/ws/user_display_manager.h
+++ b/components/mus/ws/user_display_manager.h
@@ -7,12 +7,17 @@
 
 #include <set>
 
+#include "base/atomicops.h"
 #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 gfx {
+class Point;
+}
+
 namespace mus {
 namespace ws {
 
@@ -39,6 +44,14 @@
   // Called by Display prior to |display| being removed and destroyed.
   void OnWillDestroyDisplay(Display* display);
 
+  // Called from WindowManagerState when its EventDispatcher receives a mouse
+  // event.
+  void OnMouseCursorLocationChanged(const gfx::Point& point);
+
+  // Returns a read-only handle to the shared memory which contains the global
+  // mouse cursor position. Each call returns a new handle.
+  mojo::ScopedSharedBufferHandle GetCursorLocationMemory();
+
  private:
   friend class test::UserDisplayManagerTestApi;
 
@@ -74,6 +87,20 @@
   // Observer used for tests.
   mojom::DisplayManagerObserver* test_observer_ = nullptr;
 
+  // The current location of the cursor. This is always kept up to date so we
+  // can atomically write this to |cursor_location_memory_| once it is created.
+  base::subtle::Atomic32 current_cursor_location_;
+
+  // A handle to a shared memory buffer that is one 64 bit integer long. We
+  // share this with any connection as the same user. This buffer is lazily
+  // created on the first access.
+  mojo::ScopedSharedBufferHandle cursor_location_handle_;
+
+  // The one int32 in |cursor_location_handle_|. When we write to this
+  // location, we must always write to it atomically. (On the other side of the
+  // mojo connection, this data must be read atomically.)
+  base::subtle::Atomic32* cursor_location_memory_;
+
   DISALLOW_COPY_AND_ASSIGN(UserDisplayManager);
 };
 
diff --git a/components/mus/ws/user_display_manager_unittest.cc b/components/mus/ws/user_display_manager_unittest.cc
index f21c84a..549312f 100644
--- a/components/mus/ws/user_display_manager_unittest.cc
+++ b/components/mus/ws/user_display_manager_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/atomicops.h"
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/string_number_conversions.h"
@@ -227,6 +228,38 @@
   UserDisplayManagerTestApi(user_display_manager1).SetTestObserver(nullptr);
 }
 
+TEST_F(UserDisplayManagerTest, NegativeCoordinates) {
+  window_server_delegate_.set_num_displays_to_create(1);
+
+  const UserId kUserId1 = "2";
+  TestDisplayManagerObserver display_manager_observer1;
+  DisplayManager* display_manager = window_server_->display_manager();
+  WindowManagerFactoryRegistryTestApi(
+      window_server_->window_manager_factory_registry())
+      .AddService(kUserId1, &test_window_manager_factory_);
+  UserDisplayManager* user_display_manager1 =
+      display_manager->GetUserDisplayManager(kUserId1);
+  ASSERT_TRUE(user_display_manager1);
+
+  user_display_manager1->OnMouseCursorLocationChanged(gfx::Point(-10, -11));
+
+  base::subtle::Atomic32* cursor_location_memory = nullptr;
+  mojo::ScopedSharedBufferHandle handle =
+      user_display_manager1->GetCursorLocationMemory();
+  MojoResult result = mojo::MapBuffer(
+      handle.get(), 0,
+      sizeof(base::subtle::Atomic32),
+      reinterpret_cast<void**>(&cursor_location_memory),
+      MOJO_MAP_BUFFER_FLAG_NONE);
+  ASSERT_EQ(MOJO_RESULT_OK, result);
+
+  base::subtle::Atomic32 location =
+      base::subtle::NoBarrier_Load(cursor_location_memory);
+  EXPECT_EQ(gfx::Point(static_cast<int16_t>(location >> 16),
+                       static_cast<int16_t>(location & 0xFFFF)),
+            gfx::Point(-10, -11));
+}
+
 }  // 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 7fc9bd2..681a523 100644
--- a/components/mus/ws/window_manager_state.cc
+++ b/components/mus/ws/window_manager_state.cc
@@ -369,6 +369,11 @@
   window_server()->ProcessLostCapture(window);
 }
 
+void WindowManagerState::OnMouseCursorLocationChanged(const gfx::Point& point) {
+  window_server()->display_manager()->GetUserDisplayManager(user_id_)->
+      OnMouseCursorLocationChanged(point);
+}
+
 void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target,
                                                     bool in_nonclient_area,
                                                     const ui::Event& event,
diff --git a/components/mus/ws/window_manager_state.h b/components/mus/ws/window_manager_state.h
index 4af382a..8f967343 100644
--- a/components/mus/ws/window_manager_state.h
+++ b/components/mus/ws/window_manager_state.h
@@ -160,6 +160,7 @@
   void SetNativeCapture() override;
   void ReleaseNativeCapture() override;
   void OnServerWindowCaptureLost(ServerWindow* window) override;
+  void OnMouseCursorLocationChanged(const gfx::Point& point) override;
   void DispatchInputEventToWindow(ServerWindow* target,
                                   bool in_nonclient_area,
                                   const ui::Event& event,
diff --git a/components/mus/ws/window_tree.cc b/components/mus/ws/window_tree.cc
index 0114bf5e..14e6a6e 100644
--- a/components/mus/ws/window_tree.cc
+++ b/components/mus/ws/window_tree.cc
@@ -21,6 +21,7 @@
 #include "components/mus/ws/platform_display.h"
 #include "components/mus/ws/server_window.h"
 #include "components/mus/ws/server_window_observer.h"
+#include "components/mus/ws/user_display_manager.h"
 #include "components/mus/ws/window_manager_state.h"
 #include "components/mus/ws/window_server.h"
 #include "components/mus/ws/window_tree_binding.h"
@@ -1331,6 +1332,13 @@
           this, std::move(internal)));
 }
 
+void WindowTree::GetCursorLocationMemory(
+    const GetCursorLocationMemoryCallback& callback) {
+  callback.Run(
+      window_server_->display_manager()->GetUserDisplayManager(user_id_)->
+      GetCursorLocationMemory());
+}
+
 void WindowTree::AddAccelerator(uint32_t id,
                                 mojom::EventMatcherPtr event_matcher,
                                 const AddAcceleratorCallback& callback) {
diff --git a/components/mus/ws/window_tree.h b/components/mus/ws/window_tree.h
index 43639d2..0743e5c 100644
--- a/components/mus/ws/window_tree.h
+++ b/components/mus/ws/window_tree.h
@@ -384,6 +384,8 @@
   void GetWindowManagerClient(
       mojo::AssociatedInterfaceRequest<mojom::WindowManagerClient> internal)
       override;
+  void GetCursorLocationMemory(const GetCursorLocationMemoryCallback& callback)
+      override;
 
   // mojom::WindowManagerClient:
   void AddAccelerator(uint32_t id,
diff --git a/components/ntp_snippets/BUILD.gn b/components/ntp_snippets/BUILD.gn
index 1bfdf1f1..865a914c 100644
--- a/components/ntp_snippets/BUILD.gn
+++ b/components/ntp_snippets/BUILD.gn
@@ -29,6 +29,10 @@
     "//net",
     "//url",
   ]
+
+  deps = [
+    "//components/metrics",
+  ]
 }
 
 source_set("unit_tests") {
@@ -41,6 +45,7 @@
   deps = [
     ":ntp_snippets",
     "//base",
+    "//base/test:test_support",
     "//components/signin/core/browser:test_support",
     "//net:test_support",
     "//testing/gtest",
diff --git a/components/ntp_snippets/DEPS b/components/ntp_snippets/DEPS
index 38ff3b8..e58b5681 100644
--- a/components/ntp_snippets/DEPS
+++ b/components/ntp_snippets/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+components/keyed_service/core",
+  "+components/metrics",
   "+components/prefs",
   "+components/signin",
   "+components/suggestions",
diff --git a/components/ntp_snippets/ntp_snippets_service.cc b/components/ntp_snippets/ntp_snippets_service.cc
index af047ac3..96abae0 100644
--- a/components/ntp_snippets/ntp_snippets_service.cc
+++ b/components/ntp_snippets/ntp_snippets_service.cc
@@ -13,6 +13,7 @@
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
 #include "base/location.h"
+#include "base/metrics/sparse_histogram.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
@@ -494,6 +495,9 @@
       discarded_snippets_.end());
   StoreDiscardedSnippetsToPrefs();
 
+  UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticles",
+                              snippets_.size());
+
   FOR_EACH_OBSERVER(NTPSnippetsServiceObserver, observers_,
                     NTPSnippetsServiceLoaded());
 
diff --git a/components/ntp_snippets/ntp_snippets_service_unittest.cc b/components/ntp_snippets/ntp_snippets_service_unittest.cc
index b8f4e71..a453305 100644
--- a/components/ntp_snippets/ntp_snippets_service_unittest.cc
+++ b/components/ntp_snippets/ntp_snippets_service_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/histogram_tester.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "components/ntp_snippets/ntp_snippet.h"
@@ -386,4 +387,27 @@
   EXPECT_EQ(service()->size(), 0u);
 }
 
+TEST_F(NTPSnippetsServiceTest, LogNumArticlesHistogram) {
+  base::HistogramTester tester;
+  SetExpectJsonParseSuccess(false);
+  LoadFromJSONString(GetInvalidJson());
+  tester.ExpectUniqueSample("NewTabPage.Snippets.NumArticles", /*sample=*/0,
+                            /*expected_count=*/1);
+  SetExpectJsonParseSuccess(true);
+  LoadFromJSONString(GetTestJson());
+  tester.ExpectBucketCount("NewTabPage.Snippets.NumArticles", /*sample=*/1,
+                            /*expected_count=*/1);
+  // Duplicate snippet shouldn't increase the list size.
+  LoadFromJSONString(GetTestJson());
+  tester.ExpectBucketCount("NewTabPage.Snippets.NumArticles", /*sample=*/1,
+                            /*expected_count=*/2);
+  // Discarding a snippet should decrease the list size. This will only be
+  // logged after the next fetch.
+  EXPECT_TRUE(service()->DiscardSnippet(GURL("http://localhost/foobar")));
+  LoadFromJSONString(GetTestJson());
+  tester.ExpectBucketCount("NewTabPage.Snippets.NumArticles", /*sample=*/0,
+                            /*expected_count=*/2);
+  tester.ExpectTotalCount("NewTabPage.Snippets.NumArticles", 4);
+}
+
 }  // namespace ntp_snippets
diff --git a/components/ntp_tiles.gypi b/components/ntp_tiles.gypi
new file mode 100644
index 0000000..a02ab06
--- /dev/null
+++ b/components/ntp_tiles.gypi
@@ -0,0 +1,25 @@
+# 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': [
+    {
+      # GN version: //components/ntp_tiles
+      'target_name': 'ntp_tiles',
+      'type': 'static_library',
+      'include_dirs': [
+        '..',
+      ],
+      'dependencies': [
+        '../base/base.gyp:base',
+      ],
+      'sources': [
+        'ntp_tiles/pref_names.h',
+        'ntp_tiles/pref_names.cc',
+        'ntp_tiles/switches.h',
+        'ntp_tiles/switches.cc',
+      ],
+    },
+  ],
+}
diff --git a/components/ntp_tiles/BUILD.gn b/components/ntp_tiles/BUILD.gn
new file mode 100644
index 0000000..e524f62
--- /dev/null
+++ b/components/ntp_tiles/BUILD.gn
@@ -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.
+
+# GYP version: components/ntp_tiles.gypi:ntp_tiles
+source_set("ntp_tiles") {
+  sources = [
+    "pref_names.cc",
+    "pref_names.h",
+    "switches.cc",
+    "switches.h",
+  ]
+
+  public_deps = [
+    "//base",
+  ]
+}
diff --git a/components/ntp_tiles/OWNERS b/components/ntp_tiles/OWNERS
new file mode 100644
index 0000000..f0b684f
--- /dev/null
+++ b/components/ntp_tiles/OWNERS
@@ -0,0 +1,2 @@
+bauerb@chromium.org
+treib@chromium.org
diff --git a/components/ntp_tiles/pref_names.cc b/components/ntp_tiles/pref_names.cc
new file mode 100644
index 0000000..b1f9fe5
--- /dev/null
+++ b/components/ntp_tiles/pref_names.cc
@@ -0,0 +1,18 @@
+// 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/ntp_tiles/pref_names.h"
+
+namespace ntp_tiles {
+namespace prefs {
+
+// Ordered list of website suggestions shown on the new tab page that will allow
+// retaining the order even if the suggestions change over time.
+const char kNTPSuggestionsURL[] = "ntp.suggestions_url";
+
+// Whether the suggestion was derived from personal data.
+const char kNTPSuggestionsIsPersonal[] = "ntp.suggestions_is_personal";
+
+}  // namespace prefs
+}  // namespace ntp_tiles
diff --git a/components/ntp_tiles/pref_names.h b/components/ntp_tiles/pref_names.h
new file mode 100644
index 0000000..b71b19f
--- /dev/null
+++ b/components/ntp_tiles/pref_names.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 COMPONENTS_NTP_TILES_PREF_NAMES_H_
+#define COMPONENTS_NTP_TILES_PREF_NAMES_H_
+
+namespace ntp_tiles {
+namespace prefs {
+
+extern const char kNTPSuggestionsURL[];
+extern const char kNTPSuggestionsIsPersonal[];
+
+}  // namespace prefs
+}  // namespace ntp_tiles
+
+#endif  // COMPONENTS_NTP_TILES_PREF_NAMES_H_
diff --git a/components/ntp_tiles/switches.cc b/components/ntp_tiles/switches.cc
new file mode 100644
index 0000000..6a76ba1
--- /dev/null
+++ b/components/ntp_tiles/switches.cc
@@ -0,0 +1,22 @@
+// 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/ntp_tiles/switches.h"
+
+namespace ntp_tiles {
+namespace switches {
+
+// Enables using the default search engine country to show country specific
+// popular sites on the NTP.
+const char kEnableNTPSearchEngineCountryDetection[] =
+    "enable-ntp-search-engine-country-detection";
+
+// Enables showing popular sites on the NTP.
+const char kEnableNTPPopularSites[]         = "enable-ntp-popular-sites";
+
+// Disables showing popular sites on the NTP.
+const char kDisableNTPPopularSites[]        = "disable-ntp-popular-sites";
+
+}  // namespace switches
+}  // namespace ntp_tiles
diff --git a/components/ntp_tiles/switches.h b/components/ntp_tiles/switches.h
new file mode 100644
index 0000000..2405e7d1
--- /dev/null
+++ b/components/ntp_tiles/switches.h
@@ -0,0 +1,19 @@
+// 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_NTP_TILES_SWITCHES_H_
+#define COMPONENTS_NTP_TILES_SWITCHES_H_
+
+namespace ntp_tiles {
+namespace switches {
+
+extern const char kEnableNTPSearchEngineCountryDetection[];
+
+extern const char kEnableNTPPopularSites[];
+extern const char kDisableNTPPopularSites[];
+
+}  // namespace switches
+}  // namespace ntp_tiles
+
+#endif  // COMPONENTS_NTP_TILES_SWITCHES_H_
diff --git a/components/page_load_metrics/common/page_load_metrics_messages.h b/components/page_load_metrics/common/page_load_metrics_messages.h
index 4f4c6d22..d71a376 100644
--- a/components/page_load_metrics/common/page_load_metrics_messages.h
+++ b/components/page_load_metrics/common/page_load_metrics_messages.h
@@ -38,4 +38,4 @@
 // associated frame changed.
 IPC_MESSAGE_ROUTED2(PageLoadMetricsMsg_TimingUpdated,
                     page_load_metrics::PageLoadTiming,
-                    page_load_metrics::PageLoadMetadata);
+                    page_load_metrics::PageLoadMetadata)
diff --git a/components/password_manager/content/browser/credential_manager_impl_unittest.cc b/components/password_manager/content/browser/credential_manager_impl_unittest.cc
index 4286c6e8..66c30d3 100644
--- a/components/password_manager/content/browser/credential_manager_impl_unittest.cc
+++ b/components/password_manager/content/browser/credential_manager_impl_unittest.cc
@@ -249,6 +249,14 @@
     origin_path_form_.scheme = autofill::PasswordForm::SCHEME_HTML;
     origin_path_form_.skip_zero_click = false;
 
+    subdomain_form_.username_value = base::ASCIIToUTF16("Username 2");
+    subdomain_form_.display_name = base::ASCIIToUTF16("Display Name 2");
+    subdomain_form_.password_value = base::ASCIIToUTF16("Password 2");
+    subdomain_form_.origin = GURL("https://subdomain.example.com/path");
+    subdomain_form_.signon_realm = subdomain_form_.origin.spec();
+    subdomain_form_.scheme = autofill::PasswordForm::SCHEME_HTML;
+    subdomain_form_.skip_zero_click = false;
+
     cross_origin_form_.username_value = base::ASCIIToUTF16("Username");
     cross_origin_form_.display_name = base::ASCIIToUTF16("Display Name");
     cross_origin_form_.password_value = base::ASCIIToUTF16("Password");
@@ -354,6 +362,7 @@
   autofill::PasswordForm affiliated_form1_;
   autofill::PasswordForm affiliated_form2_;
   autofill::PasswordForm origin_path_form_;
+  autofill::PasswordForm subdomain_form_;
   autofill::PasswordForm cross_origin_form_;
   scoped_refptr<TestPasswordStore> store_;
   std::unique_ptr<testing::NiceMock<MockPasswordManagerClient>> client_;
@@ -540,14 +549,17 @@
 
 TEST_F(CredentialManagerImplTest, CredentialManagerOnRequireUserMediation) {
   store_->AddLogin(form_);
+  store_->AddLogin(subdomain_form_);
   store_->AddLogin(cross_origin_form_);
   RunAllPendingTasks();
 
   TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
-  EXPECT_EQ(2U, passwords.size());
+  EXPECT_EQ(3U, passwords.size());
   EXPECT_EQ(1U, passwords[form_.signon_realm].size());
+  EXPECT_EQ(1U, passwords[subdomain_form_.signon_realm].size());
   EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
   EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
+  EXPECT_FALSE(passwords[subdomain_form_.signon_realm][0].skip_zero_click);
   EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
 
   bool called = false;
@@ -558,10 +570,12 @@
   EXPECT_TRUE(called);
 
   passwords = store_->stored_passwords();
-  EXPECT_EQ(2U, passwords.size());
+  EXPECT_EQ(3U, passwords.size());
   EXPECT_EQ(1U, passwords[form_.signon_realm].size());
+  EXPECT_EQ(1U, passwords[subdomain_form_.signon_realm].size());
   EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
   EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
+  EXPECT_TRUE(passwords[subdomain_form_.signon_realm][0].skip_zero_click);
   EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
 }
 
diff --git a/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc b/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc
index 9a2aba77..8cf5b31 100644
--- a/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc
+++ b/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.cc
@@ -7,6 +7,7 @@
 #include "components/autofill/core/common/password_form.h"
 #include "components/password_manager/core/browser/affiliated_match_helper.h"
 #include "components/password_manager/core/browser/password_store.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "url/gurl.h"
 
 namespace password_manager {
@@ -18,7 +19,10 @@
         const std::vector<std::string>& affiliated_realms)
     : delegate_(delegate),
       affiliated_realms_(affiliated_realms.begin(), affiliated_realms.end()) {
-  origins_.insert(origin.spec());
+  registrable_domains_.insert(
+      net::registry_controlled_domains::GetDomainAndRegistry(
+          origin,
+          net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
 }
 
 CredentialManagerPendingRequireUserMediationTask::
@@ -26,14 +30,21 @@
 
 void CredentialManagerPendingRequireUserMediationTask::AddOrigin(
     const GURL& origin) {
-  origins_.insert(origin.spec());
+  registrable_domains_.insert(
+      net::registry_controlled_domains::GetDomainAndRegistry(
+          origin,
+          net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
 }
 
 void CredentialManagerPendingRequireUserMediationTask::
     OnGetPasswordStoreResults(ScopedVector<autofill::PasswordForm> results) {
   PasswordStore* store = delegate_->GetPasswordStore();
   for (autofill::PasswordForm* form : results) {
-    if (origins_.count(form->origin.spec()) ||
+    std::string form_registrable_domain =
+        net::registry_controlled_domains::GetDomainAndRegistry(
+            form->origin,
+            net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+    if (registrable_domains_.count(form_registrable_domain) ||
         (affiliated_realms_.count(form->signon_realm) &&
          AffiliatedMatchHelper::IsValidAndroidCredential(*form))) {
       form->skip_zero_click = true;
diff --git a/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h b/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h
index 8bc8b028..a5deeac 100644
--- a/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h
+++ b/components/password_manager/core/browser/credential_manager_pending_require_user_mediation_task.h
@@ -52,7 +52,7 @@
  private:
   CredentialManagerPendingRequireUserMediationTaskDelegate* const
       delegate_;  // Weak.
-  std::set<std::string> origins_;
+  std::set<std::string> registrable_domains_;
   std::set<std::string> affiliated_realms_;
 
   DISALLOW_COPY_AND_ASSIGN(CredentialManagerPendingRequireUserMediationTask);
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.cc b/components/policy/core/common/cloud/cloud_policy_constants.cc
index fed1477..be383dbf 100644
--- a/components/policy/core/common/cloud/cloud_policy_constants.cc
+++ b/components/policy/core/common/cloud/cloud_policy_constants.cc
@@ -44,6 +44,7 @@
     "device_attribute_update_permission";
 const char kValueRequestDeviceAttributeUpdate[] = "device_attribute_update";
 const char kValueRequestGcmIdUpdate[] = "gcm_id_update";
+const char kValueRequestCheckAndroidManagement[] = "check_android_management";
 
 const char kChromeDevicePolicyType[] = "google/chromeos/device";
 #if defined(OS_CHROMEOS)
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h
index e1a9134..7535eeb 100644
--- a/components/policy/core/common/cloud/cloud_policy_constants.h
+++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -42,6 +42,7 @@
 POLICY_EXPORT extern const char kValueRequestDeviceAttributeUpdatePermission[];
 POLICY_EXPORT extern const char kValueRequestDeviceAttributeUpdate[];
 POLICY_EXPORT extern const char kValueRequestGcmIdUpdate[];
+POLICY_EXPORT extern const char kValueRequestCheckAndroidManagement[];
 
 // Policy type strings for the policy_type field in PolicyFetchRequest.
 POLICY_EXPORT extern const char kChromeDevicePolicyType[];
diff --git a/components/policy/core/common/cloud/device_management_service.cc b/components/policy/core/common/cloud/device_management_service.cc
index 1a95f36..e6ccd96 100644
--- a/components/policy/core/common/cloud/device_management_service.cc
+++ b/components/policy/core/common/cloud/device_management_service.cc
@@ -127,6 +127,8 @@
       return dm_protocol::kValueRequestDeviceAttributeUpdate;
     case DeviceManagementRequestJob::TYPE_GCM_ID_UPDATE:
       return dm_protocol::kValueRequestGcmIdUpdate;
+    case DeviceManagementRequestJob::TYPE_ANDROID_MANAGEMENT_CHECK:
+      return dm_protocol::kValueRequestCheckAndroidManagement;
   }
   NOTREACHED() << "Invalid job type " << type;
   return "";
diff --git a/components/policy/core/common/cloud/device_management_service.h b/components/policy/core/common/cloud/device_management_service.h
index 5a405f0..cbec90f 100644
--- a/components/policy/core/common/cloud/device_management_service.h
+++ b/components/policy/core/common/cloud/device_management_service.h
@@ -53,6 +53,7 @@
     TYPE_ATTRIBUTE_UPDATE_PERMISSION,
     TYPE_ATTRIBUTE_UPDATE,
     TYPE_GCM_ID_UPDATE,
+    TYPE_ANDROID_MANAGEMENT_CHECK,
   };
 
   typedef base::Callback<
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index cd5e9b08..753e9ed 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -1030,6 +1030,17 @@
 // Response for GcmIdUpdateRequest, an empty message for now.
 message GcmIdUpdateResponse {}
 
+// Request from device to server to check for Android-for-Work service with
+// DPC enforcement. Must be sent only for users who are not managed in Chrome
+// OS.
+// Provide user's OAuth token with your HTTP Request.
+message CheckAndroidManagementRequest {}
+
+// Response from server to device for check for Android-for-Work service with
+// DPC enforcement request.
+// SC_CONFLICT HTTP code is returned if DPC enforcement is required.
+message CheckAndroidManagementResponse {}
+
 // Request from the DMAgent on the device to the DMServer.  This is
 // container for all requests from device to server.  The overall HTTP
 // request MUST be in the following format:
@@ -1053,13 +1064,14 @@
 //     * attribute_update_permission
 //     * attribute_update
 //     * gcm_id_update
+//     * check_android_management
 //
 //   * devicetype: MUST BE "1" for Android or "2" for Chrome OS.
 //   * apptype: MUST BE Android or Chrome.
 //   * deviceid: MUST BE no more than 64-char in [\x21-\x7E].
 //   * agent: MUST BE a string of characters.
 // * HTTP Authorization header MUST be in the following formats:
-//   * For register and ping requests
+//   * For register, ping and check_android_management requests
 //     Authorization: GoogleLogin auth=<auth cookie for Mobile Sync>
 //
 //   * For unregister, policy, status, cert_upload, remote commands requests,
@@ -1087,6 +1099,7 @@
 //   attribute_update_permission: device_attribute_update_permission_request
 //   attribute_update: device_attribute_update_request
 //   gcm_id_update: gcm_id_update_request
+//   check_android_management: check_android_management_request
 //
 message DeviceManagementRequest {
   // Register request.
@@ -1136,6 +1149,9 @@
 
   // Update the GCM id to device_id mapping.
   optional GcmIdUpdateRequest gcm_id_update_request = 16;
+
+  // Check if user is a managed Android-for-Work user with DPC enforcement.
+  optional CheckAndroidManagementRequest check_android_management_request = 17;
 }
 
 // Response from server to device.
@@ -1203,4 +1219,8 @@
 
   // Response to GCM id update request.
   optional GcmIdUpdateResponse gcm_id_update_response = 17;
+
+  // Response to check Android management request.
+  optional CheckAndroidManagementResponse
+      check_android_management_response = 18;
 }
diff --git a/components/resource_provider/android/android_hooks.cc b/components/resource_provider/android/android_hooks.cc
index b312e1af..4cf2687 100644
--- a/components/resource_provider/android/android_hooks.cc
+++ b/components/resource_provider/android/android_hooks.cc
@@ -46,6 +46,7 @@
 extern "C" JNI_EXPORT void InitApplicationContext(
     const base::android::JavaRef<jobject>& context) {
   JNIEnv* env = base::android::AttachCurrentThread();
+  base::android::InitApplicationContext(env, context);
   resource_provider::Java_Main_init(
       env, base::android::GetApplicationContext());
 }
diff --git a/components/resource_provider/android/java/org/chromium/resource_provider/Main.java b/components/resource_provider/android/java/org/chromium/resource_provider/Main.java
index a65e6917..6395262 100644
--- a/components/resource_provider/android/java/org/chromium/resource_provider/Main.java
+++ b/components/resource_provider/android/java/org/chromium/resource_provider/Main.java
@@ -6,7 +6,6 @@
 
 import android.content.Context;
 
-import org.chromium.base.ContextUtils;
 import org.chromium.base.PathUtils;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
@@ -23,7 +22,6 @@
     @SuppressWarnings("unused")
     @CalledByNative
     private static void init(Context context) {
-        ContextUtils.initApplicationContext(context.getApplicationContext());
         PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX, context);
     }
 }
diff --git a/components/suggestions.gypi b/components/suggestions.gypi
index dbbfe64d..f5fd5fc3 100644
--- a/components/suggestions.gypi
+++ b/components/suggestions.gypi
@@ -17,6 +17,7 @@
         '../ui/gfx/gfx.gyp:gfx',
         '../url/url.gyp:url_lib',
         'components.gyp:data_use_measurement_core',
+        'components.gyp:image_fetcher',
         'components.gyp:keyed_service_core',
         'components.gyp:pref_registry',
         'components.gyp:sync_driver',
@@ -27,8 +28,6 @@
         'suggestions/blacklist_store.cc',
         'suggestions/blacklist_store.h',
         'suggestions/image_encoder.h',
-        'suggestions/image_fetcher.h',
-        'suggestions/image_fetcher_delegate.h',
         'suggestions/image_manager.cc',
         'suggestions/image_manager.h',
         'suggestions/proto/suggestions.proto',
diff --git a/components/suggestions/BUILD.gn b/components/suggestions/BUILD.gn
index e33d5f1..40ac92f 100644
--- a/components/suggestions/BUILD.gn
+++ b/components/suggestions/BUILD.gn
@@ -7,8 +7,6 @@
     "blacklist_store.cc",
     "blacklist_store.h",
     "image_encoder.h",
-    "image_fetcher.h",
-    "image_fetcher_delegate.h",
     "image_manager.cc",
     "image_manager.h",
     "suggestions_pref_names.cc",
@@ -30,6 +28,7 @@
   deps = [
     "//components/data_use_measurement/core",
     "//components/google/core/browser",
+    "//components/image_fetcher",
     "//components/keyed_service/core",
     "//components/leveldb_proto",
     "//components/pref_registry",
@@ -58,6 +57,7 @@
   deps = [
     ":suggestions",
     "//base/test:test_support",
+    "//components/image_fetcher",
     "//components/leveldb_proto:test_support",
     "//components/pref_registry:test_support",
     "//components/signin/core/browser:test_support",
diff --git a/components/suggestions/DEPS b/components/suggestions/DEPS
index db8a80f..c3f0589 100644
--- a/components/suggestions/DEPS
+++ b/components/suggestions/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   "+components/data_use_measurement/core",
   "+components/google/core/browser",
+  "+components/image_fetcher",
   "+components/keyed_service/core",
   "+components/leveldb_proto",
   "+components/pref_registry",
diff --git a/components/suggestions/image_manager.cc b/components/suggestions/image_manager.cc
index 9ea21c0..440813c 100644
--- a/components/suggestions/image_manager.cc
+++ b/components/suggestions/image_manager.cc
@@ -10,8 +10,8 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/task_runner_util.h"
+#include "components/image_fetcher/image_fetcher.h"
 #include "components/suggestions/image_encoder.h"
-#include "components/suggestions/image_fetcher.h"
 
 using leveldb_proto::ProtoDatabase;
 
@@ -36,7 +36,7 @@
 ImageManager::ImageManager() : weak_ptr_factory_(this) {}
 
 ImageManager::ImageManager(
-    std::unique_ptr<ImageFetcher> image_fetcher,
+    std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
     std::unique_ptr<ProtoDatabase<ImageData>> database,
     const base::FilePath& database_dir,
     scoped_refptr<base::TaskRunner> background_task_runner)
diff --git a/components/suggestions/image_manager.h b/components/suggestions/image_manager.h
index 99ad131..b72f76c 100644
--- a/components/suggestions/image_manager.h
+++ b/components/suggestions/image_manager.h
@@ -18,12 +18,16 @@
 #include "base/memory/weak_ptr.h"
 #include "base/task_runner.h"
 #include "base/threading/thread_checker.h"
+#include "components/image_fetcher/image_fetcher_delegate.h"
 #include "components/leveldb_proto/proto_database.h"
-#include "components/suggestions/image_fetcher_delegate.h"
 #include "components/suggestions/proto/suggestions.pb.h"
 #include "ui/gfx/image/image_skia.h"
 #include "url/gurl.h"
 
+namespace image_fetcher {
+class ImageFetcher;
+}
+
 namespace net {
 class URLRequestContextGetter;
 }
@@ -31,17 +35,16 @@
 namespace suggestions {
 
 class ImageData;
-class ImageFetcher;
 class SuggestionsProfile;
 
 // A class used to fetch server images asynchronously and manage the caching
 // layer (both in memory and on disk).
-class ImageManager : public ImageFetcherDelegate {
+class ImageManager : public image_fetcher::ImageFetcherDelegate {
  public:
   typedef std::vector<ImageData> ImageDataVector;
 
   ImageManager(
-      std::unique_ptr<ImageFetcher> image_fetcher,
+      std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher,
       std::unique_ptr<leveldb_proto::ProtoDatabase<ImageData>> database,
       const base::FilePath& database_dir,
       scoped_refptr<base::TaskRunner> background_task_runner);
@@ -142,7 +145,7 @@
   // Holding the bitmaps in memory, keyed by website URL string.
   ImageMap image_map_;
 
-  std::unique_ptr<ImageFetcher> image_fetcher_;
+  std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
 
   std::unique_ptr<leveldb_proto::ProtoDatabase<ImageData>> database_;
 
diff --git a/components/suggestions/image_manager_unittest.cc b/components/suggestions/image_manager_unittest.cc
index 29d0d19..28398c3 100644
--- a/components/suggestions/image_manager_unittest.cc
+++ b/components/suggestions/image_manager_unittest.cc
@@ -11,11 +11,11 @@
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/thread_task_runner_handle.h"
+#include "components/image_fetcher/image_fetcher.h"
+#include "components/image_fetcher/image_fetcher_delegate.h"
 #include "components/leveldb_proto/proto_database.h"
 #include "components/leveldb_proto/testing/fake_db.h"
 #include "components/suggestions/image_encoder.h"
-#include "components/suggestions/image_fetcher.h"
-#include "components/suggestions/image_fetcher_delegate.h"
 #include "components/suggestions/proto/suggestions.pb.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -26,6 +26,9 @@
 using ::testing::StrictMock;
 using ::testing::_;
 
+using image_fetcher::ImageFetcher;
+using image_fetcher::ImageFetcherDelegate;
+
 namespace suggestions {
 
 const char kTestUrl1[] = "http://go.com/";
@@ -34,14 +37,12 @@
 const char kInvalidImagePath[] = "files/DOESNOTEXIST";
 
 using leveldb_proto::test::FakeDB;
-using suggestions::ImageData;
-using suggestions::ImageManager;
 
 typedef base::hash_map<std::string, ImageData> EntryMap;
 
 void AddEntry(const ImageData& d, EntryMap* map) { (*map)[d.url()] = d; }
 
-class MockImageFetcher : public suggestions::ImageFetcher {
+class MockImageFetcher : public ImageFetcher {
  public:
   MockImageFetcher() {}
   virtual ~MockImageFetcher() {}
diff --git a/components/sync_driver/device_info_service_unittest.cc b/components/sync_driver/device_info_service_unittest.cc
index 1ce08c9..8b0f726 100644
--- a/components/sync_driver/device_info_service_unittest.cc
+++ b/components/sync_driver/device_info_service_unittest.cc
@@ -302,6 +302,11 @@
     service_.reset();
   }
 
+  void RestartService() {
+    PumpAndShutdown();
+    InitializeAndPump();
+  }
+
   Time GetLastUpdateTime(const DeviceInfoSpecifics& specifics) {
     return DeviceInfoService::GetLastUpdateTime(specifics);
   }
@@ -309,10 +314,7 @@
  private:
   int change_count_;
 
-  // Although we never use this in this class, the in memory model type store
-  // grabs the current task runner from a static accessor which point at this
-  // message loop. Must be declared/initilized before we call the synchronous
-  // CreateInMemoryStoreForTest.
+  // In memory model type store needs a MessageLoop.
   base::MessageLoop message_loop_;
 
   // Holds the store while the service is not initialized.
@@ -572,18 +574,16 @@
   EXPECT_FALSE(error.IsSet());
   EXPECT_EQ(1, change_count());
 
-  PumpAndShutdown();
-  InitializeAndPump();
+  RestartService();
 
   std::unique_ptr<DeviceInfo> info =
       service()->GetDeviceInfo(specifics.cache_guid());
   ASSERT_TRUE(info);
   AssertEqual(specifics, *info.get());
-  // TODO(skym): Uncomment once SimpleMetadataChangeList::TransferChanges is
-  // implemented.
-  // EXPECT_TRUE(processor()->metadata());
-  // EXPECT_EQ(state.encryption_key_name(),
-  // processor()->metadata()->GetDataTypeState().encryption_key_name());
+
+  EXPECT_TRUE(processor()->metadata());
+  EXPECT_EQ(state.encryption_key_name(),
+            processor()->metadata()->GetDataTypeState().encryption_key_name());
 }
 
 TEST_F(DeviceInfoServiceTest, ApplySyncChangesWithLocalGuid) {
@@ -703,10 +703,9 @@
   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());
+  RestartService();
+  ASSERT_EQ(state.encryption_key_name(),
+            processor()->metadata()->GetDataTypeState().encryption_key_name());
 }
 
 TEST_F(DeviceInfoServiceTest, MergeLocalGuid) {
diff --git a/components/test/data/autofill/merge/tools/autofill_merge_common.py b/components/test/data/autofill/merge/tools/autofill_merge_common.py
index 6a4a788..bbf5008 100644
--- a/components/test/data/autofill/merge/tools/autofill_merge_common.py
+++ b/components/test/data/autofill/merge/tools/autofill_merge_common.py
@@ -41,7 +41,8 @@
 
   column_name = column_name.lower()
   field_type = "unknown"
-  if column_name in ["guid", "label", "country", "date_modified"]:
+  if column_name in ["guid", "label", "country", "date_modified", "origin",
+      "language_code", "use_count", "use_date"]:
     field_type = "ignored"
   elif column_name == "first_name":
     field_type = "NAME_FIRST"
@@ -49,6 +50,8 @@
     field_type = "NAME_MIDDLE"
   elif column_name == "last_name":
     field_type = "NAME_LAST"
+  elif column_name == "full_name":
+    field_type = "NAME_FULL"
   elif column_name == "email":
     field_type = "EMAIL_ADDRESS"
   elif column_name == "company_name":
@@ -57,6 +60,8 @@
     field_type = "ADDRESS_HOME_LINE1"
   elif column_name == "address_line_2":
     field_type = "ADDRESS_HOME_LINE2"
+  elif column_name == "street_address":
+    field_type = "ADDRESS_HOME_STREET_ADDRESS"
   elif column_name == "city":
     field_type = "ADDRESS_HOME_CITY"
   elif column_name == "state":
@@ -65,6 +70,10 @@
     field_type = "ADDRESS_HOME_ZIP"
   elif column_name == "country_code":
     field_type = "ADDRESS_HOME_COUNTRY"
+  elif column_name == "sorting_code":
+    field_type = "ADDRESS_HOME_SORTING_CODE"
+  elif column_name == "dependent_locality":
+    field_type = "ADDRESS_HOME_DEPENDENT_LOCALITY"
   elif column_name == "phone":
     field_type = "PHONE_HOME_WHOLE_NUMBER"
   else:
diff --git a/components/test/data/autofill/merge/tools/serialize_profiles.py b/components/test/data/autofill/merge/tools/serialize_profiles.py
index 18df1f2..ff3fb45 100755
--- a/components/test/data/autofill/merge/tools/serialize_profiles.py
+++ b/components/test/data/autofill/merge/tools/serialize_profiles.py
@@ -76,7 +76,7 @@
 
   for profile in cursor:
     guid = profile[0]
-    profiles[guid].append(("PHONE_HOME_WHOLE_NUMBER", profile[2]))
+    profiles[guid].append(("PHONE_HOME_WHOLE_NUMBER", profile[1]))
 
   print SerializeProfiles(profiles.values())
   return 0
diff --git a/components/test_runner/BUILD.gn b/components/test_runner/BUILD.gn
index 6973f1e..7cd8530 100644
--- a/components/test_runner/BUILD.gn
+++ b/components/test_runner/BUILD.gn
@@ -158,20 +158,24 @@
     ]
   }
 }
+if (is_mac) {
+  bundle_data("test_runner_bundle_data") {
+    sources = [
+      "resources/fonts/AHEM____.TTF",
+      "resources/fonts/ChromiumAATTest.ttf",
+    ]
+
+    outputs = [
+      "{{bundle_resources_dir}}/{{source_file_part}}",
+    ]
+  }
+}
 
 group("resources") {
   deps = []
 
   if (is_mac) {
-    # TODO(GYP) Mac bundle resources.
-    #'all_dependent_settings': {
-    #  'mac_bundle_resources': [
-    #    'resources/fonts/AHEM____.TTF',
-    #    'resources/fonts/ChromiumAATTest.ttf',
-    #    '<(SHARED_INTERMEDIATE_DIR)/webkit/missingImage.png',
-    #    '<(SHARED_INTERMEDIATE_DIR)/webkit/textAreaResizeCorner.png',
-    #  ],
-    #},
+    deps += [ ":test_runner_bundle_data" ]
   } else {
     deps += [ ":copy_ahem" ]
   }
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc
index 0a968910..2f310fc 100644
--- a/components/user_manager/fake_user_manager.cc
+++ b/components/user_manager/fake_user_manager.cc
@@ -59,7 +59,8 @@
   while (it != users_.end() && (*it)->GetEmail() != account_id.GetUserEmail())
     ++it;
   if (it != users_.end()) {
-    delete *it;
+    if (active_user_ != *it)
+      delete *it;
     users_.erase(it);
   }
 }
@@ -101,6 +102,9 @@
 }
 
 user_manager::User* FakeUserManager::GetActiveUserInternal() const {
+  if (active_user_ != nullptr)
+    return active_user_;
+
   if (!users_.empty()) {
     if (active_account_id_.is_valid()) {
       for (user_manager::UserList::const_iterator it = users_.begin();
@@ -155,14 +159,16 @@
 
 const user_manager::User* FakeUserManager::FindUser(
     const AccountId& account_id) const {
+  if (active_user_ != nullptr && active_user_->GetAccountId() == account_id)
+    return active_user_;
+
   const user_manager::UserList& users = GetUsers();
   for (user_manager::UserList::const_iterator it = users.begin();
        it != users.end(); ++it) {
-    // TODO (alemate): Chenge this to GetAccountId(), once a real AccountId is
-    // passed. crbug.com/546876
-    if ((*it)->GetEmail() == account_id.GetUserEmail())
+    if ((*it)->GetAccountId() == account_id)
       return *it;
   }
+
   return nullptr;
 }
 
@@ -271,7 +277,7 @@
 }
 
 bool FakeUserManager::IsDemoApp(const AccountId& account_id) const {
-  return false;
+  return account_id == chromeos::login::DemoAccountId();
 }
 
 bool FakeUserManager::IsDeviceLocalAccountMarkedForRemoval(
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h
index 601eb41..e790873 100644
--- a/components/user_manager/user_manager.h
+++ b/components/user_manager/user_manager.h
@@ -269,6 +269,10 @@
   // display email) is ephemeral.
   virtual bool IsCurrentUserNonCryptohomeDataEphemeral() const = 0;
 
+  // Returns true if data stored or cached for the current user inside that
+  // user's cryptohome is ephemeral.
+  virtual bool IsCurrentUserCryptohomeDataEphemeral() const = 0;
+
   // Returns true if the current user's session can be locked (i.e. the user has
   // a password with which to unlock the session).
   virtual bool CanCurrentUserLock() const = 0;
@@ -309,6 +313,9 @@
   virtual bool IsUserNonCryptohomeDataEphemeral(
       const AccountId& account_id) const = 0;
 
+  virtual bool IsUserCryptohomeDataEphemeral(
+      const AccountId& account_id) const = 0;
+
   virtual void AddObserver(Observer* obs) = 0;
   virtual void RemoveObserver(Observer* obs) = 0;
 
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 67215eec..dead416 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -538,6 +538,12 @@
          IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->GetAccountId());
 }
 
+bool UserManagerBase::IsCurrentUserCryptohomeDataEphemeral() const {
+  DCHECK(task_runner_->RunsTasksOnCurrentThread());
+  return IsUserLoggedIn() &&
+         IsUserCryptohomeDataEphemeral(GetActiveUser()->GetAccountId());
+}
+
 bool UserManagerBase::CanCurrentUserLock() const {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
   return IsUserLoggedIn() && active_user_->can_lock();
@@ -621,6 +627,30 @@
   return AreEphemeralUsersEnabled() || HasBrowserRestarted();
 }
 
+bool UserManagerBase::IsUserCryptohomeDataEphemeral(
+    const AccountId& account_id) const {
+  // Don't consider stub users data as ephemeral.
+  if (IsStubAccountId(account_id))
+    return false;
+
+  // Data belonging to the guest and demo users is always ephemeral.
+  if (IsGuestAccountId(account_id) || IsDemoApp(account_id))
+    return true;
+
+  // Data belonging to the public accounts is always ephemeral.
+  const User* user = FindUser(account_id);
+  if (user && user->GetType() == USER_TYPE_PUBLIC_ACCOUNT)
+    return true;
+
+  // Ephemeral users.
+  if (user && user->GetType() == USER_TYPE_REGULAR &&
+      FindUserInList(account_id) == nullptr) {
+    return true;
+  }
+
+  return false;
+}
+
 void UserManagerBase::AddObserver(UserManager::Observer* obs) {
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
   observer_list_.AddObserver(obs);
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h
index 520f7ff7..649bed2 100644
--- a/components/user_manager/user_manager_base.h
+++ b/components/user_manager/user_manager_base.h
@@ -86,6 +86,7 @@
   bool IsCurrentUserOwner() const override;
   bool IsCurrentUserNew() const override;
   bool IsCurrentUserNonCryptohomeDataEphemeral() const override;
+  bool IsCurrentUserCryptohomeDataEphemeral() const override;
   bool CanCurrentUserLock() const override;
   bool IsUserLoggedIn() const override;
   bool IsLoggedInAsUserWithGaiaAccount() const override;
@@ -98,6 +99,8 @@
   bool IsSessionStarted() const override;
   bool IsUserNonCryptohomeDataEphemeral(
       const AccountId& account_id) const override;
+  bool IsUserCryptohomeDataEphemeral(
+      const AccountId& account_id) const override;
   void AddObserver(UserManager::Observer* obs) override;
   void RemoveObserver(UserManager::Observer* obs) override;
   void AddSessionStateObserver(
diff --git a/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java b/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java
index 0fd8756..662fbf40 100644
--- a/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java
+++ b/components/web_restrictions/browser/junit/src/org/chromium/components/webrestrictions/WebRestrictionsClientTest.java
@@ -41,7 +41,7 @@
 
     @Before
     public void setUp() {
-        ContextUtils.initApplicationContextForTests(Robolectric.application);
+        ContextUtils.initApplicationContextForJUnitTests(Robolectric.application);
         mTestClient = Mockito.spy(new WebRestrictionsClient());
         Mockito.doNothing().when(mTestClient).nativeNotifyWebRestrictionsChanged(anyLong());
         mProvider = Mockito.mock(ContentProvider.class);
diff --git a/components/webdata/DEPS b/components/webdata/DEPS
index d5cca70..99ab708 100644
--- a/components/webdata/DEPS
+++ b/components/webdata/DEPS
@@ -8,6 +8,7 @@
   # than production code.
   r'(.*_unittest|.*_test_util)\.(cc|h)': [
     "+components/autofill/core/browser",
+    "+components/autofill/core/common",
     "+components/password_manager/core/browser/webdata",
     "+components/search_engines/keyword_table.h",
     "+components/signin/core/browser/webdata",
diff --git a/components/webdata/common/BUILD.gn b/components/webdata/common/BUILD.gn
index 4ddd2c90..b5d45a5 100644
--- a/components/webdata/common/BUILD.gn
+++ b/components/webdata/common/BUILD.gn
@@ -69,6 +69,7 @@
     ":unit_tests_bundle_data",
     "//base",
     "//components/autofill/core/browser",
+    "//components/autofill/core/common",
     "//components/password_manager/core/browser",
     "//components/search_engines",
     "//components/signin/core/browser",
diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc
index 0436618..f9581cb 100644
--- a/components/webdata/common/web_database_migration_unittest.cc
+++ b/components/webdata/common/web_database_migration_unittest.cc
@@ -24,6 +24,7 @@
 #include "components/autofill/core/browser/webdata/autofill_change.h"
 #include "components/autofill/core/browser/webdata/autofill_entry.h"
 #include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/password_manager/core/browser/webdata/logins_table.h"
 #include "components/search_engines/keyword_table.h"
 #include "components/signin/core/browser/webdata/token_service_table.h"
@@ -368,7 +369,8 @@
     EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
     EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
     EXPECT_EQ(1386046731, s_profiles.ColumnInt(9));
-    EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+    EXPECT_EQ(ASCIIToUTF16(autofill::kSettingsOrigin),
+              s_profiles.ColumnString16(10));
 
     // Only address line 1.
     ASSERT_TRUE(s_profiles.Step());
@@ -384,7 +386,8 @@
     EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
     EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
     EXPECT_EQ(1386046800, s_profiles.ColumnInt(9));
-    EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+    EXPECT_EQ(ASCIIToUTF16(autofill::kSettingsOrigin),
+              s_profiles.ColumnString16(10));
 
     // Only address line 2.
     ASSERT_TRUE(s_profiles.Step());
@@ -399,7 +402,8 @@
     EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
     EXPECT_EQ(base::string16(), s_profiles.ColumnString16(8));
     EXPECT_EQ(1386046834, s_profiles.ColumnInt(9));
-    EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+    EXPECT_EQ(ASCIIToUTF16(autofill::kSettingsOrigin),
+              s_profiles.ColumnString16(10));
 
     // No address lines.
     ASSERT_TRUE(s_profiles.Step());
@@ -414,7 +418,8 @@
     EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
     EXPECT_EQ(base::string16(), s_profiles.ColumnString16(8));
     EXPECT_EQ(1386046847, s_profiles.ColumnInt(9));
-    EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+    EXPECT_EQ(ASCIIToUTF16(autofill::kSettingsOrigin),
+              s_profiles.ColumnString16(10));
 
     // That should be it.
     EXPECT_FALSE(s_profiles.Step());
@@ -658,7 +663,8 @@
     EXPECT_EQ(base::string16(), s_profiles.ColumnString16(7));
     EXPECT_EQ(ASCIIToUTF16("US"), s_profiles.ColumnString16(8));
     EXPECT_EQ(1395948829, s_profiles.ColumnInt(9));
-    EXPECT_EQ(ASCIIToUTF16("Chrome settings"), s_profiles.ColumnString16(10));
+    EXPECT_EQ(ASCIIToUTF16(autofill::kSettingsOrigin),
+              s_profiles.ColumnString16(10));
     EXPECT_EQ(std::string(), s_profiles.ColumnString(11));
 
     // No more entries expected.
diff --git a/content/app/BUILD.gn b/content/app/BUILD.gn
index 8663cf89e..3406797 100644
--- a/content/app/BUILD.gn
+++ b/content/app/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/chrome_build.gni")
+import("//build/config/features.gni")
 
 content_app_sources = [
   "android/app_jni_registrar.cc",
@@ -52,6 +53,10 @@
   ]
 }
 
+if (is_linux && enable_plugins) {
+  content_app_deps += [ "//content/ppapi_plugin:ppapi_plugin_sources" ]
+}
+
 content_app_extra_configs = [
   "//build/config/compiler:wexit_time_destructors",
   "//content:content_implementation",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 9980d2e0..794d54a 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -176,7 +176,7 @@
 #endif
 
 #if defined(USE_X11)
-#include "ui/base/x/x11_util_internal.h"
+#include "ui/base/x/x11_util_internal.h"  // nogncheck
 #include "ui/gfx/x/x11_connection.h"  // nogncheck
 #include "ui/gfx/x/x11_switches.h"  // nogncheck
 #include "ui/gfx/x/x11_types.h"  // nogncheck
diff --git a/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h b/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h
index 97bb8da..3cb8c58 100644
--- a/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h
+++ b/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h
@@ -16,7 +16,8 @@
 class CONTENT_EXPORT BrowserCompositorOverlayCandidateValidatorMac
     : public BrowserCompositorOverlayCandidateValidator {
  public:
-  BrowserCompositorOverlayCandidateValidatorMac();
+  explicit BrowserCompositorOverlayCandidateValidatorMac(
+      bool ca_layer_disabled);
   ~BrowserCompositorOverlayCandidateValidatorMac() override;
 
   // cc::OverlayCandidateValidator implementation.
@@ -30,7 +31,7 @@
  private:
   gfx::AcceleratedWidget widget_;
   bool software_mirror_active_;
-  bool ca_layers_disabled_;
+  const bool ca_layer_disabled_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowserCompositorOverlayCandidateValidatorMac);
 };
diff --git a/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm b/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
index 8898fc4a..c6822d9b 100644
--- a/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
+++ b/content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.mm
@@ -6,19 +6,11 @@
 
 #include <stddef.h>
 
-#include "base/command_line.h"
-#include "content/browser/gpu/gpu_data_manager_impl.h"
-#include "gpu/config/gpu_driver_bug_workaround_type.h"
-#include "ui/base/ui_base_switches.h"
-
 namespace content {
 
 BrowserCompositorOverlayCandidateValidatorMac::
-    BrowserCompositorOverlayCandidateValidatorMac()
-    : software_mirror_active_(false),
-      ca_layers_disabled_(
-          GpuDataManagerImpl::GetInstance()->IsDriverBugWorkaroundActive(
-              gpu::DISABLE_OVERLAY_CA_LAYERS)) {}
+    BrowserCompositorOverlayCandidateValidatorMac(bool ca_layer_disabled)
+    : software_mirror_active_(false), ca_layer_disabled_(ca_layer_disabled) {}
 
 BrowserCompositorOverlayCandidateValidatorMac::
     ~BrowserCompositorOverlayCandidateValidatorMac() {
@@ -29,27 +21,11 @@
 }
 
 bool BrowserCompositorOverlayCandidateValidatorMac::AllowCALayerOverlays() {
-  static bool overlays_disabled_at_command_line =
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kDisableMacOverlays);
-  if (software_mirror_active_ || ca_layers_disabled_ ||
-      overlays_disabled_at_command_line)
-    return false;
-  return true;
+  return !ca_layer_disabled_ && !software_mirror_active_;
 }
 
 void BrowserCompositorOverlayCandidateValidatorMac::CheckOverlaySupport(
     cc::OverlayCandidateList* surfaces) {
-  // SW mirroring copies out of the framebuffer, so we can't remove any
-  // quads for overlaying, otherwise the output is incorrect.
-  if (software_mirror_active_)
-    return;
-
-  if (ca_layers_disabled_)
-    return;
-
-  for (size_t i = 0; i < surfaces->size(); ++i)
-    surfaces->at(i).overlay_handled = true;
 }
 
 void BrowserCompositorOverlayCandidateValidatorMac::SetSoftwareMirrorMode(
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 065117a..e615006ed 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -74,7 +74,9 @@
 #elif defined(OS_MACOSX)
 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator_mac.h"
 #include "content/browser/compositor/software_output_device_mac.h"
+#include "gpu/config/gpu_driver_bug_workaround_type.h"
 #include "ui/base/cocoa/remote_layer_api.h"
+#include "ui/base/ui_base_switches.h"
 #elif defined(OS_ANDROID)
 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator_android.h"
 #endif
@@ -131,6 +133,13 @@
       nullptr));
 }
 
+#if defined(OS_MACOSX)
+bool IsCALayersDisabledFromCommandLine() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  return command_line->HasSwitch(switches::kDisableMacOverlays);
+}
+#endif
+
 }  // namespace
 
 namespace content {
@@ -216,7 +225,14 @@
 #elif defined(OS_MACOSX)
   // Overlays are only supported through the remote layer API.
   if (ui::RemoteLayerAPISupported()) {
-    validator.reset(new BrowserCompositorOverlayCandidateValidatorMac());
+    static bool overlays_disabled_at_command_line =
+        IsCALayersDisabledFromCommandLine();
+    const bool ca_layers_disabled =
+        overlays_disabled_at_command_line ||
+        GpuDataManagerImpl::GetInstance()->IsDriverBugWorkaroundActive(
+            gpu::DISABLE_OVERLAY_CA_LAYERS);
+    validator.reset(
+        new BrowserCompositorOverlayCandidateValidatorMac(ca_layers_disabled));
   }
 #elif defined(OS_ANDROID)
   validator.reset(new BrowserCompositorOverlayCandidateValidatorAndroid());
diff --git a/content/browser/devtools/devtools_protocol_handler.cc b/content/browser/devtools/devtools_protocol_handler.cc
index c7bba21..be689d43 100644
--- a/content/browser/devtools/devtools_protocol_handler.cc
+++ b/content/browser/devtools/devtools_protocol_handler.cc
@@ -60,14 +60,15 @@
 
 bool DevToolsProtocolHandler::HandleOptionalMessage(int session_id,
                                                     const std::string& message,
-                                                    int* call_id) {
+                                                    int* call_id,
+                                                    std::string* method) {
   std::unique_ptr<base::DictionaryValue> command =
       ParseCommand(session_id, message);
   if (!command)
     return true;
   if (PassCommandToDelegate(session_id, command.get()))
     return true;
-  return HandleOptionalCommand(session_id, std::move(command), call_id);
+  return HandleOptionalCommand(session_id, std::move(command), call_id, method);
 }
 
 bool DevToolsProtocolHandler::PassCommandToDelegate(
@@ -146,13 +147,13 @@
 bool DevToolsProtocolHandler::HandleOptionalCommand(
     int session_id,
     std::unique_ptr<base::DictionaryValue> command,
-    int* call_id) {
+    int* call_id,
+    std::string* method) {
   *call_id = DevToolsCommandId::kNoId;
-  std::string method;
   command->GetInteger(kIdParam, call_id);
-  command->GetString(kMethodParam, &method);
+  command->GetString(kMethodParam, method);
   DevToolsProtocolDispatcher::CommandHandler command_handler(
-      dispatcher_.FindCommandHandler(method));
+      dispatcher_.FindCommandHandler(*method));
   if (!command_handler.is_null()) {
     return command_handler.Run(DevToolsCommandId(*call_id, session_id),
                                TakeDictionary(command.get(), kParamsParam));
diff --git a/content/browser/devtools/devtools_protocol_handler.h b/content/browser/devtools/devtools_protocol_handler.h
index d9fc156..b91c2eb8 100644
--- a/content/browser/devtools/devtools_protocol_handler.h
+++ b/content/browser/devtools/devtools_protocol_handler.h
@@ -23,7 +23,8 @@
   void HandleMessage(int session_id, const std::string& message);
   bool HandleOptionalMessage(int session_id,
                              const std::string& message,
-                             int* call_id);
+                             int* call_id,
+                             std::string* method);
 
   DevToolsProtocolDispatcher* dispatcher() { return &dispatcher_; }
 
@@ -36,7 +37,8 @@
                      std::unique_ptr<base::DictionaryValue> command);
   bool HandleOptionalCommand(int session_id,
                              std::unique_ptr<base::DictionaryValue> command,
-                             int* call_id);
+                             int* call_id,
+                             std::string* method);
 
   DevToolsAgentHost* agent_host_;
   DevToolsProtocolClient client_;
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index d9a1a1c0..8c8f66f 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -98,6 +98,7 @@
   void Detach();
   void DispatchProtocolMessage(int session_id,
                                int call_id,
+                               const std::string& method,
                                const std::string& message);
   void InspectElement(int x, int y);
   void ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
@@ -116,8 +117,8 @@
   DevToolsMessageChunkProcessor chunk_processor_;
   // <session_id, message>
   std::vector<std::pair<int, std::string>> pending_messages_;
-  // <call_id> -> <session_id, message>
-  std::map<int, std::pair<int, std::string>> sent_messages_;
+  // <call_id> -> PendingMessage
+  std::map<int, PendingMessage> sent_messages_;
 };
 
 RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder(
@@ -154,8 +155,8 @@
       chunk_processor_.state_cookie()));
   if (old) {
     for (const auto& pair : old->sent_messages_) {
-      DispatchProtocolMessage(pair.second.first, pair.first,
-                              pair.second.second);
+      DispatchProtocolMessage(pair.second.session_id, pair.first,
+                              pair.second.method, pair.second.message);
     }
   }
   GrantPolicy();
@@ -198,10 +199,11 @@
 void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage(
     int session_id,
     int call_id,
+    const std::string& method,
     const std::string& message) {
   host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
-      host_->GetRoutingID(), session_id, message));
-  sent_messages_[call_id] = std::make_pair(session_id, message);
+      host_->GetRoutingID(), session_id, call_id, method, message));
+  sent_messages_[call_id] = { session_id, method, message };
 }
 
 void RenderFrameDevToolsAgentHost::FrameHostHolder::InspectElement(
@@ -459,20 +461,22 @@
 bool RenderFrameDevToolsAgentHost::DispatchProtocolMessage(
     const std::string& message) {
   int call_id = 0;
-  if (protocol_handler_->HandleOptionalMessage(session_id(), message, &call_id))
+  std::string method;
+  if (protocol_handler_->HandleOptionalMessage(session_id(), message, &call_id,
+                                               &method))
     return true;
 
   if (!navigating_handles_.empty()) {
     DCHECK(IsBrowserSideNavigationEnabled());
     in_navigation_protocol_message_buffer_[call_id] =
-        std::make_pair(session_id(), message);
+        { session_id(), method, message };
     return true;
   }
 
   if (current_)
-    current_->DispatchProtocolMessage(session_id(), call_id, message);
+    current_->DispatchProtocolMessage(session_id(), call_id, method, message);
   if (pending_)
-    pending_->DispatchProtocolMessage(session_id(), call_id, message);
+    pending_->DispatchProtocolMessage(session_id(), call_id, method, message);
   return true;
 }
 
@@ -746,8 +750,9 @@
       in_navigation_protocol_message_buffer_.size()) {
     DCHECK(current_);
     for (const auto& pair : in_navigation_protocol_message_buffer_) {
-      current_->DispatchProtocolMessage(pair.second.first, pair.first,
-                                        pair.second.second);
+      current_->DispatchProtocolMessage(
+          pair.second.session_id, pair.first, pair.second.method,
+          pair.second.message);
     }
     in_navigation_protocol_message_buffer_.clear();
   }
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h
index beedd88..d45ccfe5 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -174,9 +174,13 @@
   // List of handles currently navigating.
   std::set<NavigationHandle*> navigating_handles_;
 
-  // <call_id> -> <session_id, message>
-  std::map<int, std::pair<int, std::string>>
-      in_navigation_protocol_message_buffer_;
+  struct PendingMessage {
+    int session_id;
+    std::string method;
+    std::string message;
+  };
+  // <call_id> -> PendingMessage
+  std::map<int, PendingMessage> in_navigation_protocol_message_buffer_;
 
   // The FrameTreeNode associated with this agent.
   FrameTreeNode* frame_tree_node_;
diff --git a/content/browser/devtools/worker_devtools_agent_host.cc b/content/browser/devtools/worker_devtools_agent_host.cc
index d7be60a..0673a191b 100644
--- a/content/browser/devtools/worker_devtools_agent_host.cc
+++ b/content/browser/devtools/worker_devtools_agent_host.cc
@@ -46,12 +46,14 @@
     return true;
 
   int call_id;
-  if (protocol_handler_->HandleOptionalMessage(session_id(), message, &call_id))
+  std::string method;
+  if (protocol_handler_->HandleOptionalMessage(session_id(), message, &call_id,
+                                               &method))
     return true;
 
   if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
     host->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
-        worker_id_.second, session_id(), message));
+        worker_id_.second, session_id(), call_id, method, message));
   }
   return true;
 }
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index a45d21f..2823952 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -48,7 +48,7 @@
 #endif
 
 #if defined(OS_LINUX) && defined(USE_X11)
-#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util.h"       // nogncheck
 #include "ui/gfx/x/x11_atom_cache.h"  // nogncheck
 #endif
 
diff --git a/content/browser/screen_orientation/screen_orientation_browsertest.cc b/content/browser/screen_orientation/screen_orientation_browsertest.cc
index efdd4cf..45710af 100644
--- a/content/browser/screen_orientation/screen_orientation_browsertest.cc
+++ b/content/browser/screen_orientation/screen_orientation_browsertest.cc
@@ -227,7 +227,8 @@
 
 // Check that when --disable-screen-orientation-lock is passed to the command
 // line, screen.orientation.lock() correctly reports to not be supported.
-IN_PROC_BROWSER_TEST_F(ScreenOrientationLockDisabledBrowserTest, NotSupported) {
+IN_PROC_BROWSER_TEST_F(ScreenOrientationLockDisabledBrowserTest,
+    DISABLED_NotSupported) {
   GURL test_url = GetTestUrl("screen_orientation",
                              "screen_orientation_lock_disabled.html");
 
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index 40271d43..89786403 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -334,31 +334,18 @@
     return real_url;
 
   GURL url = SiteInstanceImpl::GetEffectiveURL(browser_context, real_url);
+  url::Origin origin(url);
 
   // If the url has a host, then determine the site.
-  if (url.has_host()) {
-    // Only keep the scheme and registered domain as given by GetOrigin.  This
-    // may also include a port, which we need to drop.
-    GURL site = url.GetOrigin();
-
-    // Remove port, if any.
-    if (site.has_port()) {
-      GURL::Replacements rep;
-      rep.ClearPort();
-      site = site.ReplaceComponents(rep);
-    }
-
-    // If this URL has a registered domain, we only want to remember that part.
-    std::string domain =
-        net::registry_controlled_domains::GetDomainAndRegistry(
-            url,
-            net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
-    if (!domain.empty()) {
-      GURL::Replacements rep;
-      rep.SetHostStr(domain);
-      site = site.ReplaceComponents(rep);
-    }
-    return site;
+  if (!origin.host().empty()) {
+    // Only keep the scheme and registered domain of |origin|.
+    std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
+        origin.host(),
+        net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+    std::string site = origin.scheme();
+    site += url::kStandardSchemeSeparator;
+    site += domain.empty() ? origin.host() : domain;
+    return GURL(site);
   }
 
   // If there is no host but there is a scheme, return the scheme.
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc
index 9a52e3b..da71935 100644
--- a/content/browser/site_instance_impl_unittest.cc
+++ b/content/browser/site_instance_impl_unittest.cc
@@ -289,12 +289,38 @@
   EXPECT_EQ("http", site_url.scheme());
   EXPECT_EQ("google.com", site_url.host());
 
-  // Ports are irrlevant.
+  // Ports are irrelevant.
   test_url = GURL("https://www.google.com:8080");
   site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
   EXPECT_EQ(GURL("https://google.com"), site_url);
 
-  // Hostnames without TLDs are ok.
+  // Punycode is canonicalized.
+  test_url = GURL("http://☃snowperson☃.net:333/");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("http://xn--snowperson-di0gka.net"), site_url);
+
+  // Username and password are stripped out.
+  test_url = GURL("ftp://username:password@ftp.chromium.org/files/README");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("ftp://chromium.org"), site_url);
+
+  // Literal IP addresses of any flavor are okay.
+  test_url = GURL("http://127.0.0.1/a.html");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("http://127.0.0.1"), site_url);
+  EXPECT_EQ("127.0.0.1", site_url.host());
+
+  test_url = GURL("http://2130706433/a.html");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("http://127.0.0.1"), site_url);
+  EXPECT_EQ("127.0.0.1", site_url.host());
+
+  test_url = GURL("http://[::1]:2/page.html");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("http://[::1]"), site_url);
+  EXPECT_EQ("[::1]", site_url.host());
+
+  // Hostnames without TLDs are okay.
   test_url = GURL("http://foo/a.html");
   site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
   EXPECT_EQ(GURL("http://foo"), site_url);
@@ -327,6 +353,25 @@
   EXPECT_EQ("javascript", site_url.scheme());
   EXPECT_FALSE(site_url.has_host());
 
+  // Blob URLs extract the site from the origin.
+  test_url = GURL(
+      "blob:gopher://www.ftp.chromium.org/"
+      "4d4ff040-6d61-4446-86d3-13ca07ec9ab9");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("gopher://chromium.org"), site_url);
+
+  // Private domains are preserved, appspot being such a site.
+  test_url = GURL(
+      "blob:http://www.example.appspot.com:44/"
+      "4d4ff040-6d61-4446-86d3-13ca07ec9ab9");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("http://example.appspot.com"), site_url);
+
+  // The site of filesystem URLs is determined by the inner URL.
+  test_url = GURL("filesystem:http://www.google.com/foo/bar.html?foo#bar");
+  site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+  EXPECT_EQ(GURL("http://google.com"), site_url);
+
   // Guest URLs are special and need to have the path in the site as well,
   // since it affects the StoragePartition configuration.
   std::string guest_url(kGuestScheme);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index b712637..575628c 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -375,6 +375,34 @@
   }
 }
 
+// This observer detects when WebContents receives notification of a user
+// gesture having occurred, following a user input event targeted to
+// a RenderWidgetHost under that WebContents.
+class UserInteractionObserver : public WebContentsObserver {
+ public:
+  explicit UserInteractionObserver(WebContents* web_contents)
+      : WebContentsObserver(web_contents), user_interaction_received_(false) {}
+
+  ~UserInteractionObserver() override {}
+
+  // Retrieve the flag. There is no need to wait on a loop since
+  // DidGetUserInteraction() should be called synchronously with the input
+  // event processing in the browser process.
+  bool WasUserInteractionReceived() { return user_interaction_received_; }
+
+  void Reset() { user_interaction_received_ = false; }
+
+ private:
+  // WebContentsObserver
+  void DidGetUserInteraction(const blink::WebInputEvent::Type type) override {
+    user_interaction_received_ = true;
+  }
+
+  bool user_interaction_received_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserInteractionObserver);
+};
+
 // This observer is used to wait for its owner FrameTreeNode to become focused.
 class FrameFocusedObserver : public FrameTreeNode::Observer {
  public:
@@ -6225,4 +6253,31 @@
   subframe_process->DecrementWorkerRefCount();
 }
 
+// Tests that an input event targeted to a out-of-process iframe correctly
+// triggers a user interaction notification for WebContentsObservers.
+// This is used for browser features such as download request limiting and
+// launching multiple external protocol handlers, which can block repeated
+// actions from a page when a user is not interacting with the page.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+                       UserInteractionForChildFrameTest) {
+  GURL main_url(embedded_test_server()->GetURL(
+      "a.com", "/cross_site_iframe_factory.html?a(b)"));
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  UserInteractionObserver observer(web_contents());
+
+  // Target an event to the child frame's RenderWidgetHostView.
+  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+  SimulateMouseClick(
+      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 5, 5);
+
+  EXPECT_TRUE(observer.WasUserInteractionReceived());
+
+  // Target an event to the main frame.
+  observer.Reset();
+  SimulateMouseClick(root->current_frame_host()->GetRenderWidgetHost(), 1, 1);
+
+  EXPECT_TRUE(observer.WasUserInteractionReceived());
+}
+
 }  // namespace content
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index c37835e..c4d3cd3 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -174,6 +174,20 @@
   return false;
 }
 
+bool HasMatchingWidgetHost(FrameTree* tree, RenderWidgetHost* host) {
+  // This method scans the frame tree rather than checking whether
+  // host->delegate() == this, which allows it to return false when the host
+  // for a frame that is pending or pending deletion.
+  if (!host)
+    return false;
+
+  for (FrameTreeNode* node : tree->Nodes()) {
+    if (node->current_frame_host()->GetRenderWidgetHost() == host)
+      return true;
+  }
+  return false;
+}
+
 void SetAccessibilityModeOnFrame(AccessibilityMode mode,
                                  RenderFrameHost* frame_host) {
   static_cast<RenderFrameHostImpl*>(frame_host)->SetAccessibilityMode(mode);
@@ -4445,9 +4459,8 @@
 void WebContentsImpl::OnUserInteraction(
     RenderWidgetHostImpl* render_widget_host,
     const blink::WebInputEvent::Type type) {
-  // Ignore when the renderer is swapped out.
-  // TODO(dominickn,creis): support widgets for out-of-process iframes.
-  if (render_widget_host != GetRenderViewHost()->GetWidget())
+  // Ignore unless the widget is currently in the frame tree.
+  if (!HasMatchingWidgetHost(&frame_tree_, render_widget_host))
     return;
 
   FOR_EACH_OBSERVER(WebContentsObserver, observers_,
diff --git a/content/child/shared_worker_devtools_agent.cc b/content/child/shared_worker_devtools_agent.cc
index b0698f371..eab55f5 100644
--- a/content/child/shared_worker_devtools_agent.cc
+++ b/content/child/shared_worker_devtools_agent.cc
@@ -97,8 +97,12 @@
 
 void SharedWorkerDevToolsAgent::OnDispatchOnInspectorBackend(
     int session_id,
+    int call_id,
+    const std::string& method,
     const std::string& message) {
-  webworker_->dispatchDevToolsMessage(session_id, WebString::fromUTF8(message));
+  webworker_->dispatchDevToolsMessage(session_id, call_id,
+                                      WebString::fromUTF8(method),
+                                      WebString::fromUTF8(message));
 }
 
 bool SharedWorkerDevToolsAgent::Send(IPC::Message* message) {
diff --git a/content/child/shared_worker_devtools_agent.h b/content/child/shared_worker_devtools_agent.h
index e3ad2b2..b46d15f 100644
--- a/content/child/shared_worker_devtools_agent.h
+++ b/content/child/shared_worker_devtools_agent.h
@@ -38,7 +38,11 @@
                   int session_id,
                   const std::string& state);
   void OnDetach();
-  void OnDispatchOnInspectorBackend(int session_id, const std::string& message);
+  void OnDispatchOnInspectorBackend(
+      int session_id,
+      int call_id,
+      const std::string& method,
+      const std::string& message);
 
   bool Send(IPC::Message* message);
   const int route_id_;
diff --git a/content/common/devtools_messages.h b/content/common/devtools_messages.h
index 4c7c24a..7a888762 100644
--- a/content/common/devtools_messages.h
+++ b/content/common/devtools_messages.h
@@ -93,8 +93,10 @@
 IPC_MESSAGE_ROUTED0(DevToolsAgentMsg_Detach)
 
 // WebKit-level transport.
-IPC_MESSAGE_ROUTED2(DevToolsAgentMsg_DispatchOnInspectorBackend,
+IPC_MESSAGE_ROUTED4(DevToolsAgentMsg_DispatchOnInspectorBackend,
                     int /* session_id */,
+                    int /* call_id */,
+                    std::string /* method */,
                     std::string /* message */)
 
 // Inspect element with the given coordinates.
diff --git a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
index 077a710..d356897 100644
--- a/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
+++ b/content/common/sandbox_linux/bpf_gpu_policy_linux.cc
@@ -262,6 +262,7 @@
     case __NR_mprotect:
     // TODO(jln): restrict prctl.
     case __NR_prctl:
+    case __NR_sysinfo:
       return Allow();
 #if !defined(__aarch64__)
     case __NR_access:
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 6ab7e34..87693f25 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -2033,6 +2033,7 @@
     ['use_x11==1', {
       'dependencies': [
         '../build/linux/system.gyp:x11',
+        '../ui/base/x/ui_base_x.gyp:ui_base_x',
         '../ui/events/platform/x11/x11_events_platform.gyp:x11_events_platform',
         '../ui/gfx/x/gfx_x11.gyp:gfx_x11',
       ],
diff --git a/content/content_shell_test_data.isolate b/content/content_shell_test_data.isolate
index 6f27c35..72d4d7c0f 100644
--- a/content/content_shell_test_data.isolate
+++ b/content/content_shell_test_data.isolate
@@ -2,20 +2,16 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 {
-  'conditions': [
-    ['OS=="android"', {
-      'variables': {
-        'files': [
-          '<(DEPTH)/content/test/data/android/',
-          '<(DEPTH)/content/test/data/media/session/',
-          '<(DEPTH)/net/data/ssl/certificates/crit-codeSigning-chain.pem',
-          '<(DEPTH)/net/data/ssl/certificates/eku-test-root.pem',
-          '<(DEPTH)/net/data/ssl/certificates/invalid_key_usage_cert.der',
-          '<(DEPTH)/net/data/ssl/certificates/non-crit-codeSigning-chain.pem',
-          '<(DEPTH)/net/data/ssl/certificates/ok_cert.pem',
-          '<(DEPTH)/net/data/ssl/certificates/root_ca_cert.pem',
-        ],
-      },
-    }],
-  ],
+  'variables': {
+    'files': [
+      '<(DEPTH)/content/test/data/android/',
+      '<(DEPTH)/content/test/data/media/session/',
+      '<(DEPTH)/net/data/ssl/certificates/crit-codeSigning-chain.pem',
+      '<(DEPTH)/net/data/ssl/certificates/eku-test-root.pem',
+      '<(DEPTH)/net/data/ssl/certificates/invalid_key_usage_cert.der',
+      '<(DEPTH)/net/data/ssl/certificates/non-crit-codeSigning-chain.pem',
+      '<(DEPTH)/net/data/ssl/certificates/ok_cert.pem',
+      '<(DEPTH)/net/data/ssl/certificates/root_ca_cert.pem',
+    ],
+  },
 }
diff --git a/content/gpu/BUILD.gn b/content/gpu/BUILD.gn
index 0b74bdc..f91778dcd 100644
--- a/content/gpu/BUILD.gn
+++ b/content/gpu/BUILD.gn
@@ -64,6 +64,9 @@
 
   if (mojo_media_host == "gpu") {
     deps += [ "//media/mojo/services:application_factory" ]
+    if (is_android) {
+      deps += [ "//media/base/android" ]
+    }
   }
 
   if (is_win) {
diff --git a/content/gpu/DEPS b/content/gpu/DEPS
index 09b12d1e..945f4083 100644
--- a/content/gpu/DEPS
+++ b/content/gpu/DEPS
@@ -4,6 +4,7 @@
   "+content/public/gpu",
   "+libEGL",
   "+libGLESv2",
+  "+media/base/android",
   "+media/mojo/services",
   "+services/shell",
   "+sandbox",
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index 87f78fe..486281c 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -61,7 +61,7 @@
 #endif
 
 #if defined(USE_X11)
-#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util.h"     // nogncheck
 #include "ui/gfx/x/x11_switches.h"  // nogncheck
 #endif
 
diff --git a/content/gpu/gpu_process_control_impl.cc b/content/gpu/gpu_process_control_impl.cc
index f281b05..a6bc1db 100644
--- a/content/gpu/gpu_process_control_impl.cc
+++ b/content/gpu/gpu_process_control_impl.cc
@@ -7,7 +7,11 @@
 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
 #include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "content/public/common/content_client.h"
 #include "media/mojo/services/mojo_media_application_factory.h"
+#if defined(OS_ANDROID)
+#include "media/base/android/media_client_android.h"
+#endif
 #endif
 
 namespace content {
@@ -19,6 +23,11 @@
 void GpuProcessControlImpl::RegisterApplicationFactories(
     ApplicationFactoryMap* factories) {
 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
+#if defined(OS_ANDROID)
+  // Only set once per process instance.
+  media::SetMediaClientAndroid(GetContentClient()->GetMediaClientAndroid());
+#endif
+
   factories->insert(std::make_pair(
       "mojo:media", base::Bind(&media::CreateMojoMediaApplication)));
 #endif
diff --git a/content/gpu/gpu_watchdog_thread.h b/content/gpu/gpu_watchdog_thread.h
index c95c72e..c8e0095 100644
--- a/content/gpu/gpu_watchdog_thread.h
+++ b/content/gpu/gpu_watchdog_thread.h
@@ -22,7 +22,7 @@
 #include <X11/Xatom.h>
 }
 #include <sys/poll.h>
-#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util.h"  // nogncheck
 #include "ui/gfx/x/x11_types.h"  // nogncheck
 #endif
 
diff --git a/content/ppapi_plugin/BUILD.gn b/content/ppapi_plugin/BUILD.gn
index 86d1d11a..8b141bf 100644
--- a/content/ppapi_plugin/BUILD.gn
+++ b/content/ppapi_plugin/BUILD.gn
@@ -21,6 +21,9 @@
   visibility = [
     ":ppapi_plugin",
     "//content",  # For the component build.
+    "//content/app:both",
+    "//content/app:browser",
+    "//content/app:child",
     "//gin",
   ]
 
diff --git a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
index 77f70e9f..54dc6e62f 100644
--- a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
+++ b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
@@ -116,8 +116,6 @@
         sContext.set(this);
         super.onCreate();
 
-        ContextUtils.initApplicationContext(getApplicationContext());
-
         mMainThread = new Thread(new Runnable() {
             @Override
             @SuppressFBWarnings("DM_EXIT")
@@ -189,6 +187,7 @@
                             mMainThread.wait();
                         }
                     }
+                    ContextUtils.initApplicationContext(sContext.get().getApplicationContext());
                     for (FileDescriptorInfo fdInfo : mFdInfos) {
                         nativeRegisterGlobalFileDescriptor(
                                 fdInfo.mId, fdInfo.mFd.detachFd(), fdInfo.mOffset, fdInfo.mSize);
diff --git a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
index d53701d..6c97f4c 100644
--- a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupController.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.os.Handler;
 
+import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.ResourceExtractor;
 import org.chromium.base.ThreadUtils;
@@ -291,6 +292,7 @@
                     // TODO(yfriedman): Remove dependency on a command line flag for this.
                     DeviceUtils.addDeviceSpecificUserAgentSwitch(mContext);
 
+                    ContextUtils.initApplicationContext(mContext);
                     nativeSetCommandLineFlags(
                             singleProcess, nativeIsPluginEnabled() ? getPlugins() : null);
                     mPostResourceExtractionTasksCompleted = true;
@@ -317,6 +319,8 @@
         ResourceExtractor resourceExtractor = ResourceExtractor.get(mContext);
         resourceExtractor.startExtractingResources();
         resourceExtractor.waitForCompletion();
+
+        ContextUtils.initApplicationContext(mContext.getApplicationContext());
         nativeSetCommandLineFlags(false, null);
     }
 
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
index 77016cd..9f439139 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java
@@ -247,6 +247,6 @@
     protected void setUp() throws Exception {
         super.setUp();
         LibraryLoader.get(LibraryProcessType.PROCESS_CHILD)
-                .ensureInitialized(getInstrumentation().getTargetContext());
+                .ensureInitialized(getInstrumentation().getContext());
     }
 }
diff --git a/content/public/common/content_client.cc b/content/public/common/content_client.cc
index 9085b75..43463d5 100644
--- a/content/public/common/content_client.cc
+++ b/content/public/common/content_client.cc
@@ -127,6 +127,10 @@
 bool ContentClient::UsingSynchronousCompositing() {
   return false;
 }
+
+media::MediaClientAndroid* ContentClient::GetMediaClientAndroid() {
+  return nullptr;
+}
 #endif  // OS_ANDROID
 
 }  // namespace content
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
index 7f4be8746..dace907 100644
--- a/content/public/common/content_client.h
+++ b/content/public/common/content_client.h
@@ -34,6 +34,10 @@
 struct GPUInfo;
 }
 
+namespace media {
+class MediaClientAndroid;
+}
+
 namespace sandbox {
 class TargetPolicy;
 }
@@ -169,6 +173,9 @@
   // compositor. Note setting this to true will permit synchronous IPCs from
   // the browser UI thread.
   virtual bool UsingSynchronousCompositing();
+
+  // Returns the MediaClientAndroid to be used by media code on Android.
+  virtual media::MediaClientAndroid* GetMediaClientAndroid();
 #endif  // OS_ANDROID
 
  private:
diff --git a/content/renderer/devtools/devtools_agent.cc b/content/renderer/devtools/devtools_agent.cc
index 78dcd5a..64dacd3 100644
--- a/content/renderer/devtools/devtools_agent.cc
+++ b/content/renderer/devtools/devtools_agent.cc
@@ -228,9 +228,13 @@
 }
 
 void DevToolsAgent::OnDispatchOnInspectorBackend(int session_id,
+                                                 int call_id,
+                                                 const std::string& method,
                                                  const std::string& message) {
   TRACE_EVENT0("devtools", "DevToolsAgent::OnDispatchOnInspectorBackend");
   GetWebAgent()->dispatchOnInspectorBackend(session_id,
+                                            call_id,
+                                            WebString::fromUTF8(method),
                                             WebString::fromUTF8(message));
 }
 
diff --git a/content/renderer/devtools/devtools_agent.h b/content/renderer/devtools/devtools_agent.h
index 7fc1d06..c716a2b 100644
--- a/content/renderer/devtools/devtools_agent.h
+++ b/content/renderer/devtools/devtools_agent.h
@@ -76,7 +76,10 @@
                   int session_id,
                   const std::string& agent_state);
   void OnDetach();
-  void OnDispatchOnInspectorBackend(int session_id, const std::string& message);
+  void OnDispatchOnInspectorBackend(int session_id,
+                                    int call_id,
+                                    const std::string& method,
+                                    const std::string& message);
   void OnInspectElement(int x, int y);
   void OnRequestNewWindowACK(bool success);
   void ContinueProgram();
diff --git a/content/renderer/devtools/devtools_agent_filter.cc b/content/renderer/devtools/devtools_agent_filter.cc
index a5e6b886..0ccf71b 100644
--- a/content/renderer/devtools/devtools_agent_filter.cc
+++ b/content/renderer/devtools/devtools_agent_filter.cc
@@ -61,18 +61,19 @@
 
 void DevToolsAgentFilter::OnDispatchOnInspectorBackend(
     int session_id,
+    int call_id,
+    const std::string& method,
     const std::string& message) {
   if (embedded_worker_routes_.find(current_routing_id_) !=
       embedded_worker_routes_.end()) {
     return;
   }
 
-  if (WebDevToolsAgent::shouldInterruptForMessage(
-          WebString::fromUTF8(message))) {
+  if (WebDevToolsAgent::shouldInterruptForMethod(
+          WebString::fromUTF8(method))) {
     WebDevToolsAgent::interruptAndDispatch(
         session_id, new MessageImpl(message, current_routing_id_));
   }
-
 }
 
 void DevToolsAgentFilter::AddEmbeddedWorkerRouteOnMainThread(
diff --git a/content/renderer/devtools/devtools_agent_filter.h b/content/renderer/devtools/devtools_agent_filter.h
index ce85638..899bad74 100644
--- a/content/renderer/devtools/devtools_agent_filter.h
+++ b/content/renderer/devtools/devtools_agent_filter.h
@@ -46,7 +46,11 @@
   ~DevToolsAgentFilter() override;
 
  private:
-  void OnDispatchOnInspectorBackend(int session_id, const std::string& message);
+  void OnDispatchOnInspectorBackend(
+      int session_id,
+      int call_id,
+      const std::string& method,
+      const std::string& message);
 
   // Called on IO thread
   void AddEmbeddedWorkerRoute(int32_t routing_id);
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index 4a54057..8fe5bae 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -17,6 +17,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "cc/layers/layer.h"
+#include "cc/trees/layer_tree_host.h"
 #include "content/common/child_process_messages.h"
 #include "content/common/input/synthetic_gesture_params.h"
 #include "content/common/input/synthetic_pinch_gesture_params.h"
@@ -124,29 +125,27 @@
   // Recursively serializes the layer tree.
   // Each layer in the tree is serialized into a separate skp file
   // in the given directory.
-  void Serialize(const cc::Layer* layer) {
-    const cc::LayerList& children = layer->children();
-    for (size_t i = 0; i < children.size(); ++i) {
-      Serialize(children[i].get());
+  void Serialize(const cc::Layer* root_layer) {
+    for (auto* layer : *root_layer->layer_tree_host()) {
+      sk_sp<SkPicture> picture = layer->GetPicture();
+      if (!picture)
+        continue;
+
+      // Serialize picture to file.
+      // TODO(alokp): Note that for this to work Chrome needs to be launched
+      // with
+      // --no-sandbox command-line flag. Get rid of this limitation.
+      // CRBUG: 139640.
+      std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp";
+      std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII();
+      DCHECK(!filepath.empty());
+      SkFILEWStream file(filepath.c_str());
+      DCHECK(file.isValid());
+
+      EncodingSerializer serializer;
+      picture->serialize(&file, &serializer);
+      file.fsync();
     }
-
-    sk_sp<SkPicture> picture = layer->GetPicture();
-    if (!picture)
-      return;
-
-    // Serialize picture to file.
-    // TODO(alokp): Note that for this to work Chrome needs to be launched with
-    // --no-sandbox command-line flag. Get rid of this limitation.
-    // CRBUG: 139640.
-    std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp";
-    std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII();
-    DCHECK(!filepath.empty());
-    SkFILEWStream file(filepath.c_str());
-    DCHECK(file.isValid());
-
-    EncodingSerializer serializer;
-    picture->serialize(&file, &serializer);
-    file.fsync();
   }
 
  private:
diff --git a/content/renderer/media/media_recorder_handler.cc b/content/renderer/media/media_recorder_handler.cc
index aece3f5..4bc45a0 100644
--- a/content/renderer/media/media_recorder_handler.cc
+++ b/content/renderer/media/media_recorder_handler.cc
@@ -15,7 +15,6 @@
 #include "content/renderer/media/audio_track_recorder.h"
 #include "content/renderer/media/media_stream_audio_track.h"
 #include "content/renderer/media/media_stream_track.h"
-#include "content/renderer/media/video_track_recorder.h"
 #include "content/renderer/media/webrtc_uma_histograms.h"
 #include "media/base/audio_bus.h"
 #include "media/base/audio_parameters.h"
@@ -29,13 +28,33 @@
 
 using base::TimeDelta;
 using base::TimeTicks;
+using base::ToLowerASCII;
 
 namespace content {
 
+namespace {
+
+media::VideoCodec CodecIdToMediaVideoCodec(VideoTrackRecorder::CodecId id) {
+  switch (id) {
+    case VideoTrackRecorder::CodecId::VP8:
+      return media::kCodecVP8;
+    case VideoTrackRecorder::CodecId::VP9:
+      return media::kCodecVP8;
+#if BUILDFLAG(RTC_USE_H264)
+    case VideoTrackRecorder::CodecId::H264:
+      return media::kCodecH264;
+#endif
+  }
+  NOTREACHED() << "Unsupported codec";
+  return media::kUnknownVideoCodec;
+}
+
+}  // anonymous namespace
+
 MediaRecorderHandler::MediaRecorderHandler()
     : video_bits_per_second_(0),
       audio_bits_per_second_(0),
-      use_vp9_(false),
+      codec_id_(VideoTrackRecorder::CodecId::VP8),
       recording_(false),
       client_(nullptr),
       weak_factory_(this) {}
@@ -48,7 +67,8 @@
 }
 
 bool MediaRecorderHandler::canSupportMimeType(
-    const blink::WebString& web_type, const blink::WebString& web_codecs) {
+    const blink::WebString& web_type,
+    const blink::WebString& web_codecs) {
   DCHECK(main_render_thread_checker_.CalledOnValidThread());
   // An empty |web_type| means MediaRecorderHandler can choose its preferred
   // codecs.
@@ -65,7 +85,7 @@
   // Both |video| and |audio| support empty |codecs|; |type| == "video" supports
   // vp8, vp9 or opus; |type| = "audio", supports only opus.
   // http://www.webmproject.org/docs/container Sec:"HTML5 Video Type Parameters"
-  static const char* const kVideoCodecs[] = { "vp8", "vp9", "opus" };
+  static const char* const kVideoCodecs[] = { "vp8", "vp9", "h264", "opus" };
   static const char* const kAudioCodecs[] = { "opus" };
   const char* const* codecs = video ? &kVideoCodecs[0] : &kAudioCodecs[0];
   const int codecs_count =
@@ -101,7 +121,18 @@
                 << ";codecs=" << codecs.utf8();
     return false;
   }
-  use_vp9_ = base::ToLowerASCII(codecs.utf8()).find("vp9") != std::string::npos;
+
+  // Once established that we support the codec(s), hunt then individually.
+  const std::string& codecs_str = ToLowerASCII(codecs.utf8());
+  if (codecs_str.find("vp8") != std::string::npos)
+    codec_id_ = VideoTrackRecorder::CodecId::VP8;
+  else if (codecs_str.find("vp9") != std::string::npos)
+    codec_id_ = VideoTrackRecorder::CodecId::VP9;
+#if BUILDFLAG(RTC_USE_H264)
+  else if (codecs_str.find("h264") != std::string::npos)
+    codec_id_ = VideoTrackRecorder::CodecId::H264;
+#endif
+
   media_stream_ = media_stream;
   DCHECK(client);
   client_ = client;
@@ -147,9 +178,9 @@
                                     blink::WebMediaStreamSource::ReadyStateLive;
 
   webm_muxer_.reset(new media::WebmMuxer(
-      use_vp9_ ? media::kCodecVP9 : media::kCodecVP8, use_video_tracks,
-      use_audio_tracks, base::Bind(&MediaRecorderHandler::WriteData,
-                                   weak_factory_.GetWeakPtr())));
+      CodecIdToMediaVideoCodec(codec_id_), use_video_tracks, use_audio_tracks,
+      base::Bind(&MediaRecorderHandler::WriteData,
+                 weak_factory_.GetWeakPtr())));
 
   if (use_video_tracks) {
     // TODO(mcasas): The muxer API supports only one video track. Extend it to
@@ -166,9 +197,7 @@
             &MediaRecorderHandler::OnEncodedVideo, weak_factory_.GetWeakPtr()));
 
     video_recorders_.push_back(new VideoTrackRecorder(
-        use_vp9_ ? VideoTrackRecorder::CodecId::VP9
-                 : VideoTrackRecorder::CodecId::VP8,
-        video_track, on_encoded_video_cb, video_bits_per_second_));
+        codec_id_, video_track, on_encoded_video_cb, video_bits_per_second_));
   }
 
   if (use_audio_tracks) {
diff --git a/content/renderer/media/media_recorder_handler.h b/content/renderer/media/media_recorder_handler.h
index df4645a..8fa56c4a 100644
--- a/content/renderer/media/media_recorder_handler.h
+++ b/content/renderer/media/media_recorder_handler.h
@@ -14,6 +14,7 @@
 #include "base/strings/string_piece.h"
 #include "base/threading/thread_checker.h"
 #include "content/common/content_export.h"
+#include "content/renderer/media/video_track_recorder.h"
 #include "third_party/WebKit/public/platform/WebMediaRecorderHandler.h"
 #include "third_party/WebKit/public/platform/WebMediaStream.h"
 
@@ -31,7 +32,6 @@
 
 namespace content {
 
-class VideoTrackRecorder;
 class AudioTrackRecorder;
 
 // MediaRecorderHandler orchestrates the creation, lifetime management and
@@ -89,8 +89,8 @@
   int32_t video_bits_per_second_;
   int32_t audio_bits_per_second_;
 
-  // Force using VP9 for video encoding, otherwise VP8 will be used by default.
-  bool use_vp9_;
+  // Video Codec, VP8 is used by default.
+  VideoTrackRecorder::CodecId codec_id_;
 
   // |client_| has no notion of time, thus may configure us via start(timeslice)
   // to notify it after a certain |timeslice_| has passed. We use a moving
diff --git a/content/renderer/media/media_recorder_handler_unittest.cc b/content/renderer/media/media_recorder_handler_unittest.cc
index 5bc99ae..53438f8 100644
--- a/content/renderer/media/media_recorder_handler_unittest.cc
+++ b/content/renderer/media/media_recorder_handler_unittest.cc
@@ -59,6 +59,9 @@
 static const MediaRecorderTestParams kMediaRecorderTestParams[] = {
     {true, false, "video/webm", "vp8"},
     {true, false, "video/webm", "vp9"},
+#if BUILDFLAG(RTC_USE_H264)
+    {true, false, "video/webm", "h264"},
+#endif
     {false, true, "video/webm", "vp8"}};
 
 class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>,
@@ -156,6 +159,9 @@
   const WebString example_good_codecs_3(base::UTF8ToUTF16("VP9,opus"));
   EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(
                   mime_type_video, example_good_codecs_3));
+  const WebString example_good_codecs_4(base::UTF8ToUTF16("H264"));
+  EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(
+                  mime_type_video, example_good_codecs_4));
 
   const WebString example_unsupported_codecs_1(base::UTF8ToUTF16("daala"));
   EXPECT_FALSE(media_recorder_handler_->canSupportMimeType(
@@ -164,12 +170,12 @@
   const WebString mime_type_audio(base::UTF8ToUTF16("audio/webm"));
   EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(
                   mime_type_audio, WebString()));
-  const WebString example_good_codecs_4(base::UTF8ToUTF16("opus"));
-  EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(
-                  mime_type_audio, example_good_codecs_4));
-  const WebString example_good_codecs_5(base::UTF8ToUTF16("OpUs"));
+  const WebString example_good_codecs_5(base::UTF8ToUTF16("opus"));
   EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(
                   mime_type_audio, example_good_codecs_5));
+  const WebString example_good_codecs_6(base::UTF8ToUTF16("OpUs"));
+  EXPECT_TRUE(media_recorder_handler_->canSupportMimeType(
+                  mime_type_audio, example_good_codecs_6));
 
   const WebString example_unsupported_codecs_2(base::UTF8ToUTF16("vorbis"));
   EXPECT_FALSE(media_recorder_handler_->canSupportMimeType(
@@ -221,8 +227,8 @@
   const scoped_refptr<media::VideoFrame> video_frame =
       media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80));
 
-  const size_t kEncodedSizeThreshold = 16;
   {
+    const size_t kEncodedSizeThreshold = 16;
     base::RunLoop run_loop;
     base::Closure quit_closure = run_loop.QuitClosure();
     // writeData() is pinged a number of times as the WebM header is written;
@@ -239,6 +245,7 @@
   Mock::VerifyAndClearExpectations(this);
 
   {
+    const size_t kEncodedSizeThreshold = 13;
     base::RunLoop run_loop;
     base::Closure quit_closure = run_loop.QuitClosure();
     // The second time around writeData() is called a number of times to write
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
index 6b12cd1..f5aec5e 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -301,14 +301,13 @@
       &configuration->enable_rtp_data_channel)) {
     configuration->enable_rtp_data_channel = false;
   }
-  // TODO: Special treatment for screencast min bitrate, since it's an integer.
-  // if (FindConstraint(constraints,
-  //                   MediaConstraintsInterface::kScreencastMinBitrate,
-  //                   &configuration->screencast_min_bitrate, NULL)) {
-  //  configuration->override_screencast_min_bitrate = true;
-  // }
-  // Note: If an optional is not present, webrtc decides on its own
-  // what the value should be.
+  int rate;
+  if (GetConstraintValueAsInteger(
+          constraints,
+          &blink::WebMediaTrackConstraintSet::googScreencastMinBitrate,
+          &rate)) {
+    configuration->screencast_min_bitrate = rtc::Optional<int>(rate);
+  }
   configuration->combined_audio_video_bwe = ConstraintToOptional(
       constraints,
       &blink::WebMediaTrackConstraintSet::googCombinedAudioVideoBwe);
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 17925e9..16097c1e 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -781,22 +781,55 @@
   }
 }
 
-void PepperPluginInstanceImpl::CommitBackingTexture() {
+void PepperPluginInstanceImpl::CommitTextureMailbox(
+    const cc::TextureMailbox& texture_mailbox) {
+  if (committed_texture_.IsValid() && !committed_texture_in_use_) {
+    bound_graphics_3d_->ReturnFrontBuffer(
+        committed_texture_.mailbox(), committed_texture_consumed_sync_token_,
+        false);
+  }
+
+  committed_texture_ = texture_mailbox;
+  committed_texture_in_use_ = false;
+
   if (!texture_layer_) {
     UpdateLayer(true);
     return;
   }
 
-  gpu::Mailbox mailbox;
-  gpu::SyncToken sync_token;
-  bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_token);
-  DCHECK(!mailbox.IsZero());
-  DCHECK(sync_token.HasData());
-  texture_layer_->SetTextureMailboxWithoutReleaseCallback(
-      cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D));
+  PassCommittedTextureToTextureLayer();
   texture_layer_->SetNeedsDisplay();
 }
 
+void PepperPluginInstanceImpl::PassCommittedTextureToTextureLayer() {
+  DCHECK(bound_graphics_3d_);
+
+  if (!committed_texture_.IsValid())
+    return;
+
+  std::unique_ptr<cc::SingleReleaseCallback> callback(
+      cc::SingleReleaseCallback::Create(base::Bind(
+          &PepperPluginInstanceImpl::FinishedConsumingCommittedTexture,
+          weak_factory_.GetWeakPtr(), committed_texture_)));
+
+  committed_texture_in_use_ = true;
+  texture_layer_->SetTextureMailbox(committed_texture_, std::move(callback));
+}
+
+void PepperPluginInstanceImpl::FinishedConsumingCommittedTexture(
+    const cc::TextureMailbox& texture_mailbox,
+    const gpu::SyncToken& sync_token,
+    bool is_lost) {
+  if (committed_texture_.mailbox() == texture_mailbox.mailbox() && !is_lost) {
+    committed_texture_in_use_ = false;
+    committed_texture_consumed_sync_token_ = sync_token;
+    return;
+  }
+
+  bound_graphics_3d_->ReturnFrontBuffer(texture_mailbox.mailbox(), sync_token,
+                                        is_lost);
+}
+
 void PepperPluginInstanceImpl::InstanceCrashed() {
   // Force free all resources and vars.
   HostGlobals::Get()->InstanceCrashed(pp_instance());
@@ -2017,12 +2050,7 @@
   if (!container_)
     return;
 
-  gpu::Mailbox mailbox;
-  gpu::SyncToken sync_token;
-  if (bound_graphics_3d_.get()) {
-    bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_token);
-  }
-  bool want_3d_layer = !mailbox.IsZero() && sync_token.HasData();
+  bool want_3d_layer = !!bound_graphics_3d_.get();
   bool want_2d_layer = !!bound_graphics_2d_platform_;
   bool want_texture_layer = want_3d_layer || want_2d_layer;
   bool want_compositor_layer = !!bound_compositor_;
@@ -2061,8 +2089,8 @@
       DCHECK(bound_graphics_3d_.get());
       texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL);
       opaque = bound_graphics_3d_->IsOpaque();
-      texture_layer_->SetTextureMailboxWithoutReleaseCallback(
-          cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D));
+
+      PassCommittedTextureToTextureLayer();
     } else {
       DCHECK(bound_graphics_2d_platform_);
       texture_layer_ = cc::TextureLayer::CreateForMailbox(this);
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h
index da46179..315381f 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -24,6 +24,7 @@
 #include "cc/layers/content_layer_client.h"
 #include "cc/layers/layer.h"
 #include "cc/layers/texture_layer_client.h"
+#include "cc/resources/texture_mailbox.h"
 #include "content/common/content_export.h"
 #include "content/public/renderer/pepper_plugin_instance.h"
 #include "content/public/renderer/plugin_instance_throttler.h"
@@ -197,9 +198,17 @@
   // slow path can also be triggered if there is an overlapping frame.
   void ScrollRect(int dx, int dy, const gfx::Rect& rect);
 
-  // Commit the backing texture to the screen once the side effects some
-  // rendering up to an offscreen SwapBuffers are visible.
-  void CommitBackingTexture();
+  // Commit the texture mailbox to the screen.
+  void CommitTextureMailbox(const cc::TextureMailbox& texture_mailbox);
+
+  // Passes the committed texture to |texture_layer_| and marks it as in use.
+  void PassCommittedTextureToTextureLayer();
+
+  // Callback when the compositor is finished consuming the committed texture.
+  void FinishedConsumingCommittedTexture(
+      const cc::TextureMailbox& texture_mailbox,
+      const gpu::SyncToken& sync_token,
+      bool is_lost);
 
   // Called when the out-of-process plugin implementing this instance crashed.
   void InstanceCrashed();
@@ -933,6 +942,16 @@
   // The text that is currently selected in the plugin.
   base::string16 selected_text_;
 
+  // The most recently committed texture. This is kept around in case the layer
+  // needs to be regenerated.
+  cc::TextureMailbox committed_texture_;
+
+  // Whether the most recently committed texture is still in use by the
+  // compositor.
+  bool committed_texture_in_use_ = false;
+
+  gpu::SyncToken committed_texture_consumed_sync_token_;
+
   bool initialized_;
 
   // We use a weak ptr factory for scheduling DidChangeView events so that we
diff --git a/content/renderer/pepper/pepper_video_encoder_host.cc b/content/renderer/pepper/pepper_video_encoder_host.cc
index 3047b38b..ecc796330 100644
--- a/content/renderer/pepper/pepper_video_encoder_host.cc
+++ b/content/renderer/pepper/pepper_video_encoder_host.cc
@@ -242,6 +242,10 @@
   NotifyPepperError(PP_ERROR_RESOURCE_FAILED);
 }
 
+void PepperVideoEncoderHost::OnGpuControlLostContextMaybeReentrant() {
+  // No internal state to update on lost context.
+}
+
 int32_t PepperVideoEncoderHost::OnHostMsgGetSupportedProfiles(
     ppapi::host::HostMessageContext* context) {
   std::vector<PP_VideoProfileDescription> pp_profiles;
diff --git a/content/renderer/pepper/pepper_video_encoder_host.h b/content/renderer/pepper/pepper_video_encoder_host.h
index afa8ffe..fef17f3 100644
--- a/content/renderer/pepper/pepper_video_encoder_host.h
+++ b/content/renderer/pepper/pepper_video_encoder_host.h
@@ -81,6 +81,7 @@
 
   // GpuControlClient implementation.
   void OnGpuControlLostContext() final;
+  void OnGpuControlLostContextMaybeReentrant() final;
   void OnGpuControlErrorMessage(const char* msg, int id) final {}
 
   int32_t OnHostMsgGetSupportedProfiles(
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc
index 24c6513..0681198 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -28,6 +28,7 @@
 #include "third_party/WebKit/public/web/WebElement.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebPluginContainer.h"
+#include "third_party/khronos/GLES2/gl2.h"
 
 using ppapi::thunk::EnterResourceNoLock;
 using ppapi::thunk::PPB_Graphics3D_API;
@@ -114,6 +115,23 @@
   command_buffer_->EnsureWorkVisible();
 }
 
+void PPB_Graphics3D_Impl::TakeFrontBuffer() {
+  if (!taken_front_buffer_.IsZero()) {
+    DLOG(ERROR)
+        << "TakeFrontBuffer should only be called once before DoSwapBuffers";
+    return;
+  }
+  taken_front_buffer_ = GenerateMailbox();
+  command_buffer_->TakeFrontBuffer(taken_front_buffer_);
+}
+
+void PPB_Graphics3D_Impl::ReturnFrontBuffer(const gpu::Mailbox& mailbox,
+                                            const gpu::SyncToken& sync_token,
+                                            bool is_lost) {
+  command_buffer_->ReturnFrontBuffer(mailbox, sync_token, is_lost);
+  mailboxes_to_reuse_.push_back(mailbox);
+}
+
 bool PPB_Graphics3D_Impl::BindToInstance(bool bind) {
   bound_to_instance_ = bind;
   return true;
@@ -143,8 +161,10 @@
 
 int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token) {
   DCHECK(command_buffer_);
-  if (sync_token.HasData())
-    sync_token_ = sync_token;
+  if (taken_front_buffer_.IsZero()) {
+    DLOG(ERROR) << "TakeFrontBuffer should be called before DoSwapBuffers";
+    return PP_ERROR_FAILED;
+  }
 
   if (bound_to_instance_) {
     // If we are bound to the instance, we need to ask the compositor
@@ -154,14 +174,18 @@
     //
     // Don't need to check for NULL from GetPluginInstance since when we're
     // bound, we know our instance is valid.
-    HostGlobals::Get()->GetInstance(pp_instance())->CommitBackingTexture();
+    cc::TextureMailbox texture_mailbox(taken_front_buffer_, sync_token,
+                                       GL_TEXTURE_2D);
+    taken_front_buffer_.SetZero();
+    HostGlobals::Get()
+        ->GetInstance(pp_instance())
+        ->CommitTextureMailbox(texture_mailbox);
     commit_pending_ = true;
   } else {
     // Wait for the command to complete on the GPU to allow for throttling.
     command_buffer_->SignalSyncToken(
-        sync_token_,
-        base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
-                   weak_ptr_factory_.GetWeakPtr()));
+        sync_token, base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers,
+                               weak_ptr_factory_.GetWeakPtr()));
   }
 
   return PP_OK_COMPLETIONPENDING;
@@ -262,10 +286,6 @@
   if (command_buffer_id)
     *command_buffer_id = command_buffer_->GetCommandBufferID();
 
-  mailbox_ = gpu::Mailbox::Generate();
-  if (!command_buffer_->ProduceFrontBuffer(mailbox_))
-    return false;
-
   return true;
 }
 
@@ -306,6 +326,10 @@
                             weak_ptr_factory_.GetWeakPtr()));
 }
 
+void PPB_Graphics3D_Impl::OnGpuControlLostContextMaybeReentrant() {
+  // No internal state to update on lost context.
+}
+
 void PPB_Graphics3D_Impl::OnSwapBuffers() {
   if (HasPendingSwap()) {
     // If we're off-screen, no need to trigger and wait for compositing.
@@ -339,4 +363,14 @@
     ppp_graphics_3d->Graphics3DContextLost(this_pp_instance);
 }
 
+gpu::Mailbox PPB_Graphics3D_Impl::GenerateMailbox() {
+  if (!mailboxes_to_reuse_.empty()) {
+    gpu::Mailbox mailbox = mailboxes_to_reuse_.back();
+    mailboxes_to_reuse_.pop_back();
+    return mailbox;
+  }
+
+  return gpu::Mailbox::Generate();
+}
+
 }  // namespace content
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.h b/content/renderer/pepper/ppb_graphics_3d_impl.h
index b356b50..158f319 100644
--- a/content/renderer/pepper/ppb_graphics_3d_impl.h
+++ b/content/renderer/pepper/ppb_graphics_3d_impl.h
@@ -48,6 +48,10 @@
   gpu::CommandBuffer::State WaitForGetOffsetInRange(int32_t start,
                                                     int32_t end) override;
   void EnsureWorkVisible() override;
+  void TakeFrontBuffer() override;
+  void ReturnFrontBuffer(const gpu::Mailbox& mailbox,
+                         const gpu::SyncToken& sync_token,
+                         bool is_lost);
 
   // Binds/unbinds the graphics of this context with the associated instance.
   // Returns true if binding/unbinding is successful.
@@ -60,11 +64,6 @@
   // These messages are used to send Flush callbacks to the plugin.
   void ViewInitiatedPaint();
 
-  void GetBackingMailbox(gpu::Mailbox* mailbox, gpu::SyncToken* sync_token) {
-    *mailbox = mailbox_;
-    *sync_token = sync_token_;
-  }
-
   gpu::CommandBufferProxyImpl* GetCommandBufferProxy();
 
   gpu::GpuChannelHost* channel() { return channel_.get(); }
@@ -87,6 +86,7 @@
 
   // GpuControlClient implementation.
   void OnGpuControlLostContext() final;
+  void OnGpuControlLostContextMaybeReentrant() final;
   void OnGpuControlErrorMessage(const char* msg, int id) final;
 
   // Other notifications from the GPU process.
@@ -94,6 +94,16 @@
   // Notifications sent to plugin.
   void SendContextLost();
 
+  // Reuses a mailbox if one is available, otherwise makes a new one.
+  gpu::Mailbox GenerateMailbox();
+
+  // A front buffer that was recently taken from the command buffer. This should
+  // be immediately consumed by DoSwapBuffers().
+  gpu::Mailbox taken_front_buffer_;
+
+  // Mailboxes that are no longer in use.
+  std::vector<gpu::Mailbox> mailboxes_to_reuse_;
+
   // True if context is bound to instance.
   bool bound_to_instance_;
   // True when waiting for compositor to commit our backing texture.
@@ -103,8 +113,6 @@
   bool lost_context_ = false;
 #endif
 
-  gpu::Mailbox mailbox_;
-  gpu::SyncToken sync_token_;
   bool has_alpha_;
   scoped_refptr<gpu::GpuChannelHost> channel_;
   std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 8994b8d..029ec0bc 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -5769,11 +5769,6 @@
     return false;
   }
 
-  if (RenderThreadImpl::current() &&
-      RenderThreadImpl::current()->layout_test_mode()) {
-    return false;
-  }
-
   return true;
 }
 
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index b9e42b7b..9530526 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -394,8 +394,9 @@
     return agent()->paused_;
   }
 
-  void DispatchDevToolsMessage(const std::string& message) {
-    agent()->OnDispatchOnInspectorBackend(17, message);
+  void DispatchDevToolsMessage(const std::string& method,
+                               const std::string& message) {
+    agent()->OnDispatchOnInspectorBackend(17, 1, method, message);
   }
 
   void CloseWhilePaused() {
@@ -2370,7 +2371,8 @@
 TEST_F(DevToolsAgentTest, DevToolsResumeOnClose) {
   Attach();
   EXPECT_FALSE(IsPaused());
-  DispatchDevToolsMessage("{\"id\":1,\"method\":\"Debugger.enable\"}");
+  DispatchDevToolsMessage("Debugger.enable",
+                          "{\"id\":1,\"method\":\"Debugger.enable\"}");
 
   // Executing javascript will pause the thread and create nested message loop.
   // Posting task simulates message coming from browser.
@@ -2387,13 +2389,15 @@
 TEST_F(DevToolsAgentTest, RuntimeEnableForcesContexts) {
   LoadHTML("<body>page<iframe></iframe></body>");
   Attach();
-  DispatchDevToolsMessage("{\"id\":1,\"method\":\"Runtime.enable\"}");
+  DispatchDevToolsMessage("Runtime.enable",
+                          "{\"id\":1,\"method\":\"Runtime.enable\"}");
   EXPECT_EQ(2, CountNotifications("Runtime.executionContextCreated"));
 }
 
 TEST_F(DevToolsAgentTest, RuntimeEnableForcesContextsAfterNavigation) {
   Attach();
-  DispatchDevToolsMessage("{\"id\":1,\"method\":\"Runtime.enable\"}");
+  DispatchDevToolsMessage("Runtime.enable",
+                          "{\"id\":1,\"method\":\"Runtime.enable\"}");
   EXPECT_EQ(0, CountNotifications("Runtime.executionContextCreated"));
   LoadHTML("<body>page<iframe></iframe></body>");
   EXPECT_EQ(2, CountNotifications("Runtime.executionContextCreated"));
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index bcdf803..5d5bad3 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -2070,6 +2070,109 @@
   }
 }
 
+bool RenderViewImpl::allowsBrokenNullLayerTreeView() const {
+  return RenderWidget::allowsBrokenNullLayerTreeView();
+}
+
+void RenderViewImpl::closeWidgetSoon() {
+  RenderWidget::closeWidgetSoon();
+}
+
+void RenderViewImpl::convertViewportToWindow(blink::WebRect* rect) {
+  RenderWidget::convertViewportToWindow(rect);
+}
+
+void RenderViewImpl::convertWindowToViewport(blink::WebFloatRect* rect) {
+  RenderWidget::convertWindowToViewport(rect);
+}
+
+void RenderViewImpl::didAutoResize(const blink::WebSize& newSize) {
+  RenderWidget::didAutoResize(newSize);
+}
+
+void RenderViewImpl::didChangeCursor(const blink::WebCursorInfo& info) {
+  RenderWidget::didChangeCursor(info);
+}
+
+void RenderViewImpl::didInvalidateRect(const blink::WebRect& rect) {
+  RenderWidget::didInvalidateRect(rect);
+}
+
+void RenderViewImpl::didMeaningfulLayout(
+    blink::WebMeaningfulLayout layout_type) {
+  RenderWidget::didMeaningfulLayout(layout_type);
+}
+
+void RenderViewImpl::didOverscroll(
+    const blink::WebFloatSize& overscrollDelta,
+    const blink::WebFloatSize& accumulatedOverscroll,
+    const blink::WebFloatPoint& positionInViewport,
+    const blink::WebFloatSize& velocityInViewport) {
+  RenderWidget::didOverscroll(overscrollDelta, accumulatedOverscroll,
+                              positionInViewport, velocityInViewport);
+}
+
+void RenderViewImpl::didUpdateTextOfFocusedElementByNonUserInput() {
+  RenderWidget::didUpdateTextOfFocusedElementByNonUserInput();
+}
+
+void RenderViewImpl::hasTouchEventHandlers(bool has_handlers) {
+  RenderWidget::hasTouchEventHandlers(has_handlers);
+}
+
+blink::WebLayerTreeView* RenderViewImpl::layerTreeView() {
+  return RenderWidget::layerTreeView();
+}
+
+void RenderViewImpl::resetInputMethod() {
+  RenderWidget::resetInputMethod();
+}
+
+blink::WebRect RenderViewImpl::rootWindowRect() {
+  return RenderWidget::rootWindowRect();
+}
+
+void RenderViewImpl::scheduleAnimation() {
+  RenderWidget::scheduleAnimation();
+}
+
+blink::WebScreenInfo RenderViewImpl::screenInfo() {
+  return RenderWidget::screenInfo();
+}
+
+void RenderViewImpl::setToolTipText(const blink::WebString& text,
+                                    blink::WebTextDirection hint) {
+  RenderWidget::setToolTipText(text, hint);
+}
+
+void RenderViewImpl::setTouchAction(blink::WebTouchAction touchAction) {
+  RenderWidget::setTouchAction(touchAction);
+}
+
+void RenderViewImpl::setWindowRect(const blink::WebRect& rect) {
+  RenderWidget::setWindowRect(rect);
+}
+
+void RenderViewImpl::showImeIfNeeded() {
+  RenderWidget::showImeIfNeeded();
+}
+
+void RenderViewImpl::showUnhandledTapUIIfNeeded(
+    const blink::WebPoint& tappedPosition,
+    const blink::WebNode& tappedNode,
+    bool pageChanged) {
+  RenderWidget::showUnhandledTapUIIfNeeded(tappedPosition, tappedNode,
+                                           pageChanged);
+}
+
+blink::WebRect RenderViewImpl::windowRect() {
+  return RenderWidget::windowRect();
+}
+
+blink::WebRect RenderViewImpl::windowResizerRect() {
+  return RenderWidget::windowResizerRect();
+}
+
 // blink::WebFrameClient -----------------------------------------------------
 
 void RenderViewImpl::Repaint(const gfx::Size& size) {
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index fe284de..4c3d165 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -319,9 +319,40 @@
   void didHandleGestureEvent(const blink::WebGestureEvent& event,
                              bool event_cancelled) override;
   void onMouseDown(const blink::WebNode& mouse_down_node) override;
-
   void initializeLayerTreeView() override;
 
+  // TODO(lfg): Remove once WebViewClient no longer inherits from
+  // WebWidgetClient.
+  bool allowsBrokenNullLayerTreeView() const override;
+  void closeWidgetSoon() override;
+  void convertViewportToWindow(blink::WebRect* rect) override;
+  void convertWindowToViewport(blink::WebFloatRect* rect) override;
+  void didAutoResize(const blink::WebSize& newSize) override;
+  void didChangeCursor(const blink::WebCursorInfo& info) override;
+  void didInvalidateRect(const blink::WebRect& rect) override;
+  void didMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override;
+  void didOverscroll(const blink::WebFloatSize& overscrollDelta,
+                     const blink::WebFloatSize& accumulatedOverscroll,
+                     const blink::WebFloatPoint& positionInViewport,
+                     const blink::WebFloatSize& velocityInViewport) override;
+  void didUpdateTextOfFocusedElementByNonUserInput() override;
+  void hasTouchEventHandlers(bool has_handlers) override;
+  blink::WebLayerTreeView* layerTreeView() override;
+  void resetInputMethod() override;
+  blink::WebRect rootWindowRect() override;
+  void scheduleAnimation() override;
+  blink::WebScreenInfo screenInfo() override;
+  void setToolTipText(const blink::WebString&,
+                      blink::WebTextDirection hint) override;
+  void setTouchAction(blink::WebTouchAction touchAction) override;
+  void setWindowRect(const blink::WebRect& rect) override;
+  void showImeIfNeeded() override;
+  void showUnhandledTapUIIfNeeded(const blink::WebPoint& tappedPosition,
+                                  const blink::WebNode& tappedNode,
+                                  bool pageChanged) override;
+  blink::WebRect windowRect() override;
+  blink::WebRect windowResizerRect() override;
+
   // blink::WebViewClient implementation --------------------------------------
 
   blink::WebView* createView(blink::WebLocalFrame* creator,
diff --git a/content/renderer/service_worker/embedded_worker_devtools_agent.cc b/content/renderer/service_worker/embedded_worker_devtools_agent.cc
index 6d44d5f2..150f4d9 100644
--- a/content/renderer/service_worker/embedded_worker_devtools_agent.cc
+++ b/content/renderer/service_worker/embedded_worker_devtools_agent.cc
@@ -57,8 +57,12 @@
 
 void EmbeddedWorkerDevToolsAgent::OnDispatchOnInspectorBackend(
     int session_id,
+    int call_id,
+    const std::string& method,
     const std::string& message) {
-  webworker_->dispatchDevToolsMessage(session_id, WebString::fromUTF8(message));
+  webworker_->dispatchDevToolsMessage(session_id, call_id,
+                                      WebString::fromUTF8(method),
+                                      WebString::fromUTF8(message));
 }
 
 }  // namespace content
diff --git a/content/renderer/service_worker/embedded_worker_devtools_agent.h b/content/renderer/service_worker/embedded_worker_devtools_agent.h
index afb6ba8..668bd9822 100644
--- a/content/renderer/service_worker/embedded_worker_devtools_agent.h
+++ b/content/renderer/service_worker/embedded_worker_devtools_agent.h
@@ -35,7 +35,10 @@
                   int session_id,
                   const std::string& state);
   void OnDetach();
-  void OnDispatchOnInspectorBackend(int session_id, const std::string& message);
+  void OnDispatchOnInspectorBackend(int session_id,
+                                    int call_id,
+                                    const std::string& method,
+                                    const std::string& message);
 
   blink::WebEmbeddedWorker* webworker_;
   int route_id_;
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index caf5ad90..855fa20c 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -15,6 +15,7 @@
   import("//build/config/android/config.gni")
 } else if (is_mac) {
   import("//build/config/mac/rules.gni")
+  import("//build_overrides/v8.gni")
 }
 
 declare_args() {
@@ -430,11 +431,22 @@
     ]
   }
 } else if (is_mac) {
-  group("content_shell") {
+  mac_app_bundle("content_shell") {
     testonly = true
-    deps = [
-      ":content_shell_lib",
+    output_name = content_shell_product_name
+    sources = [
+      "app/shell_main.cc",
     ]
+    deps = [
+      ":content_shell_framework_bundle_data",
+      ":content_shell_resources_bundle_data",
+
+      # TODO(rsesek): Remove this after GYP is gone, since it only needs to
+      # be here per the comment in blink_test_platform_support_mac.mm about
+      # the bundle structure.
+      "//components/test_runner:resources",
+    ]
+    info_plist = "app/app-Info.plist"
   }
 } else {
   # TODO(brettw) when GYP is no longer necessary, delete
@@ -470,15 +482,6 @@
       }
     }
 
-    if (is_mac) {
-      # TODO(GYP) lots of stuff from GYP file here including helper_app and
-      # postbuilds.
-      output_name = content_shell_product_name
-      deps = [
-        ":framework",
-      ]
-    }
-
     if (is_linux && !is_component_build) {
       # Set rpath to find our own libfreetype even in a non-component build.
       configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
@@ -506,36 +509,173 @@
 }
 
 if (is_mac) {
-  # TODO(GYP) this should be a bundle. Lots of other stuff in this target.
-  # GYP version: content/content_shell.gypi:content_shell_framework
-  shared_library("framework") {
+  mac_xib_bundle_data("content_shell_framework_xibs") {
+    sources = [
+      "app/English.lproj/HttpAuth.xib",
+      "app/English.lproj/MainMenu.xib",
+    ]
+    output_path = "{{bundle_resources_dir}}/English.lproj"
+  }
+
+  bundle_data("content_shell_framework_resources") {
+    sources = [
+      "$root_out_dir/content_shell.pak",
+      "$root_out_dir/icudtl.dat",
+      "resources/missingImage.png",
+      "resources/textAreaResizeCorner.png",
+    ]
+
+    public_deps = [
+      ":pak",
+    ]
+
+    deps = [
+      "//third_party/icu:icudata",
+    ]
+
+    if (v8_use_external_startup_data) {
+      sources += [
+        "$root_out_dir/natives_blob.bin",
+        "$root_out_dir/snapshot_blob.bin",
+      ]
+      public_deps += [ "//v8" ]
+    }
+
+    outputs = [
+      "{{bundle_resources_dir}}/{{source_file_part}}",
+    ]
+  }
+
+  if (enable_plugins) {
+    bundle_data("content_shell_framework_plugins") {
+      sources = [
+        "$root_out_dir/blink_deprecated_test_plugin.plugin",
+        "$root_out_dir/blink_test_plugin.plugin",
+      ]
+
+      outputs = [
+        "{{bundle_root_dir}}/{{source_file_part}}",
+      ]
+
+      public_deps = [
+        "//ppapi:blink_deprecated_test_plugin",
+        "//ppapi:blink_test_plugin",
+      ]
+    }
+  }
+
+  content_shell_framework_name = "$content_shell_product_name Framework"
+  content_shell_helper_name = "$content_shell_product_name Helper"
+
+  mac_framework_bundle("content_shell_framework") {
     testonly = true
 
-    # TODO(GYP) bug 546894: Fix GN and toolchains to handle spaces here.
-    #output_name = "$content_shell_product_name Framework"
-    output_name = "content_shell_framework"  # Temporary one with no spaces.
+    output_name = content_shell_framework_name
 
     sources = [
       "app/shell_content_main.cc",
       "app/shell_content_main.h",
     ]
 
+    # TODO(rsesek): Handle these missing pieces:
+    #   - crash_inspector
+    #   - crash_report_sender.app
+
     deps = [
+      ":content_shell_framework_resources",
+      ":content_shell_framework_xibs",
       ":content_shell_lib",
+      "//third_party/icu:icudata",
     ]
+
+    if (enable_plugins) {
+      deps += [ ":content_shell_framework_plugins" ]
+    }
+
+    ldflags = [
+      "-install_name",
+      "@executable_path/../Frameworks/$output_name.framework/$output_name",
+    ]
+
+    info_plist = "app/framework-Info.plist"
   }
 
   mac_app_bundle("content_shell_helper_app") {
     testonly = true
-    output_name = "$content_shell_product_name Helper"
+    output_name = content_shell_helper_name
     sources = [
       "app/shell_main.cc",
     ]
     deps = [
-      ":framework",
+      ":content_shell_framework+link",
     ]
     info_plist = "app/helper-Info.plist"
   }
+
+  # The install_name_tool can only operate in-place, rather than producing a
+  # unique output. Use the xcrun wrapper script to write a fake stamp output
+  # file. After :content_shell_helper_app has been built and bundled, this
+  # will run, modifying the executable in the bundle and writing out the
+  # --stamp specified. This will change the mtime on the executable, but
+  # because the stamp will also be updated, the
+  # :content_shell_framework_bundle_data will re-copy the output. This only
+  # works because nothing else depends on the output of
+  # :content_shell_helper_app.
+  # TODO(rsesek): After GYP is gone, re-write content_shell_main to be like
+  # chrome_main and use dlopen() instead of a linked framework.
+  action("fix_helper_link_framework") {
+    testonly = true
+    script = "//build/config/mac/xcrun.py"
+    inputs = [
+      "$root_out_dir/$content_shell_helper_name.app/Contents/MacOS/$content_shell_helper_name",
+    ]
+
+    stamp_file = "$target_out_dir/xcrun_$target_name.stamp"
+    outputs = [
+      stamp_file,
+    ]
+
+    # TODO(rsesek): Figure out something like GYP's postbuilds to allow
+    # install_name_tool to operate in-place <https://crbug.com/607292>.
+    args = [
+             "--stamp",
+             rebase_path(stamp_file, root_build_dir),
+
+             # xcrun arguments:
+             "install_name_tool",
+             "-change",
+             "@executable_path/../Frameworks/$content_shell_framework_name.framework/$content_shell_framework_name",
+             "@executable_path/../../../$content_shell_framework_name.framework/$content_shell_framework_name",
+           ] + rebase_path(inputs, root_build_dir)
+    public_deps = [
+      ":content_shell_helper_app",
+    ]
+  }
+
+  bundle_data("content_shell_framework_bundle_data") {
+    testonly = true
+    sources = [
+      "$root_out_dir/$content_shell_framework_name.framework",
+      "$root_out_dir/$content_shell_helper_name.app",
+    ]
+    outputs = [
+      "{{bundle_root_dir}}/Frameworks/{{source_file_part}}",
+    ]
+    public_deps = [
+      ":content_shell_framework+link",
+      ":fix_helper_link_framework",
+    ]
+  }
+
+  bundle_data("content_shell_resources_bundle_data") {
+    testonly = true
+    sources = [
+      "app/app.icns",
+    ]
+    outputs = [
+      "{{bundle_resources_dir}}/{{source_file_part}}",
+    ]
+  }
 }
 
 mojom("mojo_bindings") {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index cd17f0a..20efd38 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -542,10 +542,7 @@
 
   if (is_mac) {
     sources += [ "../renderer/external_popup_menu_browsertest.cc" ]
-    deps += [
-      # Needed for Content Shell.app's Helper.
-      #"//content/shell:content_shell",  #TODO(GYP) enable for mac
-    ]
+    deps += [ "//content/shell:content_shell" ]
   }
 
   if (use_aura && !is_win) {
diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc
index a9592626..6285c38 100644
--- a/courgette/disassembler_elf_32.cc
+++ b/courgette/disassembler_elf_32.cc
@@ -169,6 +169,12 @@
   if (!ParseFile(target))
     return false;
 
+  std::sort(rel32_locations_.begin(),
+            rel32_locations_.end(),
+            TypedRVA::IsLessThanByRVA);
+  DCHECK(rel32_locations_.empty() ||
+         rel32_locations_.back()->rva() != kUnassignedRVA);
+
   target->DefaultAssignIndexes();
   return true;
 }
@@ -283,16 +289,23 @@
 
   std::vector<FileOffset> abs_offsets;
 
+  // File parsing follows file offset order, and we visit abs32 and rel32
+  // locations in lockstep. Therefore we need to extract and sort file offsets
+  // of all abs32 and rel32 locations.
   if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets))
     return false;
+  std::sort(abs32_locations_.begin(), abs32_locations_.end());
 
   if (!RVAsToFileOffsets(&rel32_locations_))
     return false;
+  std::sort(rel32_locations_.begin(),
+            rel32_locations_.end(),
+            TypedRVA::IsLessThanByFileOffset);
 
   std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin();
-  ScopedVector<TypedRVA>::iterator current_rel = rel32_locations_.begin();
-
   std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end();
+
+  ScopedVector<TypedRVA>::iterator current_rel = rel32_locations_.begin();
   ScopedVector<TypedRVA>::iterator end_rel = rel32_locations_.end();
 
   // Visit section headers ordered by file offset.
@@ -512,27 +525,32 @@
 
 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() {
   rel32_locations_.clear();
+  bool found_rel32 = false;
 
   // Loop through sections for relocation sections
   for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
        ++section_id) {
     const Elf32_Shdr* section_header = SectionHeader(section_id);
 
-    // TODO(huangs): Add better checks to skip non-code sections.
     // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0.
     if (section_header->sh_type != SHT_PROGBITS ||
         section_header->sh_addr == 0)
       continue;
 
+    // Heuristic: Only consider ".text" section.
+    std::string section_name;
+    if (!SectionName(*section_header, &section_name))
+      return false;
+    if (section_name != ".text")
+      continue;
+
+    found_rel32 = true;
     if (!ParseRel32RelocsFromSection(section_header))
       return false;
   }
+  if (!found_rel32)
+    VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?";
 
-  std::sort(rel32_locations_.begin(),
-            rel32_locations_.end(),
-            TypedRVA::IsLessThan);
-  DCHECK(rel32_locations_.empty() ||
-         rel32_locations_.back()->rva() != kUnassignedRVA);
   return true;
 }
 
diff --git a/courgette/disassembler_elf_32.h b/courgette/disassembler_elf_32.h
index 063c2e2..8793106 100644
--- a/courgette/disassembler_elf_32.h
+++ b/courgette/disassembler_elf_32.h
@@ -61,10 +61,15 @@
     virtual uint16_t op_size() const = 0;
 
     // Comparator for sorting, which assumes uniqueness of RVAs.
-    static bool IsLessThan(TypedRVA* a, TypedRVA* b) {
+    static bool IsLessThanByRVA(TypedRVA* a, TypedRVA* b) {
       return a->rva() < b->rva();
     }
 
+    // Comparator for sorting, which assumes uniqueness of file offsets.
+    static bool IsLessThanByFileOffset(TypedRVA* a, TypedRVA* b) {
+      return a->file_offset() < b->file_offset();
+    }
+
   private:
     const RVA rva_;
     RVA relative_target_ = kNoRVA;
@@ -163,6 +168,7 @@
 
   CheckBool CheckSection(RVA rva) WARN_UNUSED_RESULT;
 
+  // Extracts all rel32 TypedRVAs. Does not sort the result.
   CheckBool ParseRel32RelocsFromSections() WARN_UNUSED_RESULT;
 
   const Elf32_Ehdr* header_;
diff --git a/courgette/disassembler_elf_32_x86_unittest.cc b/courgette/disassembler_elf_32_x86_unittest.cc
index 521596b..7060dd3 100644
--- a/courgette/disassembler_elf_32_x86_unittest.cc
+++ b/courgette/disassembler_elf_32_x86_unittest.cc
@@ -131,8 +131,8 @@
 }  // namespace
 
 TEST_F(DisassemblerElf32X86Test, All) {
-  TestExe("elf-32-1", 200, 3441);
-  TestExe("elf-32-high-bss", 0, 13);
+  TestExe("elf-32-1", 200, 3337);
+  TestExe("elf-32-high-bss", 0, 4);
 }
 
 }  // namespace courgette
diff --git a/courgette/encode_decode_unittest.cc b/courgette/encode_decode_unittest.cc
index 7a7d7207..6c52e20 100644
--- a/courgette/encode_decode_unittest.cc
+++ b/courgette/encode_decode_unittest.cc
@@ -16,12 +16,12 @@
 class EncodeDecodeTest : public BaseTest {
  public:
   void TestAssembleToStreamDisassemble(std::string file,
-                                       size_t expected_encoded_lenth) const;
+                                       size_t expected_encoded_length) const;
 };
 
 void EncodeDecodeTest::TestAssembleToStreamDisassemble(
     std::string file,
-    size_t expected_encoded_lenth) const {
+    size_t expected_encoded_length) const {
   const void* original_buffer = file.c_str();
   size_t original_length = file.length();
 
@@ -52,7 +52,7 @@
   const void* buffer = sink.Buffer();
   size_t length = sink.Length();
 
-  EXPECT_EQ(expected_encoded_lenth, length);
+  EXPECT_EQ(expected_encoded_length, length);
 
   courgette::SourceStreamSet sources;
   bool can_get_source_streams = sources.Init(buffer, length);
@@ -88,12 +88,12 @@
 
 TEST_F(EncodeDecodeTest, Elf_Small) {
   std::string file = FileContents("elf-32-1");
-  TestAssembleToStreamDisassemble(file, 136218);
+  TestAssembleToStreamDisassemble(file, 136201);
 }
 
 TEST_F(EncodeDecodeTest, Elf_HighBSS) {
   std::string file = FileContents("elf-32-high-bss");
-  TestAssembleToStreamDisassemble(file, 7312);
+  TestAssembleToStreamDisassemble(file, 7308);
 }
 
 TEST_F(EncodeDecodeTest, Elf_Arm) {
diff --git a/device/BUILD.gn b/device/BUILD.gn
index acfb715..1f688037 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -163,6 +163,7 @@
       "bluetooth/bluez/bluetooth_bluez_unittest.cc",
       "bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc",
       "bluetooth/bluez/bluetooth_socket_bluez_unittest.cc",
+      "bluetooth/dbus/bluetooth_gatt_application_service_provider_unittest.cc",
       "bluetooth/test/bluetooth_test_bluez.cc",
       "bluetooth/test/bluetooth_test_bluez.h",
     ]
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 3fff20b..65347485 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -218,20 +218,35 @@
         "dbus/bluetooth_dbus_client_bundle.h",
         "dbus/bluetooth_device_client.cc",
         "dbus/bluetooth_device_client.h",
+        "dbus/bluetooth_gatt_application_service_provider.cc",
+        "dbus/bluetooth_gatt_application_service_provider.h",
+        "dbus/bluetooth_gatt_application_service_provider_impl.cc",
+        "dbus/bluetooth_gatt_application_service_provider_impl.h",
+        "dbus/bluetooth_gatt_attribute_value_delegate.h",
         "dbus/bluetooth_gatt_characteristic_client.cc",
         "dbus/bluetooth_gatt_characteristic_client.h",
+        "dbus/bluetooth_gatt_characteristic_delegate_wrapper.cc",
+        "dbus/bluetooth_gatt_characteristic_delegate_wrapper.h",
         "dbus/bluetooth_gatt_characteristic_service_provider.cc",
         "dbus/bluetooth_gatt_characteristic_service_provider.h",
+        "dbus/bluetooth_gatt_characteristic_service_provider_impl.cc",
+        "dbus/bluetooth_gatt_characteristic_service_provider_impl.h",
         "dbus/bluetooth_gatt_descriptor_client.cc",
         "dbus/bluetooth_gatt_descriptor_client.h",
+        "dbus/bluetooth_gatt_descriptor_delegate_wrapper.cc",
+        "dbus/bluetooth_gatt_descriptor_delegate_wrapper.h",
         "dbus/bluetooth_gatt_descriptor_service_provider.cc",
         "dbus/bluetooth_gatt_descriptor_service_provider.h",
+        "dbus/bluetooth_gatt_descriptor_service_provider_impl.cc",
+        "dbus/bluetooth_gatt_descriptor_service_provider_impl.h",
         "dbus/bluetooth_gatt_manager_client.cc",
         "dbus/bluetooth_gatt_manager_client.h",
         "dbus/bluetooth_gatt_service_client.cc",
         "dbus/bluetooth_gatt_service_client.h",
         "dbus/bluetooth_gatt_service_service_provider.cc",
         "dbus/bluetooth_gatt_service_service_provider.h",
+        "dbus/bluetooth_gatt_service_service_provider_impl.cc",
+        "dbus/bluetooth_gatt_service_service_provider_impl.h",
         "dbus/bluetooth_input_client.cc",
         "dbus/bluetooth_input_client.h",
         "dbus/bluetooth_le_advertisement_service_provider.cc",
@@ -259,6 +274,8 @@
         "dbus/fake_bluetooth_agent_service_provider.h",
         "dbus/fake_bluetooth_device_client.cc",
         "dbus/fake_bluetooth_device_client.h",
+        "dbus/fake_bluetooth_gatt_application_service_provider.cc",
+        "dbus/fake_bluetooth_gatt_application_service_provider.h",
         "dbus/fake_bluetooth_gatt_characteristic_client.cc",
         "dbus/fake_bluetooth_gatt_characteristic_client.h",
         "dbus/fake_bluetooth_gatt_characteristic_service_provider.cc",
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index 4e39639e..659a90b0 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -192,18 +192,33 @@
                 'dbus/bluetooth_dbus_client_bundle.h',
                 'dbus/bluetooth_device_client.cc',
                 'dbus/bluetooth_device_client.h',
+                'dbus/bluetooth_gatt_application_service_provider.cc',
+                'dbus/bluetooth_gatt_application_service_provider.h',
+                'dbus/bluetooth_gatt_application_service_provider_impl.cc',
+                'dbus/bluetooth_gatt_application_service_provider_impl.h',
+                'dbus/bluetooth_gatt_attribute_value_delegate.h',
                 'dbus/bluetooth_gatt_characteristic_client.cc',
                 'dbus/bluetooth_gatt_characteristic_client.h',
+                'dbus/bluetooth_gatt_characteristic_delegate_wrapper.cc',
+                'dbus/bluetooth_gatt_characteristic_delegate_wrapper.h',
+                'dbus/bluetooth_gatt_characteristic_service_provider_impl.cc',
+                'dbus/bluetooth_gatt_characteristic_service_provider_impl.h',
                 'dbus/bluetooth_gatt_characteristic_service_provider.cc',
                 'dbus/bluetooth_gatt_characteristic_service_provider.h',
+                'dbus/bluetooth_gatt_descriptor_delegate_wrapper.cc',
+                'dbus/bluetooth_gatt_descriptor_delegate_wrapper.h',
                 'dbus/bluetooth_gatt_descriptor_client.cc',
                 'dbus/bluetooth_gatt_descriptor_client.h',
+                'dbus/bluetooth_gatt_descriptor_service_provider_impl.cc',
+                'dbus/bluetooth_gatt_descriptor_service_provider_impl.h',
                 'dbus/bluetooth_gatt_descriptor_service_provider.cc',
                 'dbus/bluetooth_gatt_descriptor_service_provider.h',
                 'dbus/bluetooth_gatt_manager_client.cc',
                 'dbus/bluetooth_gatt_manager_client.h',
                 'dbus/bluetooth_gatt_service_client.cc',
                 'dbus/bluetooth_gatt_service_client.h',
+                'dbus/bluetooth_gatt_service_service_provider_impl.cc',
+                'dbus/bluetooth_gatt_service_service_provider_impl.h',
                 'dbus/bluetooth_gatt_service_service_provider.cc',
                 'dbus/bluetooth_gatt_service_service_provider.h',
                 'dbus/bluetooth_input_client.cc',
@@ -233,6 +248,8 @@
                 'dbus/fake_bluetooth_agent_service_provider.h',
                 'dbus/fake_bluetooth_device_client.cc',
                 'dbus/fake_bluetooth_device_client.h',
+                'dbus/fake_bluetooth_gatt_application_service_provider.cc',
+                'dbus/fake_bluetooth_gatt_application_service_provider.h',
                 'dbus/fake_bluetooth_gatt_characteristic_client.cc',
                 'dbus/fake_bluetooth_gatt_characteristic_client.h',
                 'dbus/fake_bluetooth_gatt_characteristic_service_provider.cc',
diff --git a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.cc
new file mode 100644
index 0000000..30d7dcd
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.cc
@@ -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.
+
+#include "device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/memory/ptr_util.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+#include "device/bluetooth/bluez/bluetooth_gatt_service_bluez.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h"
+
+namespace bluez {
+
+BluetoothGattApplicationServiceProvider::
+    BluetoothGattApplicationServiceProvider() {}
+
+BluetoothGattApplicationServiceProvider::
+    ~BluetoothGattApplicationServiceProvider() {}
+
+// static
+void BluetoothGattApplicationServiceProvider::CreateAttributeServiceProviders(
+    dbus::Bus* bus,
+    const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>& services,
+    std::vector<std::unique_ptr<BluetoothGattServiceServiceProvider>>*
+        service_providers,
+    std::vector<std::unique_ptr<BluetoothGattCharacteristicServiceProvider>>*
+        characteristic_providers,
+    std::vector<std::unique_ptr<BluetoothGattDescriptorServiceProvider>>*
+        descriptor_providers) {
+  for (const auto& service : services) {
+    service_providers->push_back(
+        base::WrapUnique(BluetoothGattServiceServiceProvider::Create(
+            bus, service.second->object_path(),
+            service.second->GetUUID().value(),
+            std::vector<dbus::ObjectPath>())));
+    for (const auto& characteristic : service.second->GetCharacteristics()) {
+      characteristic_providers->push_back(
+          base::WrapUnique(BluetoothGattCharacteristicServiceProvider::Create(
+              bus, characteristic->object_path(),
+              base::WrapUnique(new BluetoothGattCharacteristicDelegateWrapper(
+                  service.second, characteristic.get())),
+              characteristic->GetUUID().value(), std::vector<std::string>(),
+              std::vector<std::string>(), service.second->object_path())));
+      for (const auto& descriptor : characteristic->GetDescriptors()) {
+        descriptor_providers->push_back(
+            base::WrapUnique(BluetoothGattDescriptorServiceProvider::Create(
+                bus, descriptor->object_path(),
+                base::WrapUnique(new BluetoothGattDescriptorDelegateWrapper(
+                    service.second, descriptor.get())),
+                descriptor->GetUUID().value(), std::vector<std::string>(),
+                characteristic->object_path())));
+      }
+    }
+  }
+}
+
+// static
+std::unique_ptr<BluetoothGattApplicationServiceProvider>
+BluetoothGattApplicationServiceProvider::Create(
+    dbus::Bus* bus,
+    const dbus::ObjectPath& object_path,
+    const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
+        services) {
+  if (!bluez::BluezDBusManager::Get()->IsUsingFakes()) {
+    return base::WrapUnique(new BluetoothGattApplicationServiceProviderImpl(
+        bus, object_path, services));
+  }
+  return base::WrapUnique(
+      new FakeBluetoothGattApplicationServiceProvider(object_path, services));
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h
new file mode 100644
index 0000000..3c0e1cef
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h
@@ -0,0 +1,65 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_H_
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "dbus/bus.h"
+#include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h"
+
+namespace bluez {
+
+class BluetoothLocalGattServiceBlueZ;
+
+// BluetoothGattApplicationServiceProvider is used to provide a D-Bus object
+// that the Bluetooth daemon can communicate with to register GATT service
+// hierarchies.
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattApplicationServiceProvider {
+ public:
+  virtual ~BluetoothGattApplicationServiceProvider();
+
+  // Creates individual service providers for all the attributes managed by the
+  // object manager interface implemented by this application service provider.
+  static void CreateAttributeServiceProviders(
+      dbus::Bus* bus,
+      const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
+          services,
+      std::vector<std::unique_ptr<BluetoothGattServiceServiceProvider>>*
+          service_providers,
+      std::vector<std::unique_ptr<BluetoothGattCharacteristicServiceProvider>>*
+          characteristic_providers,
+      std::vector<std::unique_ptr<BluetoothGattDescriptorServiceProvider>>*
+          descriptor_providers);
+
+  // Creates the instance where |bus| is the D-Bus bus connection to export the
+  // object onto, |object_path| is the object path that it should have, |uuid|
+  // is the 128-bit GATT service UUID, and |includes| are a list of object paths
+  // belonging to other exported GATT services that are included by the GATT
+  // service being created. Make sure that all included services have been
+  // exported before registering a GATT services with the GATT manager.
+  static std::unique_ptr<BluetoothGattApplicationServiceProvider> Create(
+      dbus::Bus* bus,
+      const dbus::ObjectPath& object_path,
+      const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
+          services);
+
+ protected:
+  BluetoothGattApplicationServiceProvider();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattApplicationServiceProvider);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_H_
diff --git a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.cc b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.cc
new file mode 100644
index 0000000..bfabe51
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.cc
@@ -0,0 +1,172 @@
+// 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 "device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace bluez {
+
+BluetoothGattApplicationServiceProviderImpl::
+    BluetoothGattApplicationServiceProviderImpl(
+        dbus::Bus* bus,
+        const dbus::ObjectPath& object_path,
+        const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
+            services)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      bus_(bus),
+      object_path_(object_path),
+      weak_ptr_factory_(this) {
+  VLOG(1) << "Creating Bluetooth GATT application: " << object_path_.value();
+  DCHECK(object_path_.IsValid());
+  DCHECK(bus_);
+
+  exported_object_ = bus_->GetExportedObject(object_path_);
+
+  exported_object_->ExportMethod(
+      dbus::kDBusObjectManagerInterface,
+      dbus::kDBusObjectManagerGetManagedObjects,
+      base::Bind(
+          &BluetoothGattApplicationServiceProviderImpl::GetManagedObjects,
+          weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattApplicationServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  BluetoothGattApplicationServiceProvider::CreateAttributeServiceProviders(
+      bus, services, &service_providers_, &characteristic_providers_,
+      &descriptor_providers_);
+}
+
+BluetoothGattApplicationServiceProviderImpl::
+    ~BluetoothGattApplicationServiceProviderImpl() {
+  VLOG(1) << "Cleaning up Bluetooth GATT service: " << object_path_.value();
+  if (bus_)
+    bus_->UnregisterExportedObject(object_path_);
+}
+
+BluetoothGattApplicationServiceProviderImpl::
+    BluetoothGattApplicationServiceProviderImpl(
+        const dbus::ObjectPath& object_path)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      bus_(nullptr),
+      object_path_(object_path),
+      weak_ptr_factory_(this) {
+  VLOG(1) << "Creating Fake Bluetooth GATT application service provider.";
+}
+
+bool BluetoothGattApplicationServiceProviderImpl::OnOriginThread() {
+  return base::PlatformThread::CurrentId() == origin_thread_id_;
+}
+
+template <typename AttributeProvider>
+void BluetoothGattApplicationServiceProviderImpl::WriteObjectStruct(
+    dbus::MessageWriter* writer,
+    const std::string& attribute_interface,
+    AttributeProvider* attribute_provider) {
+  // Open a struct entry for { object_path : interface_list }.
+  dbus::MessageWriter object_struct_writer(NULL);
+  // [ (oa(sa{sv}) ]
+  writer->OpenStruct(&object_struct_writer);
+
+  // Key: Object path. [ (o ]
+  object_struct_writer.AppendObjectPath(attribute_provider->object_path());
+
+  // Value: Open array for single entry interface_list. [ a(sa{sv}) ]
+  dbus::MessageWriter interface_array_writer(NULL);
+  object_struct_writer.OpenArray("(sa{sv})", &interface_array_writer);
+  WriteInterfaceStruct(&interface_array_writer, attribute_interface,
+                       attribute_provider);
+  object_struct_writer.CloseContainer(&interface_array_writer);
+
+  writer->CloseContainer(&object_struct_writer);
+}
+
+template <typename AttributeProvider>
+void BluetoothGattApplicationServiceProviderImpl::WriteInterfaceStruct(
+    dbus::MessageWriter* writer,
+    const std::string& attribute_interface,
+    AttributeProvider* attribute_provider) {
+  // Open a struct entry for { interface_name : properties_list }.
+  dbus::MessageWriter interface_struct_writer(NULL);
+  // [ (sa{sv}) ]
+  writer->OpenStruct(&interface_struct_writer);
+
+  // Key: Interface name. [ (s ]
+  interface_struct_writer.AppendString(attribute_interface);
+  // Value: Open a array for properties_list. [ a{sv}) ]
+  WriteAttributeProperties(&interface_struct_writer, attribute_provider);
+  writer->CloseContainer(&interface_struct_writer);
+}
+
+void BluetoothGattApplicationServiceProviderImpl::WriteAttributeProperties(
+    dbus::MessageWriter* writer,
+    BluetoothGattServiceServiceProvider* service_provider) {
+  service_provider->WriteProperties(writer);
+}
+
+void BluetoothGattApplicationServiceProviderImpl::WriteAttributeProperties(
+    dbus::MessageWriter* writer,
+    BluetoothGattCharacteristicServiceProvider* characteristic_provider) {
+  characteristic_provider->WriteProperties(writer, nullptr);
+}
+
+void BluetoothGattApplicationServiceProviderImpl::WriteAttributeProperties(
+    dbus::MessageWriter* writer,
+    BluetoothGattDescriptorServiceProvider* descriptor_provider) {
+  descriptor_provider->WriteProperties(writer, nullptr);
+}
+
+void BluetoothGattApplicationServiceProviderImpl::GetManagedObjects(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattApplicationServiceProvider::GetManagedObjects: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+
+  // The expected format by GetAll is [ a(oa(sa{sv})) ]
+  dbus::MessageWriter writer(response.get());
+  dbus::MessageWriter array_writer(nullptr);
+
+  writer.OpenArray("(oa(sa{sv}))", &array_writer);
+
+  for (const auto& service_provider : service_providers_) {
+    WriteObjectStruct(&array_writer,
+                      bluetooth_gatt_service::kBluetoothGattServiceInterface,
+                      service_provider.get());
+  }
+  for (const auto& characteristic_provider : characteristic_providers_) {
+    WriteObjectStruct(
+        &array_writer,
+        bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
+        characteristic_provider.get());
+  }
+  for (const auto& descriptor_provider : descriptor_providers_) {
+    WriteObjectStruct(
+        &array_writer,
+        bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface,
+        descriptor_provider.get());
+  }
+
+  writer.CloseContainer(&array_writer);
+
+  response_sender.Run(std::move(response));
+}
+
+// Called by dbus:: when a method is exported.
+void BluetoothGattApplicationServiceProviderImpl::OnExported(
+    const std::string& interface_name,
+    const std::string& method_name,
+    bool success) {
+  LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "."
+                            << method_name;
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h
new file mode 100644
index 0000000..ffa5f3c4
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h
@@ -0,0 +1,121 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_IMPL_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_IMPL_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/platform_thread.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+#include "dbus/message.h"
+#include "dbus/object_path.h"
+#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h"
+
+namespace bluez {
+
+class BluetoothLocalGattServiceBlueZ;
+
+// The BluetoothGattApplicationServiceProvider implementation used in
+// production.
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattApplicationServiceProviderImpl
+    : public BluetoothGattApplicationServiceProvider {
+ public:
+  BluetoothGattApplicationServiceProviderImpl(
+      dbus::Bus* bus,
+      const dbus::ObjectPath& object_path,
+      const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
+          services);
+  ~BluetoothGattApplicationServiceProviderImpl() override;
+
+  // For testing.
+  BluetoothGattApplicationServiceProviderImpl(
+      const dbus::ObjectPath& object_path);
+
+ private:
+  friend class BluetoothGattApplicationServiceProviderTest;
+  FRIEND_TEST_ALL_PREFIXES(BluetoothGattApplicationServiceProviderTest,
+                           GetManagedObjects);
+
+  // Returns true if the current thread is on the origin thread.
+  bool OnOriginThread();
+
+  template <typename Attribute>
+  void WriteObjectStruct(dbus::MessageWriter* writer,
+                         const std::string& attribute_interface,
+                         Attribute* attribute);
+  template <typename Attribute>
+  void WriteInterfaceStruct(dbus::MessageWriter* writer,
+                            const std::string& attribute_interface,
+                            Attribute* attribute);
+
+  void WriteAttributeProperties(
+      dbus::MessageWriter* writer,
+      BluetoothGattServiceServiceProvider* service_provider);
+  void WriteAttributeProperties(
+      dbus::MessageWriter* writer,
+      BluetoothGattCharacteristicServiceProvider* characteristic_provider);
+  void WriteAttributeProperties(
+      dbus::MessageWriter* writer,
+      BluetoothGattDescriptorServiceProvider* descriptor_provider);
+
+  // Called by dbus:: when the Bluetooth daemon wants to fetch all the objects
+  // managed by this object manager.
+  void GetManagedObjects(dbus::MethodCall* method_call,
+                         dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when a method is exported.
+  void OnExported(const std::string& interface_name,
+                  const std::string& method_name,
+                  bool success);
+
+  // Origin thread (i.e. the UI thread in production).
+  base::PlatformThreadId origin_thread_id_;
+
+  // List of GATT Service service providers managed by this object manager.
+  std::vector<std::unique_ptr<BluetoothGattServiceServiceProvider>>
+      service_providers_;
+  // List of GATT Characteristic service providers managed by this object
+  // manager.
+  std::vector<std::unique_ptr<BluetoothGattCharacteristicServiceProvider>>
+      characteristic_providers_;
+  // List of GATT Descriptor service providers managed by this object manager.
+  std::vector<std::unique_ptr<BluetoothGattDescriptorServiceProvider>>
+      descriptor_providers_;
+
+  // D-Bus bus object is exported on, not owned by this object and must
+  // outlive it.
+  dbus::Bus* bus_;
+
+  // D-Bus object path of object we are exporting, kept so we can unregister
+  // again in our destructor.
+  dbus::ObjectPath object_path_;
+
+  // D-Bus object we are exporting, owned by this object.
+  scoped_refptr<dbus::ExportedObject> exported_object_;
+
+  // Weak pointer factory for generating 'this' pointers that might live longer
+  // than we do.
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<BluetoothGattApplicationServiceProviderImpl>
+      weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattApplicationServiceProviderImpl);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_IMPL_H_
diff --git a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_unittest.cc b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_unittest.cc
new file mode 100644
index 0000000..2ed954e
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_unittest.cc
@@ -0,0 +1,310 @@
+// 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/bind.h>
+#include <base/memory/ptr_util.h>
+#include <dbus/bus.h>
+#include <dbus/message.h>
+#include <dbus/object_path.h>
+#include <device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h>
+#include <device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h>
+#include <device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h>
+#include <device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h>
+#include <gtest/gtest.h>
+#include <gtest/internal/gtest-internal.h>
+#include <string>
+#include "device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h"
+
+namespace bluez {
+
+namespace {
+
+const char kAppObjectPath[] = "/fake/hci0/gatt_application";
+const char kFakeServiceUuid[] = "00000000-0000-0000-0000-010040008000";
+const char kFakeCharacteristicUuid[] = "00000000-0000-0000-0000-010040908000";
+const char kFakeDescriptorUuid[] = "00000000-0000-0000-0000-018390008000";
+
+// This is really ugly, but it really is the best way to verify our message
+// was constructed correctly. This string was generated from the test data
+// and then manually verified to match the expected signature.
+const char kExpectedMessage[] =
+    "message_type: MESSAGE_METHOD_RETURN\n"
+    "signature: a(oa(sa{sv}))\n"
+    "reply_serial: 123\n"
+    "\n"
+    "array [\n"
+    "  struct {\n"
+    "    object_path \"/fake/hci0/gatt_application/service0\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattService1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-010040008000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Includes\"\n"
+    "            variant               array [\n"
+    "              ]\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path \"/fake/hci0/gatt_application/service1\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattService1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-010040008000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Includes\"\n"
+    "            variant               array [\n"
+    "              ]\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path \"/fake/hci0/gatt_application/service0/characteristic0\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattCharacteristic1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-010040908000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Service\"\n"
+    "            variant               object_path "
+    "\"/fake/hci0/gatt_application/service0\"\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path \"/fake/hci0/gatt_application/service0/characteristic1\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattCharacteristic1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-010040908000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Service\"\n"
+    "            variant               object_path "
+    "\"/fake/hci0/gatt_application/service0\"\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path \"/fake/hci0/gatt_application/service1/characteristic0\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattCharacteristic1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-010040908000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Service\"\n"
+    "            variant               object_path "
+    "\"/fake/hci0/gatt_application/service1\"\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path "
+    "\"/fake/hci0/gatt_application/service0/characteristic0/descriptor0\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattDescriptor1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-018390008000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Characteristic\"\n"
+    "            variant               object_path "
+    "\"/fake/hci0/gatt_application/service0/characteristic0\"\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path "
+    "\"/fake/hci0/gatt_application/service0/characteristic1/descriptor1\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattDescriptor1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-018390008000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Characteristic\"\n"
+    "            variant               object_path "
+    "\"/fake/hci0/gatt_application/service0/characteristic1\"\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path "
+    "\"/fake/hci0/gatt_application/service1/characteristic0/descriptor2\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattDescriptor1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-018390008000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Characteristic\"\n"
+    "            variant               object_path "
+    "\"/fake/hci0/gatt_application/service1/characteristic0\"\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "  struct {\n"
+    "    object_path "
+    "\"/fake/hci0/gatt_application/service0/characteristic0/descriptor3\"\n"
+    "    array [\n"
+    "      struct {\n"
+    "        string \"org.bluez.GattDescriptor1\"\n"
+    "        array [\n"
+    "          dict entry {\n"
+    "            string \"UUID\"\n"
+    "            variant               string "
+    "\"00000000-0000-0000-0000-018390008000\"\n"
+    "          }\n"
+    "          dict entry {\n"
+    "            string \"Characteristic\"\n"
+    "            variant               object_path "
+    "\"/fake/hci0/gatt_application/service0/characteristic0\"\n"
+    "          }\n"
+    "        ]\n"
+    "      }\n"
+    "    ]\n"
+    "  }\n"
+    "]\n";
+
+void ResponseSenderCallback(const std::string& expected_message,
+                            std::unique_ptr<dbus::Response> response) {
+  EXPECT_EQ(expected_message, response->ToString());
+}
+
+}  // namespace
+
+class BluetoothGattApplicationServiceProviderTest : public testing::Test {
+ public:
+  std::string CreateFakeService(
+      dbus::Bus* bus,
+      BluetoothGattApplicationServiceProviderImpl* app_provider,
+      const std::string& service_path) {
+    const std::string& full_service_path =
+        std::string(kAppObjectPath) + "/" + service_path;
+    app_provider->service_providers_.push_back(
+        base::WrapUnique(new BluetoothGattServiceServiceProviderImpl(
+            dbus::ObjectPath(full_service_path), kFakeServiceUuid)));
+    return full_service_path;
+  }
+
+  std::string CreateFakeCharacteristic(
+      dbus::Bus* bus,
+      BluetoothGattApplicationServiceProviderImpl* app_provider,
+      const std::string& characteristic_path,
+      const std::string& service_path) {
+    const std::string& full_characteristic_path =
+        service_path + "/" + characteristic_path;
+    app_provider->characteristic_providers_.push_back(
+        base::WrapUnique(new BluetoothGattCharacteristicServiceProviderImpl(
+            dbus::ObjectPath(full_characteristic_path), kFakeCharacteristicUuid,
+            dbus::ObjectPath(service_path))));
+    return full_characteristic_path;
+  }
+
+  void CreateFakeDescriptor(
+      dbus::Bus* bus,
+      BluetoothGattApplicationServiceProviderImpl* app_provider,
+      const std::string& descriptor_path,
+      const std::string& characteristic_path) {
+    const std::string& full_descriptor_path =
+        characteristic_path + "/" + descriptor_path;
+    app_provider->descriptor_providers_.push_back(
+        base::WrapUnique(new BluetoothGattDescriptorServiceProviderImpl(
+            dbus::ObjectPath(full_descriptor_path), kFakeDescriptorUuid,
+            dbus::ObjectPath(characteristic_path))));
+  }
+
+  void CreateFakeAttributes(
+      dbus::Bus* bus,
+      BluetoothGattApplicationServiceProviderImpl* app_provider) {
+    const std::string& kServicePath1 =
+        CreateFakeService(bus, app_provider, "service0");
+    const std::string& kServicePath2 =
+        CreateFakeService(bus, app_provider, "service1");
+
+    const std::string& kCharacteristicPath1 = CreateFakeCharacteristic(
+        bus, app_provider, "characteristic0", kServicePath1);
+    const std::string& kCharacteristicPath2 = CreateFakeCharacteristic(
+        bus, app_provider, "characteristic1", kServicePath1);
+    const std::string& kCharacteristicPath3 = CreateFakeCharacteristic(
+        bus, app_provider, "characteristic0", kServicePath2);
+
+    CreateFakeDescriptor(bus, app_provider, "descriptor0",
+                         kCharacteristicPath1);
+    CreateFakeDescriptor(bus, app_provider, "descriptor1",
+                         kCharacteristicPath2);
+    CreateFakeDescriptor(bus, app_provider, "descriptor2",
+                         kCharacteristicPath3);
+    CreateFakeDescriptor(bus, app_provider, "descriptor3",
+                         kCharacteristicPath1);
+  }
+};
+
+TEST_F(BluetoothGattApplicationServiceProviderTest, GetManagedObjects) {
+  std::unique_ptr<BluetoothGattApplicationServiceProviderImpl> app_provider =
+      base::WrapUnique(new BluetoothGattApplicationServiceProviderImpl(
+          dbus::ObjectPath(kAppObjectPath)));
+  CreateFakeAttributes(nullptr, app_provider.get());
+
+  dbus::MethodCall method_call("com.example.Interface", "SomeMethod");
+  // Not setting the serial causes a crash.
+  method_call.SetSerial(123);
+  app_provider->GetManagedObjects(
+      &method_call, base::Bind(&ResponseSenderCallback, kExpectedMessage));
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h b/device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h
new file mode 100644
index 0000000..f44847a
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h
@@ -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.
+
+#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_ATTRIBUTE_VALUE_DELEGATE_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_ATTRIBUTE_VALUE_DELEGATE_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "device/bluetooth/bluetooth_local_gatt_service.h"
+
+namespace bluez {
+
+// A simpler interface for reacting to GATT attribute value requests by the
+// DBus attribute service providers.
+class BluetoothGattAttributeValueDelegate {
+ public:
+  virtual ~BluetoothGattAttributeValueDelegate() {}
+
+  // This method will be called when a remote device requests to read the
+  // value of the exported GATT attribute. Invoke |callback| with a value
+  // to return that value to the requester. Invoke |error_callback| to report
+  // a failure to read the value. This can happen, for example, if the
+  // attribute has no read permission set. Either callback should be
+  // invoked after a reasonable amount of time, since the request will time
+  // out if left pending for too long causing a disconnection.
+  virtual void GetValue(
+      const device::BluetoothLocalGattService::Delegate::ValueCallback&
+          callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback) = 0;
+
+  // This method will be called, when a remote device requests to write the
+  // value of the exported GATT attribute. Invoke |callback| to report
+  // that the value was successfully written. Invoke |error_callback| to
+  // report a failure to write the value. This can happen, for example, if the
+  // attribute has no write permission set. Either callback should be
+  // invoked after a reasonable amount of time, since the request will time
+  // out if left pending for too long causing a disconnection.
+  virtual void SetValue(
+      const std::vector<uint8_t>& value,
+      const base::Closure& callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback) = 0;
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_ATTRIBUTE_VALUE_DELEGATE_H_
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.cc
new file mode 100644
index 0000000..f8f6669
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.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 "device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.h"
+
+#include "device/bluetooth/bluez/bluetooth_local_gatt_characteristic_bluez.h"
+
+namespace bluez {
+
+BluetoothGattCharacteristicDelegateWrapper::
+    BluetoothGattCharacteristicDelegateWrapper(
+        BluetoothLocalGattServiceBlueZ* service,
+        BluetoothLocalGattCharacteristicBlueZ* characteristic)
+    : service_(service), characteristic_(characteristic) {}
+
+void BluetoothGattCharacteristicDelegateWrapper::GetValue(
+    const device::BluetoothLocalGattService::Delegate::ValueCallback& callback,
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
+  service_->GetDelegate()->OnCharacteristicReadRequest(
+      service_, characteristic_, 0, callback, error_callback);
+}
+
+void BluetoothGattCharacteristicDelegateWrapper::SetValue(
+    const std::vector<uint8_t>& value,
+    const base::Closure& callback,
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
+  service_->GetDelegate()->OnCharacteristicWriteRequest(
+      service_, characteristic_, value, 0, callback, error_callback);
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.h
new file mode 100644
index 0000000..17a5568
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_delegate_wrapper.h
@@ -0,0 +1,50 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_DELEGATE_WRAPPER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_DELEGATE_WRAPPER_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "device/bluetooth/bluetooth_local_gatt_service.h"
+#include "device/bluetooth/bluez/bluetooth_gatt_service_bluez.h"
+#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h"
+
+namespace bluez {
+
+class BluetoothLocalGattCharacteristicBlueZ;
+
+// Wrapper class around AttributeValueDelegate to handle characteristics.
+class BluetoothGattCharacteristicDelegateWrapper
+    : public BluetoothGattAttributeValueDelegate {
+ public:
+  BluetoothGattCharacteristicDelegateWrapper(
+      BluetoothLocalGattServiceBlueZ* service,
+      BluetoothLocalGattCharacteristicBlueZ* characteristic);
+
+  void GetValue(
+      const device::BluetoothLocalGattService::Delegate::ValueCallback&
+          callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback) override;
+  void SetValue(
+      const std::vector<uint8_t>& value,
+      const base::Closure& callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback) override;
+
+ private:
+  BluetoothLocalGattServiceBlueZ* service_;
+  BluetoothLocalGattCharacteristicBlueZ* characteristic_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicDelegateWrapper);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_DELEGATE_WRAPPER_H_
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc
index e69a52e..58d34db 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc
@@ -4,444 +4,11 @@
 
 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
 
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/strings/string_util.h"
-#include "base/threading/platform_thread.h"
-#include "dbus/exported_object.h"
-#include "dbus/message.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace bluez {
-namespace {
-const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
-const char kErrorPropertyReadOnly[] =
-    "org.freedesktop.DBus.Error.PropertyReadOnly";
-const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed";
-}  // namespace
-
-// The BluetoothGattCharacteristicServiceProvider implementation used in
-// production.
-class BluetoothGattCharacteristicServiceProviderImpl
-    : public BluetoothGattCharacteristicServiceProvider {
- public:
-  BluetoothGattCharacteristicServiceProviderImpl(
-      dbus::Bus* bus,
-      const dbus::ObjectPath& object_path,
-      Delegate* delegate,
-      const std::string& uuid,
-      const std::vector<std::string>& flags,
-      const std::vector<std::string>& permissions,
-      const dbus::ObjectPath& service_path)
-      : origin_thread_id_(base::PlatformThread::CurrentId()),
-        uuid_(uuid),
-        bus_(bus),
-        delegate_(delegate),
-        object_path_(object_path),
-        service_path_(service_path),
-        weak_ptr_factory_(this) {
-    VLOG(1) << "Created Bluetooth GATT characteristic: " << object_path.value()
-            << " UUID: " << uuid;
-    DCHECK(bus_);
-    DCHECK(delegate_);
-    DCHECK(!uuid_.empty());
-    DCHECK(object_path_.IsValid());
-    DCHECK(service_path_.IsValid());
-    DCHECK(base::StartsWith(object_path_.value(), service_path_.value() + "/",
-                            base::CompareCase::SENSITIVE));
-
-    exported_object_ = bus_->GetExportedObject(object_path_);
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet,
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::Get,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet,
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::Set,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll,
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::GetAll,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  ~BluetoothGattCharacteristicServiceProviderImpl() override {
-    VLOG(1) << "Cleaning up Bluetooth GATT characteristic: "
-            << object_path_.value();
-    bus_->UnregisterExportedObject(object_path_);
-  }
-
-  // BluetoothGattCharacteristicServiceProvider override.
-  void SendValueChanged(const std::vector<uint8_t>& value) override {
-    VLOG(2) << "Emitting a PropertiesChanged signal for characteristic value.";
-    dbus::Signal signal(dbus::kDBusPropertiesInterface,
-                        dbus::kDBusPropertiesChangedSignal);
-    dbus::MessageWriter writer(&signal);
-    dbus::MessageWriter array_writer(NULL);
-    dbus::MessageWriter dict_entry_writer(NULL);
-    dbus::MessageWriter variant_writer(NULL);
-
-    // interface_name
-    writer.AppendString(
-        bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
-
-    // changed_properties
-    writer.OpenArray("{sv}", &array_writer);
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(
-        bluetooth_gatt_characteristic::kValueProperty);
-    dict_entry_writer.OpenVariant("ay", &variant_writer);
-    variant_writer.AppendArrayOfBytes(value.data(), value.size());
-    dict_entry_writer.CloseContainer(&variant_writer);
-    array_writer.CloseContainer(&dict_entry_writer);
-    writer.CloseContainer(&array_writer);
-
-    // invalidated_properties.
-    writer.OpenArray("s", &array_writer);
-    writer.CloseContainer(&array_writer);
-
-    exported_object_->SendSignal(&signal);
-  }
-
- private:
-  // Returns true if the current thread is on the origin thread.
-  bool OnOriginThread() {
-    return base::PlatformThread::CurrentId() == origin_thread_id_;
-  }
-
-  // Called by dbus:: when the Bluetooth daemon fetches a single property of
-  // the characteristic.
-  void Get(dbus::MethodCall* method_call,
-           dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Get: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    std::string property_name;
-    if (!reader.PopString(&interface_name) ||
-        !reader.PopString(&property_name) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 'ss'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT characteristic interface is supported.
-    if (interface_name !=
-        bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // If getting the "Value" property, obtain the value from the delegate.
-    if (property_name == bluetooth_gatt_characteristic::kValueProperty) {
-      DCHECK(delegate_);
-      delegate_->GetCharacteristicValue(
-          base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGet,
-                     weak_ptr_factory_.GetWeakPtr(), method_call,
-                     response_sender),
-          base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure,
-                     weak_ptr_factory_.GetWeakPtr(), method_call,
-                     response_sender));
-      return;
-    }
-
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter variant_writer(NULL);
-
-    // TODO(armansito): Process the "Flags" and "Permissions" properties below.
-    if (property_name == bluetooth_gatt_characteristic::kUUIDProperty) {
-      writer.OpenVariant("s", &variant_writer);
-      variant_writer.AppendString(uuid_);
-      writer.CloseContainer(&variant_writer);
-    } else if (property_name ==
-               bluetooth_gatt_characteristic::kServiceProperty) {
-      writer.OpenVariant("o", &variant_writer);
-      variant_writer.AppendObjectPath(service_path_);
-      writer.CloseContainer(&variant_writer);
-    } else {
-      response = dbus::ErrorResponse::FromMethodCall(
-          method_call, kErrorInvalidArgs,
-          "No such property: '" + property_name + "'.");
-    }
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by dbus:: when the Bluetooth daemon sets a single property of the
-  // characteristic.
-  void Set(dbus::MethodCall* method_call,
-           dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Set: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    std::string property_name;
-    dbus::MessageReader variant_reader(NULL);
-    if (!reader.PopString(&interface_name) ||
-        !reader.PopString(&property_name) ||
-        !reader.PopVariant(&variant_reader) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 'ssv'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT characteristic interface is allowed.
-    if (interface_name !=
-        bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the "Value" property is writeable.
-    if (property_name != bluetooth_gatt_characteristic::kValueProperty) {
-      std::string error_name;
-      std::string error_message;
-      if (property_name == bluetooth_gatt_characteristic::kUUIDProperty ||
-          property_name == bluetooth_gatt_characteristic::kServiceProperty) {
-        error_name = kErrorPropertyReadOnly;
-        error_message = "Read-only property: '" + property_name + "'.";
-      } else {
-        error_name = kErrorInvalidArgs;
-        error_message = "No such property: '" + property_name + "'.";
-      }
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, error_name,
-                                              error_message);
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Obtain the value.
-    const uint8_t* bytes = NULL;
-    size_t length = 0;
-    if (!variant_reader.PopArrayOfBytes(&bytes, &length)) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "Property '" + property_name + "' has type 'ay'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Pass the set request onto the delegate.
-    std::vector<uint8_t> value(bytes, bytes + length);
-    DCHECK(delegate_);
-    delegate_->SetCharacteristicValue(
-        value,
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnSet,
-                   weak_ptr_factory_.GetWeakPtr(), method_call,
-                   response_sender),
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure,
-                   weak_ptr_factory_.GetWeakPtr(), method_call,
-                   response_sender));
-  }
-
-  // Called by dbus:: when the Bluetooth daemon fetches all properties of the
-  // characteristic.
-  void GetAll(dbus::MethodCall* method_call,
-              dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattCharacteristicServiceProvider::GetAll: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    if (!reader.PopString(&interface_name) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 's'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT characteristic interface is supported.
-    if (interface_name !=
-        bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Try to obtain the value from the delegate. We will construct the
-    // response in the success callback.
-    DCHECK(delegate_);
-    delegate_->GetCharacteristicValue(
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGetAll,
-                   weak_ptr_factory_.GetWeakPtr(), method_call,
-                   response_sender),
-        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure,
-                   weak_ptr_factory_.GetWeakPtr(), method_call,
-                   response_sender));
-  }
-
-  // Called by dbus:: when a method is exported.
-  void OnExported(const std::string& interface_name,
-                  const std::string& method_name,
-                  bool success) {
-    LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "."
-                              << method_name;
-  }
-
-  // Called by the Delegate in response to a method to call to get all
-  // properties, in which the delegate has successfully returned the
-  // characteristic value.
-  void OnGetAll(dbus::MethodCall* method_call,
-                dbus::ExportedObject::ResponseSender response_sender,
-                const std::vector<uint8_t>& value) {
-    VLOG(2) << "Characteristic value obtained from delegate. Responding to "
-            << "GetAll.";
-
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter array_writer(NULL);
-    dbus::MessageWriter dict_entry_writer(NULL);
-    dbus::MessageWriter variant_writer(NULL);
-
-    writer.OpenArray("{sv}", &array_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(
-        bluetooth_gatt_characteristic::kUUIDProperty);
-    dict_entry_writer.AppendVariantOfString(uuid_);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(
-        bluetooth_gatt_characteristic::kServiceProperty);
-    dict_entry_writer.AppendVariantOfObjectPath(service_path_);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(
-        bluetooth_gatt_characteristic::kValueProperty);
-    dict_entry_writer.OpenVariant("ay", &variant_writer);
-    variant_writer.AppendArrayOfBytes(value.data(), value.size());
-    dict_entry_writer.CloseContainer(&variant_writer);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    // TODO(armansito): Process Flags & Permissions properties.
-
-    writer.CloseContainer(&array_writer);
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by the Delegate in response to a successful method call to get the
-  // characteristic value.
-  void OnGet(dbus::MethodCall* method_call,
-             dbus::ExportedObject::ResponseSender response_sender,
-             const std::vector<uint8_t>& value) {
-    VLOG(2) << "Returning characteristic value obtained from delegate.";
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter variant_writer(NULL);
-
-    writer.OpenVariant("ay", &variant_writer);
-    variant_writer.AppendArrayOfBytes(value.data(), value.size());
-    writer.CloseContainer(&variant_writer);
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by the Delegate in response to a successful method call to set the
-  // characteristic value.
-  void OnSet(dbus::MethodCall* method_call,
-             dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "Successfully set characteristic value. Return success.";
-    response_sender.Run(dbus::Response::FromMethodCall(method_call));
-  }
-
-  // Called by the Delegate in response to a failed method call to get or set
-  // the characteristic value.
-  void OnFailure(dbus::MethodCall* method_call,
-                 dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "Failed to get/set characteristic value. Report error.";
-    std::unique_ptr<dbus::ErrorResponse> error_response =
-        dbus::ErrorResponse::FromMethodCall(
-            method_call, kErrorFailed,
-            "Failed to get/set characteristic value.");
-    response_sender.Run(std::move(error_response));
-  }
-
-  // Origin thread (i.e. the UI thread in production).
-  base::PlatformThreadId origin_thread_id_;
-
-  // 128-bit characteristic UUID of this object.
-  std::string uuid_;
-
-  // D-Bus bus object is exported on, not owned by this object and must
-  // outlive it.
-  dbus::Bus* bus_;
-
-  // Incoming methods to get and set the "Value" property are passed on to the
-  // delegate and callbacks passed to generate a reply. |delegate_| is generally
-  // the object that owns this one and must outlive it.
-  Delegate* delegate_;
-
-  // D-Bus object path of object we are exporting, kept so we can unregister
-  // again in our destructor.
-  dbus::ObjectPath object_path_;
-
-  // Object path of the GATT service that the exported characteristic belongs
-  // to.
-  dbus::ObjectPath service_path_;
-
-  // D-Bus object we are exporting, owned by this object.
-  scoped_refptr<dbus::ExportedObject> exported_object_;
-
-  // Weak pointer factory for generating 'this' pointers that might live longer
-  // than we do.
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothGattCharacteristicServiceProviderImpl>
-      weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicServiceProviderImpl);
-};
 
 BluetoothGattCharacteristicServiceProvider::
     BluetoothGattCharacteristicServiceProvider() {}
@@ -454,17 +21,18 @@
 BluetoothGattCharacteristicServiceProvider::Create(
     dbus::Bus* bus,
     const dbus::ObjectPath& object_path,
-    Delegate* delegate,
+    std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
     const std::string& uuid,
     const std::vector<std::string>& flags,
     const std::vector<std::string>& permissions,
     const dbus::ObjectPath& service_path) {
   if (!bluez::BluezDBusManager::Get()->IsUsingFakes()) {
     return new BluetoothGattCharacteristicServiceProviderImpl(
-        bus, object_path, delegate, uuid, flags, permissions, service_path);
+        bus, object_path, std::move(delegate), uuid, flags, permissions,
+        service_path);
   }
   return new FakeBluetoothGattCharacteristicServiceProvider(
-      object_path, delegate, uuid, flags, permissions, service_path);
+      object_path, std::move(delegate), uuid, flags, permissions, service_path);
 }
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
index 2d372390..80a2b7d9 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
@@ -6,15 +6,15 @@
 #define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
 
 #include <stdint.h>
-
 #include <string>
 #include <vector>
 
-#include "base/callback.h"
 #include "base/macros.h"
 #include "dbus/bus.h"
+#include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h"
 
 namespace bluez {
 
@@ -34,52 +34,20 @@
 // "Value" property.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicServiceProvider {
  public:
-  // Interface for reacting to GATT characteristic value requests.
-  class Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // ValueCallback is used for methods that require a characteristic value
-    // to be returned.
-    typedef base::Callback<void(const std::vector<uint8_t>&)> ValueCallback;
-
-    // ErrorCallback is used by methods to report failure.
-    typedef base::Closure ErrorCallback;
-
-    // This method will be called when a remote device requests to read the
-    // value of the exported GATT characteristic. Invoke |callback| with a value
-    // to return that value to the requester. Invoke |error_callback| to report
-    // a failure to read the value. This can happen, for example, if the
-    // characteristic has no read permission set. Either callback should be
-    // invoked after a reasonable amount of time, since the request will time
-    // out if left pending for too long.
-    virtual void GetCharacteristicValue(
-        const ValueCallback& callback,
-        const ErrorCallback& error_callback) = 0;
-
-    // This method will be called, when a remote device requests to write the
-    // value of the exported GATT characteristic. Invoke |callback| to report
-    // that the value was successfully written. Invoke |error_callback| to
-    // report a failure to write the value. This can happen, for example, if the
-    // characteristic has no write permission set. Either callback should be
-    // invoked after a reasonable amount of time, since the request will time
-    // out if left pending for too long.
-    //
-    // The delegate should use this method to perform any side-effects that may
-    // occur based on the set value and potentially send a property changed
-    // signal to notify the Bluetooth daemon that the value has changed.
-    virtual void SetCharacteristicValue(
-        const std::vector<uint8_t>& value,
-        const base::Closure& callback,
-        const ErrorCallback& error_callback) = 0;
-  };
-
   virtual ~BluetoothGattCharacteristicServiceProvider();
 
   // Send a PropertyChanged signal to notify the Bluetooth daemon that the value
   // of the "Value" property has changed to |value|.
   virtual void SendValueChanged(const std::vector<uint8_t>& value) = 0;
 
+  // Writes the characteristics's properties into the provided writer. If
+  // value is not null, it is written also, otherwise no value property is
+  // written.
+  virtual void WriteProperties(dbus::MessageWriter* writer,
+                               const std::vector<uint8_t>* value) {}
+
+  virtual const dbus::ObjectPath& object_path() const = 0;
+
   // Creates the instance, where |bus| is the D-Bus bus connection to export
   // the object onto, |uuid| is the 128-bit GATT characteristic UUID,
   // |flags| is the list of GATT characteristic properties, |permissions| is the
@@ -97,7 +65,7 @@
   static BluetoothGattCharacteristicServiceProvider* Create(
       dbus::Bus* bus,
       const dbus::ObjectPath& object_path,
-      Delegate* delegate,
+      std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
       const std::string& uuid,
       const std::vector<std::string>& flags,
       const std::vector<std::string>& permissions,
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.cc
new file mode 100644
index 0000000..c315ea1f
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.cc
@@ -0,0 +1,408 @@
+// 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 "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h"
+
+#include <stddef.h>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace bluez {
+
+namespace {
+
+const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
+const char kErrorPropertyReadOnly[] =
+    "org.freedesktop.DBus.Error.PropertyReadOnly";
+const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed";
+
+}  // namespace
+
+BluetoothGattCharacteristicServiceProviderImpl::
+    BluetoothGattCharacteristicServiceProviderImpl(
+        dbus::Bus* bus,
+        const dbus::ObjectPath& object_path,
+        std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
+        const std::string& uuid,
+        const std::vector<std::string>& flags,
+        const std::vector<std::string>& permissions,
+        const dbus::ObjectPath& service_path)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      uuid_(uuid),
+      bus_(bus),
+      delegate_(std::move(delegate)),
+      object_path_(object_path),
+      service_path_(service_path),
+      weak_ptr_factory_(this) {
+  VLOG(1) << "Created Bluetooth GATT characteristic: " << object_path.value()
+          << " UUID: " << uuid;
+  DCHECK(bus_);
+  DCHECK(delegate_);
+  DCHECK(!uuid_.empty());
+  DCHECK(object_path_.IsValid());
+  DCHECK(service_path_.IsValid());
+  DCHECK(base::StartsWith(object_path_.value(), service_path_.value() + "/",
+                          base::CompareCase::SENSITIVE));
+
+  exported_object_ = bus_->GetExportedObject(object_path_);
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet,
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::Get,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet,
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::Set,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll,
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::GetAll,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+BluetoothGattCharacteristicServiceProviderImpl::
+    ~BluetoothGattCharacteristicServiceProviderImpl() {
+  VLOG(1) << "Cleaning up Bluetooth GATT characteristic: "
+          << object_path_.value();
+  if (bus_)
+    bus_->UnregisterExportedObject(object_path_);
+}
+
+BluetoothGattCharacteristicServiceProviderImpl::
+    BluetoothGattCharacteristicServiceProviderImpl(
+        const dbus::ObjectPath& object_path,
+        const std::string& uuid,
+        const dbus::ObjectPath& service_path)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      uuid_(uuid),
+      bus_(nullptr),
+      delegate_(nullptr),
+      object_path_(object_path),
+      service_path_(service_path),
+      weak_ptr_factory_(this) {}
+
+void BluetoothGattCharacteristicServiceProviderImpl::SendValueChanged(
+    const std::vector<uint8_t>& value) {
+  VLOG(2) << "Emitting a PropertiesChanged signal for characteristic value.";
+  dbus::Signal signal(dbus::kDBusPropertiesInterface,
+                      dbus::kDBusPropertiesChangedSignal);
+  dbus::MessageWriter writer(&signal);
+  dbus::MessageWriter array_writer(NULL);
+  dbus::MessageWriter dict_entry_writer(NULL);
+  dbus::MessageWriter variant_writer(NULL);
+
+  // interface_name
+  writer.AppendString(
+      bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
+
+  // changed_properties
+  writer.OpenArray("{sv}", &array_writer);
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(bluetooth_gatt_characteristic::kValueProperty);
+  dict_entry_writer.OpenVariant("ay", &variant_writer);
+  variant_writer.AppendArrayOfBytes(value.data(), value.size());
+  dict_entry_writer.CloseContainer(&variant_writer);
+  array_writer.CloseContainer(&dict_entry_writer);
+  writer.CloseContainer(&array_writer);
+
+  // invalidated_properties.
+  writer.OpenArray("s", &array_writer);
+  writer.CloseContainer(&array_writer);
+
+  exported_object_->SendSignal(&signal);
+}
+
+// Returns true if the current thread is on the origin thread.
+bool BluetoothGattCharacteristicServiceProviderImpl::OnOriginThread() {
+  return base::PlatformThread::CurrentId() == origin_thread_id_;
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::Get(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Get: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  std::string property_name;
+  if (!reader.PopString(&interface_name) || !reader.PopString(&property_name) ||
+      reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 'ss'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT characteristic interface is supported.
+  if (interface_name !=
+      bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // If getting the "Value" property, obtain the value from the delegate.
+  if (property_name == bluetooth_gatt_characteristic::kValueProperty) {
+    DCHECK(delegate_);
+    delegate_->GetValue(
+        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGet,
+                   weak_ptr_factory_.GetWeakPtr(), method_call,
+                   response_sender),
+        base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure,
+                   weak_ptr_factory_.GetWeakPtr(), method_call,
+                   response_sender));
+    return;
+  }
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  dbus::MessageWriter variant_writer(NULL);
+
+  // TODO(armansito): Process the "Flags" and "Permissions" properties below.
+  if (property_name == bluetooth_gatt_characteristic::kUUIDProperty) {
+    writer.OpenVariant("s", &variant_writer);
+    variant_writer.AppendString(uuid_);
+    writer.CloseContainer(&variant_writer);
+  } else if (property_name == bluetooth_gatt_characteristic::kServiceProperty) {
+    writer.OpenVariant("o", &variant_writer);
+    variant_writer.AppendObjectPath(service_path_);
+    writer.CloseContainer(&variant_writer);
+  } else {
+    response = dbus::ErrorResponse::FromMethodCall(
+        method_call, kErrorInvalidArgs,
+        "No such property: '" + property_name + "'.");
+  }
+
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::Set(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Set: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  std::string property_name;
+  dbus::MessageReader variant_reader(NULL);
+  if (!reader.PopString(&interface_name) || !reader.PopString(&property_name) ||
+      !reader.PopVariant(&variant_reader) || reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 'ssv'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT characteristic interface is allowed.
+  if (interface_name !=
+      bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the "Value" property is writeable.
+  if (property_name != bluetooth_gatt_characteristic::kValueProperty) {
+    std::string error_name;
+    std::string error_message;
+    if (property_name == bluetooth_gatt_characteristic::kUUIDProperty ||
+        property_name == bluetooth_gatt_characteristic::kServiceProperty) {
+      error_name = kErrorPropertyReadOnly;
+      error_message = "Read-only property: '" + property_name + "'.";
+    } else {
+      error_name = kErrorInvalidArgs;
+      error_message = "No such property: '" + property_name + "'.";
+    }
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, error_name,
+                                            error_message);
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Obtain the value.
+  const uint8_t* bytes = NULL;
+  size_t length = 0;
+  if (!variant_reader.PopArrayOfBytes(&bytes, &length)) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "Property '" + property_name + "' has type 'ay'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Pass the set request onto the delegate.
+  std::vector<uint8_t> value(bytes, bytes + length);
+  DCHECK(delegate_);
+  delegate_->SetValue(
+      value,
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnSet,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender),
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender));
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::GetAll(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattCharacteristicServiceProvider::GetAll: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  if (!reader.PopString(&interface_name) || reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 's'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT characteristic interface is supported.
+  if (interface_name !=
+      bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Try to obtain the value from the delegate. We will construct the
+  // response in the success callback.
+  DCHECK(delegate_);
+  delegate_->GetValue(
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGetAll,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender),
+      base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender));
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::OnExported(
+    const std::string& interface_name,
+    const std::string& method_name,
+    bool success) {
+  LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "."
+                            << method_name;
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::OnGetAll(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender,
+    const std::vector<uint8_t>& value) {
+  VLOG(2) << "Characteristic value obtained from delegate. Responding to "
+          << "GetAll.";
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  WriteProperties(&writer, &value);
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::WriteProperties(
+    dbus::MessageWriter* writer,
+    const std::vector<uint8_t>* value) {
+  dbus::MessageWriter array_writer(NULL);
+  dbus::MessageWriter dict_entry_writer(NULL);
+  dbus::MessageWriter variant_writer(NULL);
+
+  writer->OpenArray("{sv}", &array_writer);
+
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(bluetooth_gatt_characteristic::kUUIDProperty);
+  dict_entry_writer.AppendVariantOfString(uuid_);
+  array_writer.CloseContainer(&dict_entry_writer);
+
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(
+      bluetooth_gatt_characteristic::kServiceProperty);
+  dict_entry_writer.AppendVariantOfObjectPath(service_path_);
+  array_writer.CloseContainer(&dict_entry_writer);
+
+  if (value) {
+    array_writer.OpenDictEntry(&dict_entry_writer);
+    dict_entry_writer.AppendString(
+        bluetooth_gatt_characteristic::kValueProperty);
+    dict_entry_writer.OpenVariant("ay", &variant_writer);
+    variant_writer.AppendArrayOfBytes(value->data(), value->size());
+    dict_entry_writer.CloseContainer(&variant_writer);
+    array_writer.CloseContainer(&dict_entry_writer);
+  }
+
+  // TODO(armansito): Process Flags & Permissions properties.
+
+  writer->CloseContainer(&array_writer);
+};
+
+void BluetoothGattCharacteristicServiceProviderImpl::OnGet(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender,
+    const std::vector<uint8_t>& value) {
+  VLOG(2) << "Returning characteristic value obtained from delegate.";
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  dbus::MessageWriter variant_writer(NULL);
+
+  writer.OpenVariant("ay", &variant_writer);
+  variant_writer.AppendArrayOfBytes(value.data(), value.size());
+  writer.CloseContainer(&variant_writer);
+
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::OnSet(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "Successfully set characteristic value. Return success.";
+  response_sender.Run(dbus::Response::FromMethodCall(method_call));
+}
+
+void BluetoothGattCharacteristicServiceProviderImpl::OnFailure(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "Failed to get/set characteristic value. Report error.";
+  std::unique_ptr<dbus::ErrorResponse> error_response =
+      dbus::ErrorResponse::FromMethodCall(
+          method_call, kErrorFailed, "Failed to get/set characteristic value.");
+  response_sender.Run(std::move(error_response));
+}
+
+const dbus::ObjectPath&
+BluetoothGattCharacteristicServiceProviderImpl::object_path() const {
+  return object_path_;
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h
new file mode 100644
index 0000000..f9c0f06d5
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h
@@ -0,0 +1,141 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_IMPL_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_IMPL_H_
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/platform_thread.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+#include "dbus/message.h"
+#include "dbus/object_path.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
+
+namespace bluez {
+
+// The BluetoothGattCharacteristicServiceProvider implementation used in
+// production.
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicServiceProviderImpl
+    : public BluetoothGattCharacteristicServiceProvider {
+ public:
+  BluetoothGattCharacteristicServiceProviderImpl(
+      dbus::Bus* bus,
+      const dbus::ObjectPath& object_path,
+      std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
+      const std::string& uuid,
+      const std::vector<std::string>& flags,
+      const std::vector<std::string>& permissions,
+      const dbus::ObjectPath& service_path);
+
+  ~BluetoothGattCharacteristicServiceProviderImpl() override;
+
+  // For testing.
+  BluetoothGattCharacteristicServiceProviderImpl(
+      const dbus::ObjectPath& object_path,
+      const std::string& uuid,
+      const dbus::ObjectPath& service_path);
+
+  // BluetoothGattCharacteristicServiceProvider override.
+  void SendValueChanged(const std::vector<uint8_t>& value) override;
+
+ private:
+  // Returns true if the current thread is on the origin thread.
+  bool OnOriginThread();
+
+  // Called by dbus:: when the Bluetooth daemon fetches a single property of
+  // the characteristic.
+  void Get(dbus::MethodCall* method_call,
+           dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when the Bluetooth daemon sets a single property of the
+  // characteristic.
+  void Set(dbus::MethodCall* method_call,
+           dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when the Bluetooth daemon fetches all properties of the
+  // characteristic.
+  void GetAll(dbus::MethodCall* method_call,
+              dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when a method is exported.
+  void OnExported(const std::string& interface_name,
+                  const std::string& method_name,
+                  bool success);
+
+  // Called by the Delegate in response to a method to call to get all
+  // properties, in which the delegate has successfully returned the
+  // characteristic value.
+  void OnGetAll(dbus::MethodCall* method_call,
+                dbus::ExportedObject::ResponseSender response_sender,
+                const std::vector<uint8_t>& value);
+
+  // Writes an array of the service's properties into the provided writer.
+  void WriteProperties(dbus::MessageWriter* writer,
+                       const std::vector<uint8_t>* value) override;
+
+  // Called by the Delegate in response to a successful method call to get the
+  // characteristic value.
+  void OnGet(dbus::MethodCall* method_call,
+             dbus::ExportedObject::ResponseSender response_sender,
+             const std::vector<uint8_t>& value);
+
+  // Called by the Delegate in response to a successful method call to set the
+  // characteristic value.
+  void OnSet(dbus::MethodCall* method_call,
+             dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by the Delegate in response to a failed method call to get or set
+  // the characteristic value.
+  void OnFailure(dbus::MethodCall* method_call,
+                 dbus::ExportedObject::ResponseSender response_sender);
+
+  const dbus::ObjectPath& object_path() const override;
+
+  // Origin thread (i.e. the UI thread in production).
+  base::PlatformThreadId origin_thread_id_;
+
+  // 128-bit characteristic UUID of this object.
+  std::string uuid_;
+
+  // D-Bus bus object is exported on, not owned by this object and must
+  // outlive it.
+  dbus::Bus* bus_;
+
+  // Incoming methods to get and set the "Value" property are passed on to the
+  // delegate and callbacks passed to generate a reply. |delegate_| is generally
+  // the object that owns this one and must outlive it.
+  std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate_;
+
+  // D-Bus object path of object we are exporting, kept so we can unregister
+  // again in our destructor.
+  dbus::ObjectPath object_path_;
+
+  // Object path of the GATT service that the exported characteristic belongs
+  // to.
+  dbus::ObjectPath service_path_;
+
+  // D-Bus object we are exporting, owned by this object.
+  scoped_refptr<dbus::ExportedObject> exported_object_;
+
+  // Weak pointer factory for generating 'this' pointers that might live longer
+  // than we do.
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<BluetoothGattCharacteristicServiceProviderImpl>
+      weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicServiceProviderImpl);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_IMPL_H_
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.cc
new file mode 100644
index 0000000..836b40c
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.cc
@@ -0,0 +1,33 @@
+// 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 "device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.h"
+
+#include "device/bluetooth/bluez/bluetooth_local_gatt_descriptor_bluez.h"
+
+namespace bluez {
+
+BluetoothGattDescriptorDelegateWrapper::BluetoothGattDescriptorDelegateWrapper(
+    BluetoothLocalGattServiceBlueZ* service,
+    BluetoothLocalGattDescriptorBlueZ* descriptor)
+    : service_(service), descriptor_(descriptor) {}
+
+void BluetoothGattDescriptorDelegateWrapper::GetValue(
+    const device::BluetoothLocalGattService::Delegate::ValueCallback& callback,
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
+  service_->GetDelegate()->OnDescriptorReadRequest(service_, descriptor_, 0,
+                                                   callback, error_callback);
+}
+
+void BluetoothGattDescriptorDelegateWrapper::SetValue(
+    const std::vector<uint8_t>& value,
+    const base::Closure& callback,
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
+  service_->GetDelegate()->OnDescriptorWriteRequest(
+      service_, descriptor_, value, 0, callback, error_callback);
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.h
new file mode 100644
index 0000000..8536b17
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_delegate_wrapper.h
@@ -0,0 +1,50 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_DELEGATE_WRAPPER_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_DELEGATE_WRAPPER_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "device/bluetooth/bluetooth_local_gatt_service.h"
+#include "device/bluetooth/bluez/bluetooth_gatt_service_bluez.h"
+#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h"
+
+namespace bluez {
+
+class BluetoothLocalGattDescriptorBlueZ;
+
+// Wrapper class around AttributeValueDelegate to handle descriptors.
+class BluetoothGattDescriptorDelegateWrapper
+    : public BluetoothGattAttributeValueDelegate {
+ public:
+  BluetoothGattDescriptorDelegateWrapper(
+      BluetoothLocalGattServiceBlueZ* service,
+      BluetoothLocalGattDescriptorBlueZ* descriptor);
+
+  void GetValue(
+      const device::BluetoothLocalGattService::Delegate::ValueCallback&
+          callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback) override;
+  void SetValue(
+      const std::vector<uint8_t>& value,
+      const base::Closure& callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback) override;
+
+ private:
+  BluetoothLocalGattServiceBlueZ* service_;
+  BluetoothLocalGattDescriptorBlueZ* descriptor_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorDelegateWrapper);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_DELEGATE_WRAPPER_H_
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc
index 239be9cc..5f85d9b 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc
@@ -4,438 +4,11 @@
 
 #include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
 
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/strings/string_util.h"
-#include "base/threading/platform_thread.h"
-#include "dbus/exported_object.h"
-#include "dbus/message.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace bluez {
-namespace {
-const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
-const char kErrorPropertyReadOnly[] =
-    "org.freedesktop.DBus.Error.PropertyReadOnly";
-const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed";
-}  // namespace
-
-// The BluetoothGattDescriptorServiceProvider implementation used in production.
-class BluetoothGattDescriptorServiceProviderImpl
-    : public BluetoothGattDescriptorServiceProvider {
- public:
-  BluetoothGattDescriptorServiceProviderImpl(
-      dbus::Bus* bus,
-      const dbus::ObjectPath& object_path,
-      Delegate* delegate,
-      const std::string& uuid,
-      const std::vector<std::string>& permissions,
-      const dbus::ObjectPath& characteristic_path)
-      : origin_thread_id_(base::PlatformThread::CurrentId()),
-        uuid_(uuid),
-        bus_(bus),
-        delegate_(delegate),
-        object_path_(object_path),
-        characteristic_path_(characteristic_path),
-        weak_ptr_factory_(this) {
-    VLOG(1) << "Created Bluetooth GATT characteristic descriptor: "
-            << object_path.value() << " UUID: " << uuid;
-    DCHECK(bus_);
-    DCHECK(delegate_);
-    DCHECK(!uuid_.empty());
-    DCHECK(object_path_.IsValid());
-    DCHECK(characteristic_path_.IsValid());
-    DCHECK(base::StartsWith(object_path_.value(),
-                            characteristic_path_.value() + "/",
-                            base::CompareCase::SENSITIVE));
-
-    exported_object_ = bus_->GetExportedObject(object_path_);
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet,
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::Get,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet,
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::Set,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll,
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::GetAll,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  ~BluetoothGattDescriptorServiceProviderImpl() override {
-    VLOG(1) << "Cleaning up Bluetooth GATT characteristic descriptor: "
-            << object_path_.value();
-    bus_->UnregisterExportedObject(object_path_);
-  }
-
-  // BluetoothGattDescriptorServiceProvider override.
-  void SendValueChanged(const std::vector<uint8_t>& value) override {
-    VLOG(2) << "Emitting a PropertiesChanged signal for descriptor value.";
-    dbus::Signal signal(dbus::kDBusPropertiesInterface,
-                        dbus::kDBusPropertiesChangedSignal);
-    dbus::MessageWriter writer(&signal);
-    dbus::MessageWriter array_writer(NULL);
-    dbus::MessageWriter dict_entry_writer(NULL);
-    dbus::MessageWriter variant_writer(NULL);
-
-    // interface_name
-    writer.AppendString(
-        bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface);
-
-    // changed_properties
-    writer.OpenArray("{sv}", &array_writer);
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kValueProperty);
-    dict_entry_writer.OpenVariant("ay", &variant_writer);
-    variant_writer.AppendArrayOfBytes(value.data(), value.size());
-    dict_entry_writer.CloseContainer(&variant_writer);
-    array_writer.CloseContainer(&dict_entry_writer);
-    writer.CloseContainer(&array_writer);
-
-    // invalidated_properties.
-    writer.OpenArray("s", &array_writer);
-    writer.CloseContainer(&array_writer);
-
-    exported_object_->SendSignal(&signal);
-  }
-
- private:
-  // Returns true if the current thread is on the origin thread.
-  bool OnOriginThread() {
-    return base::PlatformThread::CurrentId() == origin_thread_id_;
-  }
-
-  // Called by dbus:: when the Bluetooth daemon fetches a single property of
-  // the descriptor.
-  void Get(dbus::MethodCall* method_call,
-           dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattDescriptorServiceProvider::Get: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    std::string property_name;
-    if (!reader.PopString(&interface_name) ||
-        !reader.PopString(&property_name) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 'ss'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT descriptor interface is supported.
-    if (interface_name !=
-        bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // If getting the "Value" property, obtain the value from the delegate.
-    if (property_name == bluetooth_gatt_descriptor::kValueProperty) {
-      DCHECK(delegate_);
-      delegate_->GetDescriptorValue(
-          base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnGet,
-                     weak_ptr_factory_.GetWeakPtr(), method_call,
-                     response_sender),
-          base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure,
-                     weak_ptr_factory_.GetWeakPtr(), method_call,
-                     response_sender));
-      return;
-    }
-
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter variant_writer(NULL);
-
-    // TODO(armansito): Process the "Permissions" property below.
-    if (property_name == bluetooth_gatt_descriptor::kUUIDProperty) {
-      writer.OpenVariant("s", &variant_writer);
-      variant_writer.AppendString(uuid_);
-      writer.CloseContainer(&variant_writer);
-    } else if (property_name ==
-               bluetooth_gatt_descriptor::kCharacteristicProperty) {
-      writer.OpenVariant("o", &variant_writer);
-      variant_writer.AppendObjectPath(characteristic_path_);
-      writer.CloseContainer(&variant_writer);
-    } else {
-      response = dbus::ErrorResponse::FromMethodCall(
-          method_call, kErrorInvalidArgs,
-          "No such property: '" + property_name + "'.");
-    }
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by dbus:: when the Bluetooth daemon sets a single property of the
-  // descriptor.
-  void Set(dbus::MethodCall* method_call,
-           dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattDescriptorServiceProvider::Set: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    std::string property_name;
-    dbus::MessageReader variant_reader(NULL);
-    if (!reader.PopString(&interface_name) ||
-        !reader.PopString(&property_name) ||
-        !reader.PopVariant(&variant_reader) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 'ssv'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT descriptor interface is allowed.
-    if (interface_name !=
-        bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the "Value" property is writeable.
-    if (property_name != bluetooth_gatt_descriptor::kValueProperty) {
-      std::string error_name;
-      std::string error_message;
-      if (property_name == bluetooth_gatt_descriptor::kUUIDProperty ||
-          property_name == bluetooth_gatt_descriptor::kCharacteristicProperty) {
-        error_name = kErrorPropertyReadOnly;
-        error_message = "Read-only property: '" + property_name + "'.";
-      } else {
-        error_name = kErrorInvalidArgs;
-        error_message = "No such property: '" + property_name + "'.";
-      }
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, error_name,
-                                              error_message);
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Obtain the value.
-    const uint8_t* bytes = NULL;
-    size_t length = 0;
-    if (!variant_reader.PopArrayOfBytes(&bytes, &length)) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "Property '" + property_name + "' has type 'ay'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Pass the set request onto the delegate.
-    std::vector<uint8_t> value(bytes, bytes + length);
-    DCHECK(delegate_);
-    delegate_->SetDescriptorValue(
-        value, base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnSet,
-                          weak_ptr_factory_.GetWeakPtr(), method_call,
-                          response_sender),
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure,
-                   weak_ptr_factory_.GetWeakPtr(), method_call,
-                   response_sender));
-  }
-
-  // Called by dbus:: when the Bluetooth daemon fetches all properties of the
-  // descriptor.
-  void GetAll(dbus::MethodCall* method_call,
-              dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattDescriptorServiceProvider::GetAll: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    if (!reader.PopString(&interface_name) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 's'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT descriptor interface is supported.
-    if (interface_name !=
-        bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Try to obtain the value from the delegate. We will construct the
-    // response in the success callback.
-    DCHECK(delegate_);
-    delegate_->GetDescriptorValue(
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnGetAll,
-                   weak_ptr_factory_.GetWeakPtr(), method_call,
-                   response_sender),
-        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure,
-                   weak_ptr_factory_.GetWeakPtr(), method_call,
-                   response_sender));
-  }
-
-  // Called by dbus:: when a method is exported.
-  void OnExported(const std::string& interface_name,
-                  const std::string& method_name,
-                  bool success) {
-    LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "."
-                              << method_name;
-  }
-
-  // Called by the Delegate in response to a method to call to get all
-  // properties, in which the delegate has successfully returned the
-  // descriptor value.
-  void OnGetAll(dbus::MethodCall* method_call,
-                dbus::ExportedObject::ResponseSender response_sender,
-                const std::vector<uint8_t>& value) {
-    VLOG(2) << "Descriptor value obtained from delegate. Responding to "
-            << "GetAll.";
-
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter array_writer(NULL);
-    dbus::MessageWriter dict_entry_writer(NULL);
-    dbus::MessageWriter variant_writer(NULL);
-
-    writer.OpenArray("{sv}", &array_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kUUIDProperty);
-    dict_entry_writer.AppendVariantOfString(uuid_);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(
-        bluetooth_gatt_descriptor::kCharacteristicProperty);
-    dict_entry_writer.AppendVariantOfObjectPath(characteristic_path_);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kValueProperty);
-    dict_entry_writer.OpenVariant("ay", &variant_writer);
-    variant_writer.AppendArrayOfBytes(value.data(), value.size());
-    dict_entry_writer.CloseContainer(&variant_writer);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    // TODO(armansito): Process "Permissions" property.
-
-    writer.CloseContainer(&array_writer);
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by the Delegate in response to a successful method call to get the
-  // descriptor value.
-  void OnGet(dbus::MethodCall* method_call,
-             dbus::ExportedObject::ResponseSender response_sender,
-             const std::vector<uint8_t>& value) {
-    VLOG(2) << "Returning descriptor value obtained from delegate.";
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter variant_writer(NULL);
-
-    writer.OpenVariant("ay", &variant_writer);
-    variant_writer.AppendArrayOfBytes(value.data(), value.size());
-    writer.CloseContainer(&variant_writer);
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by the Delegate in response to a successful method call to set the
-  // descriptor value.
-  void OnSet(dbus::MethodCall* method_call,
-             dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "Successfully set descriptor value. Return success.";
-    response_sender.Run(dbus::Response::FromMethodCall(method_call));
-  }
-
-  // Called by the Delegate in response to a failed method call to get or set
-  // the descriptor value.
-  void OnFailure(dbus::MethodCall* method_call,
-                 dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "Failed to get/set descriptor value. Report error.";
-    std::unique_ptr<dbus::ErrorResponse> error_response =
-        dbus::ErrorResponse::FromMethodCall(
-            method_call, kErrorFailed, "Failed to get/set descriptor value.");
-    response_sender.Run(std::move(error_response));
-  }
-
-  // Origin thread (i.e. the UI thread in production).
-  base::PlatformThreadId origin_thread_id_;
-
-  // 128-bit descriptor UUID of this object.
-  std::string uuid_;
-
-  // D-Bus bus object is exported on, not owned by this object and must
-  // outlive it.
-  dbus::Bus* bus_;
-
-  // Incoming methods to get and set the "Value" property are passed on to the
-  // delegate and callbacks passed to generate a reply. |delegate_| is generally
-  // the object that owns this one and must outlive it.
-  Delegate* delegate_;
-
-  // D-Bus object path of object we are exporting, kept so we can unregister
-  // again in our destructor.
-  dbus::ObjectPath object_path_;
-
-  // Object path of the GATT characteristic that the exported descriptor belongs
-  // to.
-  dbus::ObjectPath characteristic_path_;
-
-  // D-Bus object we are exporting, owned by this object.
-  scoped_refptr<dbus::ExportedObject> exported_object_;
-
-  // Weak pointer factory for generating 'this' pointers that might live longer
-  // than we do.
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothGattDescriptorServiceProviderImpl>
-      weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorServiceProviderImpl);
-};
 
 BluetoothGattDescriptorServiceProvider::
     BluetoothGattDescriptorServiceProvider() {}
@@ -448,16 +21,17 @@
 BluetoothGattDescriptorServiceProvider::Create(
     dbus::Bus* bus,
     const dbus::ObjectPath& object_path,
-    Delegate* delegate,
+    std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
     const std::string& uuid,
     const std::vector<std::string>& permissions,
     const dbus::ObjectPath& characteristic_path) {
   if (!bluez::BluezDBusManager::Get()->IsUsingFakes()) {
     return new BluetoothGattDescriptorServiceProviderImpl(
-        bus, object_path, delegate, uuid, permissions, characteristic_path);
+        bus, object_path, std::move(delegate), uuid, permissions,
+        characteristic_path);
   }
   return new FakeBluetoothGattDescriptorServiceProvider(
-      object_path, delegate, uuid, permissions, characteristic_path);
+      object_path, std::move(delegate), uuid, permissions, characteristic_path);
 }
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
index b9e4959..043c013 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
@@ -6,15 +6,15 @@
 #define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
 
 #include <stdint.h>
-
 #include <string>
 #include <vector>
 
-#include "base/callback.h"
 #include "base/macros.h"
 #include "dbus/bus.h"
+#include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h"
 
 namespace bluez {
 
@@ -34,50 +34,20 @@
 // "Value" property.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptorServiceProvider {
  public:
-  // Interface for reacting to GATT characteristic descriptor value requests.
-  class Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // ValueCallback is used for methods that require a descriptor value
-    // to be returned.
-    typedef base::Callback<void(const std::vector<uint8_t>&)> ValueCallback;
-
-    // ErrorCallback is used by methods to report failure.
-    typedef base::Closure ErrorCallback;
-
-    // This method will be called when a remote device requests to read the
-    // value of the exported GATT descriptor. Invoke |callback| with a value
-    // to return that value to the requester. Invoke |error_callback| to report
-    // a failure to read the value. This can happen, for example, if the
-    // descriptor has no read permission set. Either callback should be
-    // invoked after a reasonable amount of time, since the request will time
-    // out if left pending for too long.
-    virtual void GetDescriptorValue(const ValueCallback& callback,
-                                    const ErrorCallback& error_callback) = 0;
-
-    // This method will be called, when a remote device requests to write the
-    // value of the exported GATT descriptor. Invoke |callback| to report
-    // that the value was successfully written. Invoke |error_callback| to
-    // report a failure to write the value. This can happen, for example, if the
-    // descriptor has no write permission set. Either callback should be
-    // invoked after a reasonable amount of time, since the request will time
-    // out if left pending for too long.
-    //
-    // The delegate should use this method to perform any side-effects that may
-    // occur based on the set value and potentially send a property changed
-    // signal to notify the Bluetooth daemon that the value has changed.
-    virtual void SetDescriptorValue(const std::vector<uint8_t>& value,
-                                    const base::Closure& callback,
-                                    const ErrorCallback& error_callback) = 0;
-  };
-
   virtual ~BluetoothGattDescriptorServiceProvider();
 
   // Send a PropertyChanged signal to notify the Bluetooth daemon that the value
   // of the "Value" property has changed to |value|.
   virtual void SendValueChanged(const std::vector<uint8_t>& value) = 0;
 
+  // Writes the descriptor's properties into the provided writer. If
+  // value is not null, it is written also, otherwise no value property is
+  // written.
+  virtual void WriteProperties(dbus::MessageWriter* writer,
+                               const std::vector<uint8_t>* value) {}
+
+  virtual const dbus::ObjectPath& object_path() const = 0;
+
   // Creates the instance, where |bus| is the D-Bus bus connection to export
   // the object onto, |uuid| is the 128-bit GATT descriptor UUID, |permissions|
   // is the list of attribute permissions, |characteristic_path| is the object
@@ -94,7 +64,7 @@
   static BluetoothGattDescriptorServiceProvider* Create(
       dbus::Bus* bus,
       const dbus::ObjectPath& object_path,
-      Delegate* delegate,
+      std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
       const std::string& uuid,
       const std::vector<std::string>& permissions,
       const dbus::ObjectPath& characteristic_path);
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.cc
new file mode 100644
index 0000000..1d38aaf
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.cc
@@ -0,0 +1,409 @@
+// 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 "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h"
+
+#include <stddef.h>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace bluez {
+
+namespace {
+
+const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
+const char kErrorPropertyReadOnly[] =
+    "org.freedesktop.DBus.Error.PropertyReadOnly";
+const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed";
+
+}  // namespace
+
+// The BluetoothGattDescriptorServiceProvider implementation used in production.
+BluetoothGattDescriptorServiceProviderImpl::
+    BluetoothGattDescriptorServiceProviderImpl(
+        dbus::Bus* bus,
+        const dbus::ObjectPath& object_path,
+        std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
+        const std::string& uuid,
+        const std::vector<std::string>& permissions,
+        const dbus::ObjectPath& characteristic_path)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      uuid_(uuid),
+      bus_(bus),
+      delegate_(std::move(delegate)),
+      object_path_(object_path),
+      characteristic_path_(characteristic_path),
+      weak_ptr_factory_(this) {
+  VLOG(1) << "Created Bluetooth GATT characteristic descriptor: "
+          << object_path.value() << " UUID: " << uuid;
+  DCHECK(bus_);
+  DCHECK(delegate_);
+  DCHECK(!uuid_.empty());
+  DCHECK(object_path_.IsValid());
+  DCHECK(characteristic_path_.IsValid());
+  DCHECK(base::StartsWith(object_path_.value(),
+                          characteristic_path_.value() + "/",
+                          base::CompareCase::SENSITIVE));
+
+  exported_object_ = bus_->GetExportedObject(object_path_);
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet,
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::Get,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet,
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::Set,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll,
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::GetAll,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+BluetoothGattDescriptorServiceProviderImpl::
+    ~BluetoothGattDescriptorServiceProviderImpl() {
+  VLOG(1) << "Cleaning up Bluetooth GATT characteristic descriptor: "
+          << object_path_.value();
+  if (bus_)
+    bus_->UnregisterExportedObject(object_path_);
+}
+
+BluetoothGattDescriptorServiceProviderImpl::
+    BluetoothGattDescriptorServiceProviderImpl(
+        const dbus::ObjectPath& object_path,
+        const std::string& uuid,
+        const dbus::ObjectPath& characteristic_path)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      uuid_(uuid),
+      bus_(nullptr),
+      delegate_(nullptr),
+      object_path_(object_path),
+      characteristic_path_(characteristic_path),
+      weak_ptr_factory_(this) {}
+
+void BluetoothGattDescriptorServiceProviderImpl::SendValueChanged(
+    const std::vector<uint8_t>& value) {
+  VLOG(2) << "Emitting a PropertiesChanged signal for descriptor value.";
+  dbus::Signal signal(dbus::kDBusPropertiesInterface,
+                      dbus::kDBusPropertiesChangedSignal);
+  dbus::MessageWriter writer(&signal);
+  dbus::MessageWriter array_writer(NULL);
+  dbus::MessageWriter dict_entry_writer(NULL);
+  dbus::MessageWriter variant_writer(NULL);
+
+  // interface_name
+  writer.AppendString(
+      bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface);
+
+  // changed_properties
+  writer.OpenArray("{sv}", &array_writer);
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kValueProperty);
+  dict_entry_writer.OpenVariant("ay", &variant_writer);
+  variant_writer.AppendArrayOfBytes(value.data(), value.size());
+  dict_entry_writer.CloseContainer(&variant_writer);
+  array_writer.CloseContainer(&dict_entry_writer);
+  writer.CloseContainer(&array_writer);
+
+  // invalidated_properties.
+  writer.OpenArray("s", &array_writer);
+  writer.CloseContainer(&array_writer);
+
+  exported_object_->SendSignal(&signal);
+}
+
+bool BluetoothGattDescriptorServiceProviderImpl::OnOriginThread() {
+  return base::PlatformThread::CurrentId() == origin_thread_id_;
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::Get(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattDescriptorServiceProvider::Get: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  std::string property_name;
+  if (!reader.PopString(&interface_name) || !reader.PopString(&property_name) ||
+      reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 'ss'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT descriptor interface is supported.
+  if (interface_name !=
+      bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // If getting the "Value" property, obtain the value from the delegate.
+  if (property_name == bluetooth_gatt_descriptor::kValueProperty) {
+    DCHECK(delegate_);
+    delegate_->GetValue(
+        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnGet,
+                   weak_ptr_factory_.GetWeakPtr(), method_call,
+                   response_sender),
+        base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure,
+                   weak_ptr_factory_.GetWeakPtr(), method_call,
+                   response_sender));
+    return;
+  }
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  dbus::MessageWriter variant_writer(NULL);
+
+  // TODO(armansito): Process the "Permissions" property below.
+  if (property_name == bluetooth_gatt_descriptor::kUUIDProperty) {
+    writer.OpenVariant("s", &variant_writer);
+    variant_writer.AppendString(uuid_);
+    writer.CloseContainer(&variant_writer);
+  } else if (property_name ==
+             bluetooth_gatt_descriptor::kCharacteristicProperty) {
+    writer.OpenVariant("o", &variant_writer);
+    variant_writer.AppendObjectPath(characteristic_path_);
+    writer.CloseContainer(&variant_writer);
+  } else {
+    response = dbus::ErrorResponse::FromMethodCall(
+        method_call, kErrorInvalidArgs,
+        "No such property: '" + property_name + "'.");
+  }
+
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::Set(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattDescriptorServiceProvider::Set: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  std::string property_name;
+  dbus::MessageReader variant_reader(NULL);
+  if (!reader.PopString(&interface_name) || !reader.PopString(&property_name) ||
+      !reader.PopVariant(&variant_reader) || reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 'ssv'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT descriptor interface is allowed.
+  if (interface_name !=
+      bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the "Value" property is writeable.
+  if (property_name != bluetooth_gatt_descriptor::kValueProperty) {
+    std::string error_name;
+    std::string error_message;
+    if (property_name == bluetooth_gatt_descriptor::kUUIDProperty ||
+        property_name == bluetooth_gatt_descriptor::kCharacteristicProperty) {
+      error_name = kErrorPropertyReadOnly;
+      error_message = "Read-only property: '" + property_name + "'.";
+    } else {
+      error_name = kErrorInvalidArgs;
+      error_message = "No such property: '" + property_name + "'.";
+    }
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, error_name,
+                                            error_message);
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Obtain the value.
+  const uint8_t* bytes = NULL;
+  size_t length = 0;
+  if (!variant_reader.PopArrayOfBytes(&bytes, &length)) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "Property '" + property_name + "' has type 'ay'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Pass the set request onto the delegate.
+  std::vector<uint8_t> value(bytes, bytes + length);
+  DCHECK(delegate_);
+  delegate_->SetValue(
+      value,
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnSet,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender),
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender));
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::GetAll(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattDescriptorServiceProvider::GetAll: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  if (!reader.PopString(&interface_name) || reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 's'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT descriptor interface is supported.
+  if (interface_name !=
+      bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Try to obtain the value from the delegate. We will construct the
+  // response in the success callback.
+  DCHECK(delegate_);
+  delegate_->GetValue(
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnGetAll,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender),
+      base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure,
+                 weak_ptr_factory_.GetWeakPtr(), method_call, response_sender));
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::OnExported(
+    const std::string& interface_name,
+    const std::string& method_name,
+    bool success) {
+  LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "."
+                            << method_name;
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::OnGetAll(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender,
+    const std::vector<uint8_t>& value) {
+  VLOG(2) << "Descriptor value obtained from delegate. Responding to "
+          << "GetAll.";
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  WriteProperties(&writer, &value);
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::WriteProperties(
+    dbus::MessageWriter* writer,
+    const std::vector<uint8_t>* value) {
+  dbus::MessageWriter array_writer(NULL);
+  dbus::MessageWriter dict_entry_writer(NULL);
+  dbus::MessageWriter variant_writer(NULL);
+
+  writer->OpenArray("{sv}", &array_writer);
+
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kUUIDProperty);
+  dict_entry_writer.AppendVariantOfString(uuid_);
+  array_writer.CloseContainer(&dict_entry_writer);
+
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(
+      bluetooth_gatt_descriptor::kCharacteristicProperty);
+  dict_entry_writer.AppendVariantOfObjectPath(characteristic_path_);
+  array_writer.CloseContainer(&dict_entry_writer);
+
+  if (value) {
+    array_writer.OpenDictEntry(&dict_entry_writer);
+    dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kValueProperty);
+    dict_entry_writer.OpenVariant("ay", &variant_writer);
+    variant_writer.AppendArrayOfBytes(value->data(), value->size());
+    dict_entry_writer.CloseContainer(&variant_writer);
+    array_writer.CloseContainer(&dict_entry_writer);
+  }
+
+  // TODO(armansito): Process "Permissions" property.
+  writer->CloseContainer(&array_writer);
+}
+
+// Called by the Delegate in response to a successful method call to get the
+// descriptor value.
+void BluetoothGattDescriptorServiceProviderImpl::OnGet(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender,
+    const std::vector<uint8_t>& value) {
+  VLOG(2) << "Returning descriptor value obtained from delegate.";
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  dbus::MessageWriter variant_writer(NULL);
+
+  writer.OpenVariant("ay", &variant_writer);
+  variant_writer.AppendArrayOfBytes(value.data(), value.size());
+  writer.CloseContainer(&variant_writer);
+
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::OnSet(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "Successfully set descriptor value. Return success.";
+  response_sender.Run(dbus::Response::FromMethodCall(method_call));
+}
+
+void BluetoothGattDescriptorServiceProviderImpl::OnFailure(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "Failed to get/set descriptor value. Report error.";
+  std::unique_ptr<dbus::ErrorResponse> error_response =
+      dbus::ErrorResponse::FromMethodCall(
+          method_call, kErrorFailed, "Failed to get/set descriptor value.");
+  response_sender.Run(std::move(error_response));
+}
+
+const dbus::ObjectPath&
+BluetoothGattDescriptorServiceProviderImpl::object_path() const {
+  return object_path_;
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h
new file mode 100644
index 0000000..46874bb
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h
@@ -0,0 +1,140 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_IMPL_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_IMPL_H_
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/platform_thread.h"
+#include "dbus/bus.h"
+#include "dbus/exported_object.h"
+#include "dbus/message.h"
+#include "dbus/object_path.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
+
+namespace bluez {
+
+// The BluetoothGattDescriptorServiceProvider implementation used in production.
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptorServiceProviderImpl
+    : public BluetoothGattDescriptorServiceProvider {
+ public:
+  BluetoothGattDescriptorServiceProviderImpl(
+      dbus::Bus* bus,
+      const dbus::ObjectPath& object_path,
+      std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
+      const std::string& uuid,
+      const std::vector<std::string>& permissions,
+      const dbus::ObjectPath& characteristic_path);
+  ~BluetoothGattDescriptorServiceProviderImpl() override;
+
+  // For testing.
+  BluetoothGattDescriptorServiceProviderImpl(
+      const dbus::ObjectPath& object_path,
+      const std::string& uuid,
+      const dbus::ObjectPath& characteristic_path);
+
+  // BluetoothGattDescriptorServiceProvider override.
+  void SendValueChanged(const std::vector<uint8_t>& value) override;
+
+ private:
+  // Returns true if the current thread is on the origin thread.
+  bool OnOriginThread();
+
+  // Called by dbus:: when the Bluetooth daemon fetches a single property of
+  // the descriptor.
+  void Get(dbus::MethodCall* method_call,
+           dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when the Bluetooth daemon sets a single property of the
+  // descriptor.
+  void Set(dbus::MethodCall* method_call,
+           dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when the Bluetooth daemon fetches all properties of the
+  // descriptor.
+  void GetAll(dbus::MethodCall* method_call,
+              dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when a method is exported.
+  void OnExported(const std::string& interface_name,
+                  const std::string& method_name,
+                  bool success);
+
+  // Called by the Delegate in response to a method to call to get all
+  // properties, in which the delegate has successfully returned the
+  // descriptor value.
+  void OnGetAll(dbus::MethodCall* method_call,
+                dbus::ExportedObject::ResponseSender response_sender,
+                const std::vector<uint8_t>& value);
+
+  // Writes the characteristics's properties into the provided writer. If
+  // value is not null, it is written also, otherwise no value property is
+  // written.
+  void WriteProperties(dbus::MessageWriter* writer,
+                       const std::vector<uint8_t>* value) override;
+
+  // Called by the Delegate in response to a successful method call to get the
+  // descriptor value.
+  void OnGet(dbus::MethodCall* method_call,
+             dbus::ExportedObject::ResponseSender response_sender,
+             const std::vector<uint8_t>& value);
+
+  // Called by the Delegate in response to a successful method call to set the
+  // descriptor value.
+  void OnSet(dbus::MethodCall* method_call,
+             dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by the Delegate in response to a failed method call to get or set
+  // the descriptor value.
+  void OnFailure(dbus::MethodCall* method_call,
+                 dbus::ExportedObject::ResponseSender response_sender);
+
+  const dbus::ObjectPath& object_path() const override;
+
+  // Origin thread (i.e. the UI thread in production).
+  base::PlatformThreadId origin_thread_id_;
+
+  // 128-bit descriptor UUID of this object.
+  std::string uuid_;
+
+  // D-Bus bus object is exported on, not owned by this object and must
+  // outlive it.
+  dbus::Bus* bus_;
+
+  // Incoming methods to get and set the "Value" property are passed on to the
+  // delegate and callbacks passed to generate a reply. |delegate_| is generally
+  // the object that owns this one and must outlive it.
+  std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate_;
+
+  // D-Bus object path of object we are exporting, kept so we can unregister
+  // again in our destructor.
+  dbus::ObjectPath object_path_;
+
+  // Object path of the GATT characteristic that the exported descriptor belongs
+  // to.
+  dbus::ObjectPath characteristic_path_;
+
+  // D-Bus object we are exporting, owned by this object.
+  scoped_refptr<dbus::ExportedObject> exported_object_;
+
+  // Weak pointer factory for generating 'this' pointers that might live longer
+  // than we do.
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<BluetoothGattDescriptorServiceProviderImpl>
+      weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorServiceProviderImpl);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_IMPL_H_
diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
index 2f88910..afa103a 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
@@ -26,20 +26,20 @@
   ~BluetoothGattManagerClientImpl() override {}
 
   // BluetoothGattManagerClient override.
-  void RegisterService(const dbus::ObjectPath& service_path,
-                       const Options& options,
-                       const base::Closure& callback,
-                       const ErrorCallback& error_callback) override {
+  void RegisterApplication(const dbus::ObjectPath& application_path,
+                           const Options& options,
+                           const base::Closure& callback,
+                           const ErrorCallback& error_callback) override {
     dbus::MethodCall method_call(
         bluetooth_gatt_manager::kBluetoothGattManagerInterface,
         bluetooth_gatt_manager::kRegisterService);
 
     dbus::MessageWriter writer(&method_call);
-    writer.AppendObjectPath(service_path);
+    writer.AppendObjectPath(application_path);
 
-    // TODO(armansito): The parameters of the Options dictionary are undefined
-    // but the method signature still requires a value dictionary. Pass an
-    // empty dictionary and fill in the contents later once this is defined.
+    // The parameters of the Options dictionary are undefined but the method
+    // signature still requires a value dictionary. Pass an empty dictionary
+    // and fill in the contents later if and when we add any options.
     dbus::MessageWriter array_writer(NULL);
     writer.OpenArray("{sv}", &array_writer);
     writer.CloseContainer(&array_writer);
@@ -54,15 +54,15 @@
   }
 
   // BluetoothGattManagerClient override.
-  void UnregisterService(const dbus::ObjectPath& service_path,
-                         const base::Closure& callback,
-                         const ErrorCallback& error_callback) override {
+  void UnregisterApplication(const dbus::ObjectPath& application_path,
+                             const base::Closure& callback,
+                             const ErrorCallback& error_callback) override {
     dbus::MethodCall method_call(
         bluetooth_gatt_manager::kBluetoothGattManagerInterface,
         bluetooth_gatt_manager::kUnregisterService);
 
     dbus::MessageWriter writer(&method_call);
-    writer.AppendObjectPath(service_path);
+    writer.AppendObjectPath(application_path);
 
     DCHECK(object_proxy_);
     object_proxy_->CallMethodWithErrorCallback(
diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
index b735f77..1213fc5 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
@@ -45,16 +45,16 @@
   // using D-Bus Object Manager. Hence, the object paths and the interfaces in
   // the registered hierarchy must comply with the BlueZ GATT D-Bus
   // specification.
-  virtual void RegisterService(const dbus::ObjectPath& service_path,
-                               const Options& options,
-                               const base::Closure& callback,
-                               const ErrorCallback& error_callback) = 0;
+  virtual void RegisterApplication(const dbus::ObjectPath& application_path,
+                                   const Options& options,
+                                   const base::Closure& callback,
+                                   const ErrorCallback& error_callback) = 0;
 
   // Unregisters the GATT service with the D-Bus object path |service_path| from
   // the remote GATT manager.
-  virtual void UnregisterService(const dbus::ObjectPath& service_path,
-                                 const base::Closure& callback,
-                                 const ErrorCallback& error_callback) = 0;
+  virtual void UnregisterApplication(const dbus::ObjectPath& application_path,
+                                     const base::Closure& callback,
+                                     const ErrorCallback& error_callback) = 0;
 
   // Creates the instance.
   static BluetoothGattManagerClient* Create();
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc
index 686a1a5..04d93d5 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc
@@ -4,255 +4,11 @@
 
 #include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h"
 
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/platform_thread.h"
-#include "dbus/exported_object.h"
-#include "dbus/message.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace bluez {
-namespace {
-const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
-const char kErrorPropertyReadOnly[] =
-    "org.freedesktop.DBus.Error.PropertyReadOnly";
-}  // namespace
-
-// The BluetoothGattServiceServiceProvider implementation used in production.
-class BluetoothGattServiceServiceProviderImpl
-    : public BluetoothGattServiceServiceProvider {
- public:
-  BluetoothGattServiceServiceProviderImpl(
-      dbus::Bus* bus,
-      const dbus::ObjectPath& object_path,
-      const std::string& uuid,
-      const std::vector<dbus::ObjectPath>& includes)
-      : origin_thread_id_(base::PlatformThread::CurrentId()),
-        uuid_(uuid),
-        includes_(includes),
-        bus_(bus),
-        object_path_(object_path),
-        weak_ptr_factory_(this) {
-    VLOG(1) << "Creating Bluetooth GATT service: " << object_path_.value()
-            << " UUID: " << uuid;
-    DCHECK(!uuid_.empty());
-    DCHECK(object_path_.IsValid());
-    DCHECK(bus_);
-
-    exported_object_ = bus_->GetExportedObject(object_path_);
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet,
-        base::Bind(&BluetoothGattServiceServiceProviderImpl::Get,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet,
-        base::Bind(&BluetoothGattServiceServiceProviderImpl::Set,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-
-    exported_object_->ExportMethod(
-        dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll,
-        base::Bind(&BluetoothGattServiceServiceProviderImpl::GetAll,
-                   weak_ptr_factory_.GetWeakPtr()),
-        base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported,
-                   weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  ~BluetoothGattServiceServiceProviderImpl() override {
-    VLOG(1) << "Cleaning up Bluetooth GATT service: " << object_path_.value();
-    bus_->UnregisterExportedObject(object_path_);
-  }
-
- private:
-  // Returns true if the current thread is on the origin thread.
-  bool OnOriginThread() {
-    return base::PlatformThread::CurrentId() == origin_thread_id_;
-  }
-
-  // Called by dbus:: when the Bluetooth daemon fetches a single property of
-  // the service.
-  void Get(dbus::MethodCall* method_call,
-           dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattServiceServiceProvider::Get: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    std::string property_name;
-    if (!reader.PopString(&interface_name) ||
-        !reader.PopString(&property_name) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 'ss'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT service interface is allowed.
-    if (interface_name !=
-        bluetooth_gatt_service::kBluetoothGattServiceInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Return error if |property_name| is unknown.
-    if (property_name != bluetooth_gatt_service::kUUIDProperty &&
-        property_name != bluetooth_gatt_service::kIncludesProperty) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such property: '" + property_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter variant_writer(NULL);
-
-    if (property_name == bluetooth_gatt_service::kUUIDProperty) {
-      writer.OpenVariant("s", &variant_writer);
-      variant_writer.AppendString(uuid_);
-      writer.CloseContainer(&variant_writer);
-    } else {
-      writer.OpenVariant("ao", &variant_writer);
-      variant_writer.AppendArrayOfObjectPaths(includes_);
-      writer.CloseContainer(&variant_writer);
-    }
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by dbus:: when the Bluetooth daemon sets a single property of the
-  // service.
-  void Set(dbus::MethodCall* method_call,
-           dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattServiceServiceProvider::Set: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    // All of the properties on this interface are read-only, so just return
-    // error.
-    std::unique_ptr<dbus::ErrorResponse> error_response =
-        dbus::ErrorResponse::FromMethodCall(method_call, kErrorPropertyReadOnly,
-                                            "All properties are read-only.");
-    response_sender.Run(std::move(error_response));
-  }
-
-  // Called by dbus:: when the Bluetooth daemon fetches all properties of the
-  // service.
-  void GetAll(dbus::MethodCall* method_call,
-              dbus::ExportedObject::ResponseSender response_sender) {
-    VLOG(2) << "BluetoothGattServiceServiceProvider::GetAll: "
-            << object_path_.value();
-    DCHECK(OnOriginThread());
-
-    dbus::MessageReader reader(method_call);
-
-    std::string interface_name;
-    if (!reader.PopString(&interface_name) || reader.HasMoreData()) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
-                                              "Expected 's'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    // Only the GATT service interface is allowed.
-    if (interface_name !=
-        bluetooth_gatt_service::kBluetoothGattServiceInterface) {
-      std::unique_ptr<dbus::ErrorResponse> error_response =
-          dbus::ErrorResponse::FromMethodCall(
-              method_call, kErrorInvalidArgs,
-              "No such interface: '" + interface_name + "'.");
-      response_sender.Run(std::move(error_response));
-      return;
-    }
-
-    std::unique_ptr<dbus::Response> response =
-        dbus::Response::FromMethodCall(method_call);
-    dbus::MessageWriter writer(response.get());
-    dbus::MessageWriter array_writer(NULL);
-    dbus::MessageWriter dict_entry_writer(NULL);
-    dbus::MessageWriter variant_writer(NULL);
-
-    writer.OpenArray("{sv}", &array_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(bluetooth_gatt_service::kUUIDProperty);
-    dict_entry_writer.AppendVariantOfString(uuid_);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    array_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(bluetooth_gatt_service::kIncludesProperty);
-    dict_entry_writer.OpenVariant("ao", &variant_writer);
-    variant_writer.AppendArrayOfObjectPaths(includes_);
-    dict_entry_writer.CloseContainer(&variant_writer);
-    array_writer.CloseContainer(&dict_entry_writer);
-
-    writer.CloseContainer(&array_writer);
-
-    response_sender.Run(std::move(response));
-  }
-
-  // Called by dbus:: when a method is exported.
-  void OnExported(const std::string& interface_name,
-                  const std::string& method_name,
-                  bool success) {
-    LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "."
-                              << method_name;
-  }
-
-  // Origin thread (i.e. the UI thread in production).
-  base::PlatformThreadId origin_thread_id_;
-
-  // 128-bit service UUID of this object.
-  std::string uuid_;
-
-  // List of object paths that represent other exported GATT services that are
-  // included from this service.
-  std::vector<dbus::ObjectPath> includes_;
-
-  // D-Bus bus object is exported on, not owned by this object and must
-  // outlive it.
-  dbus::Bus* bus_;
-
-  // D-Bus object path of object we are exporting, kept so we can unregister
-  // again in our destructor.
-  dbus::ObjectPath object_path_;
-
-  // D-Bus object we are exporting, owned by this object.
-  scoped_refptr<dbus::ExportedObject> exported_object_;
-
-  // Weak pointer factory for generating 'this' pointers that might live longer
-  // than we do.
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<BluetoothGattServiceServiceProviderImpl>
-      weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceServiceProviderImpl);
-};
 
 BluetoothGattServiceServiceProvider::BluetoothGattServiceServiceProvider() {}
 
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
index ba101ca7..db8090a 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
@@ -10,6 +10,7 @@
 
 #include "base/macros.h"
 #include "dbus/bus.h"
+#include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_export.h"
 
@@ -29,6 +30,11 @@
  public:
   virtual ~BluetoothGattServiceServiceProvider();
 
+  // Writes an array of the service's properties into the provided writer.
+  virtual void WriteProperties(dbus::MessageWriter* writer) {}
+
+  virtual const dbus::ObjectPath& object_path() const = 0;
+
   // Creates the instance where |bus| is the D-Bus bus connection to export the
   // object onto, |object_path| is the object path that it should have, |uuid|
   // is the 128-bit GATT service UUID, and |includes| are a list of object paths
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.cc b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.cc
new file mode 100644
index 0000000..4dec155
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.cc
@@ -0,0 +1,230 @@
+// 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 "device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace bluez {
+
+namespace {
+
+const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
+const char kErrorPropertyReadOnly[] =
+    "org.freedesktop.DBus.Error.PropertyReadOnly";
+
+}  // namespace
+
+BluetoothGattServiceServiceProviderImpl::
+    BluetoothGattServiceServiceProviderImpl(
+        dbus::Bus* bus,
+        const dbus::ObjectPath& object_path,
+        const std::string& uuid,
+        const std::vector<dbus::ObjectPath>& includes)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      uuid_(uuid),
+      includes_(includes),
+      bus_(bus),
+      object_path_(object_path),
+      weak_ptr_factory_(this) {
+  VLOG(1) << "Creating Bluetooth GATT service: " << object_path_.value()
+          << " UUID: " << uuid;
+  DCHECK(!uuid_.empty());
+  DCHECK(object_path_.IsValid());
+  DCHECK(bus_);
+
+  exported_object_ = bus_->GetExportedObject(object_path_);
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet,
+      base::Bind(&BluetoothGattServiceServiceProviderImpl::Get,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet,
+      base::Bind(&BluetoothGattServiceServiceProviderImpl::Set,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+
+  exported_object_->ExportMethod(
+      dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll,
+      base::Bind(&BluetoothGattServiceServiceProviderImpl::GetAll,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+BluetoothGattServiceServiceProviderImpl::
+    ~BluetoothGattServiceServiceProviderImpl() {
+  VLOG(1) << "Cleaning up Bluetooth GATT service: " << object_path_.value();
+  if (bus_)
+    bus_->UnregisterExportedObject(object_path_);
+}
+
+BluetoothGattServiceServiceProviderImpl::
+    BluetoothGattServiceServiceProviderImpl(const dbus::ObjectPath& object_path,
+                                            const std::string& uuid)
+    : origin_thread_id_(base::PlatformThread::CurrentId()),
+      uuid_(uuid),
+      bus_(nullptr),
+      object_path_(object_path),
+      weak_ptr_factory_(this) {}
+
+bool BluetoothGattServiceServiceProviderImpl::OnOriginThread() {
+  return base::PlatformThread::CurrentId() == origin_thread_id_;
+}
+
+void BluetoothGattServiceServiceProviderImpl::Get(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattServiceServiceProvider::Get: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  std::string property_name;
+  if (!reader.PopString(&interface_name) || !reader.PopString(&property_name) ||
+      reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 'ss'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT service interface is allowed.
+  if (interface_name !=
+      bluetooth_gatt_service::kBluetoothGattServiceInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Return error if |property_name| is unknown.
+  if (property_name != bluetooth_gatt_service::kUUIDProperty &&
+      property_name != bluetooth_gatt_service::kIncludesProperty) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such property: '" + property_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  dbus::MessageWriter variant_writer(NULL);
+
+  if (property_name == bluetooth_gatt_service::kUUIDProperty) {
+    writer.OpenVariant("s", &variant_writer);
+    variant_writer.AppendString(uuid_);
+    writer.CloseContainer(&variant_writer);
+  } else {
+    writer.OpenVariant("ao", &variant_writer);
+    variant_writer.AppendArrayOfObjectPaths(includes_);
+    writer.CloseContainer(&variant_writer);
+  }
+
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattServiceServiceProviderImpl::Set(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattServiceServiceProvider::Set: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  // All of the properties on this interface are read-only, so just return
+  // error.
+  std::unique_ptr<dbus::ErrorResponse> error_response =
+      dbus::ErrorResponse::FromMethodCall(method_call, kErrorPropertyReadOnly,
+                                          "All properties are read-only.");
+  response_sender.Run(std::move(error_response));
+}
+
+void BluetoothGattServiceServiceProviderImpl::GetAll(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  VLOG(2) << "BluetoothGattServiceServiceProvider::GetAll: "
+          << object_path_.value();
+  DCHECK(OnOriginThread());
+
+  dbus::MessageReader reader(method_call);
+
+  std::string interface_name;
+  if (!reader.PopString(&interface_name) || reader.HasMoreData()) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs,
+                                            "Expected 's'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  // Only the GATT service interface is allowed.
+  if (interface_name !=
+      bluetooth_gatt_service::kBluetoothGattServiceInterface) {
+    std::unique_ptr<dbus::ErrorResponse> error_response =
+        dbus::ErrorResponse::FromMethodCall(
+            method_call, kErrorInvalidArgs,
+            "No such interface: '" + interface_name + "'.");
+    response_sender.Run(std::move(error_response));
+    return;
+  }
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  WriteProperties(&writer);
+  response_sender.Run(std::move(response));
+}
+
+void BluetoothGattServiceServiceProviderImpl::WriteProperties(
+    dbus::MessageWriter* writer) {
+  dbus::MessageWriter array_writer(NULL);
+  dbus::MessageWriter dict_entry_writer(NULL);
+  dbus::MessageWriter variant_writer(NULL);
+
+  writer->OpenArray("{sv}", &array_writer);
+
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(bluetooth_gatt_service::kUUIDProperty);
+  dict_entry_writer.AppendVariantOfString(uuid_);
+  array_writer.CloseContainer(&dict_entry_writer);
+
+  array_writer.OpenDictEntry(&dict_entry_writer);
+  dict_entry_writer.AppendString(bluetooth_gatt_service::kIncludesProperty);
+  dict_entry_writer.OpenVariant("ao", &variant_writer);
+  variant_writer.AppendArrayOfObjectPaths(includes_);
+  dict_entry_writer.CloseContainer(&variant_writer);
+  array_writer.CloseContainer(&dict_entry_writer);
+
+  writer->CloseContainer(&array_writer);
+}
+
+void BluetoothGattServiceServiceProviderImpl::OnExported(
+    const std::string& interface_name,
+    const std::string& method_name,
+    bool success) {
+  LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "."
+                            << method_name;
+}
+
+const dbus::ObjectPath& BluetoothGattServiceServiceProviderImpl::object_path()
+    const {
+  return object_path_;
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h
new file mode 100644
index 0000000..2aa4c41
--- /dev/null
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h
@@ -0,0 +1,100 @@
+// 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 DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_IMPL_H_
+#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_IMPL_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <base/memory/ref_counted.h>
+#include <base/memory/weak_ptr.h>
+#include <base/threading/platform_thread.h>
+#include <dbus/bus.h>
+#include <dbus/exported_object.h>
+#include <dbus/message.h>
+#include <dbus/object_path.h>
+#include <device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h>
+
+namespace bluez {
+
+// The BluetoothGattServiceServiceProvider implementation used in production.
+class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceServiceProviderImpl
+    : public BluetoothGattServiceServiceProvider {
+ public:
+  BluetoothGattServiceServiceProviderImpl(
+      dbus::Bus* bus,
+      const dbus::ObjectPath& object_path,
+      const std::string& uuid,
+      const std::vector<dbus::ObjectPath>& includes);
+
+  ~BluetoothGattServiceServiceProviderImpl() override;
+
+  // For testing.
+  BluetoothGattServiceServiceProviderImpl(const dbus::ObjectPath& object_path,
+                                          const std::string& uuid);
+
+ private:
+  // Returns true if the current thread is on the origin thread.
+  bool OnOriginThread();
+
+  // Called by dbus:: when the Bluetooth daemon fetches a single property of
+  // the service.
+  void Get(dbus::MethodCall* method_call,
+           dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when the Bluetooth daemon sets a single property of the
+  // service.
+  void Set(dbus::MethodCall* method_call,
+           dbus::ExportedObject::ResponseSender response_sender);
+
+  // Called by dbus:: when the Bluetooth daemon fetches all properties of the
+  // service.
+  void GetAll(dbus::MethodCall* method_call,
+              dbus::ExportedObject::ResponseSender response_sender);
+
+  void WriteProperties(dbus::MessageWriter* writer) override;
+
+  // Called by dbus:: when a method is exported.
+  void OnExported(const std::string& interface_name,
+                  const std::string& method_name,
+                  bool success);
+
+  const dbus::ObjectPath& object_path() const override;
+
+  // Origin thread (i.e. the UI thread in production).
+  base::PlatformThreadId origin_thread_id_;
+
+  // 128-bit service UUID of this object.
+  std::string uuid_;
+
+  // List of object paths that represent other exported GATT services that are
+  // included from this service.
+  std::vector<dbus::ObjectPath> includes_;
+
+  // D-Bus bus object is exported on, not owned by this object and must
+  // outlive it.
+  dbus::Bus* bus_;
+
+  // D-Bus object path of object we are exporting, kept so we can unregister
+  // again in our destructor.
+  dbus::ObjectPath object_path_;
+
+  // D-Bus object we are exporting, owned by this object.
+  scoped_refptr<dbus::ExportedObject> exported_object_;
+
+  // Weak pointer factory for generating 'this' pointers that might live longer
+  // than we do.
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<BluetoothGattServiceServiceProviderImpl>
+      weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceServiceProviderImpl);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_IMPL_H_
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.cc
new file mode 100644
index 0000000..a52491d
--- /dev/null
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.cc
@@ -0,0 +1,44 @@
+// 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 "device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "device/bluetooth/dbus/bluez_dbus_manager.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h"
+
+namespace bluez {
+
+FakeBluetoothGattApplicationServiceProvider::
+    FakeBluetoothGattApplicationServiceProvider(
+        const dbus::ObjectPath& object_path,
+        const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
+            services)
+    : object_path_(object_path) {
+  VLOG(1) << "Creating Bluetooth GATT service: " << object_path_.value();
+
+  FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
+      static_cast<FakeBluetoothGattManagerClient*>(
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
+  fake_bluetooth_gatt_manager_client->RegisterApplicationServiceProvider(this);
+
+  BluetoothGattApplicationServiceProvider::CreateAttributeServiceProviders(
+      nullptr, services, &service_providers_, &characteristic_providers_,
+      &descriptor_providers_);
+}
+
+FakeBluetoothGattApplicationServiceProvider::
+    ~FakeBluetoothGattApplicationServiceProvider() {
+  VLOG(1) << "Cleaning up Bluetooth GATT application: " << object_path_.value();
+
+  FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
+      static_cast<FakeBluetoothGattManagerClient*>(
+          bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
+  fake_bluetooth_gatt_manager_client->UnregisterApplicationServiceProvider(
+      this);
+}
+
+}  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h
new file mode 100644
index 0000000..4154c8b
--- /dev/null
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h
@@ -0,0 +1,60 @@
+// 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 DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_H_
+#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_H_
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "dbus/object_path.h"
+#include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h"
+
+namespace bluez {
+
+class BluetoothLocalGattCharacteristicBlueZ;
+class BluetoothLocalGattDescriptorBlueZ;
+class BluetoothLocalGattServiceBlueZ;
+
+// FakeBluetoothGattApplicationServiceProvider simulates behavior of a local
+// GATT service object and is used both in test cases in place of a mock and on
+// the Linux desktop.
+class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattApplicationServiceProvider
+    : public BluetoothGattApplicationServiceProvider {
+ public:
+  FakeBluetoothGattApplicationServiceProvider(
+      const dbus::ObjectPath& object_path,
+      const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
+          services);
+  ~FakeBluetoothGattApplicationServiceProvider() override;
+
+  const dbus::ObjectPath& object_path() const { return object_path_; }
+
+ private:
+  // D-Bus object path of the fake GATT service.
+  dbus::ObjectPath object_path_;
+
+  // List of GATT Service service providers managed by this object manager.
+  std::vector<std::unique_ptr<BluetoothGattServiceServiceProvider>>
+      service_providers_;
+  // List of GATT Characteristic service providers managed by this object
+  // manager.
+  std::vector<std::unique_ptr<BluetoothGattCharacteristicServiceProvider>>
+      characteristic_providers_;
+  // List of GATT Descriptor service providers managed by this object manager.
+  std::vector<std::unique_ptr<BluetoothGattDescriptorServiceProvider>>
+      descriptor_providers_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattApplicationServiceProvider);
+};
+
+}  // namespace bluez
+
+#endif  // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_APPLICATION_SERVICE_PROVIDER_H_
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
index 4e60936..d30a9e0 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc
@@ -4,6 +4,7 @@
 
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
 
+#include "base/callback.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
@@ -14,7 +15,7 @@
 FakeBluetoothGattCharacteristicServiceProvider::
     FakeBluetoothGattCharacteristicServiceProvider(
         const dbus::ObjectPath& object_path,
-        Delegate* delegate,
+        std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
         const std::string& uuid,
         const std::vector<std::string>& flags,
         const std::vector<std::string>& permissions,
@@ -22,7 +23,7 @@
     : object_path_(object_path),
       uuid_(uuid),
       service_path_(service_path),
-      delegate_(delegate) {
+      delegate_(std::move(delegate)) {
   VLOG(1) << "Creating Bluetooth GATT characteristic: " << object_path_.value();
 
   DCHECK(object_path_.IsValid());
@@ -33,7 +34,6 @@
                           base::CompareCase::SENSITIVE));
 
   // TODO(armansito): Do something with |flags| and |permissions|.
-
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
           bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
@@ -45,7 +45,6 @@
     ~FakeBluetoothGattCharacteristicServiceProvider() {
   VLOG(1) << "Cleaning up Bluetooth GATT characteristic: "
           << object_path_.value();
-
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
           bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient());
@@ -60,11 +59,11 @@
 }
 
 void FakeBluetoothGattCharacteristicServiceProvider::GetValue(
-    const Delegate::ValueCallback& callback,
-    const Delegate::ErrorCallback& error_callback) {
+    const device::BluetoothLocalGattService::Delegate::ValueCallback& callback,
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
   VLOG(1) << "GATT characteristic value Get request: " << object_path_.value()
           << " UUID: " << uuid_;
-
   // Check if this characteristic is registered.
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
@@ -77,16 +76,16 @@
 
   // Pass on to the delegate.
   DCHECK(delegate_);
-  delegate_->GetCharacteristicValue(callback, error_callback);
+  delegate_->GetValue(callback, error_callback);
 }
 
 void FakeBluetoothGattCharacteristicServiceProvider::SetValue(
     const std::vector<uint8_t>& value,
     const base::Closure& callback,
-    const Delegate::ErrorCallback& error_callback) {
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
   VLOG(1) << "GATT characteristic value Set request: " << object_path_.value()
           << " UUID: " << uuid_;
-
   // Check if this characteristic is registered.
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
@@ -99,7 +98,12 @@
 
   // Pass on to the delegate.
   DCHECK(delegate_);
-  delegate_->SetCharacteristicValue(value, callback, error_callback);
+  delegate_->SetValue(value, callback, error_callback);
+}
+
+const dbus::ObjectPath&
+FakeBluetoothGattCharacteristicServiceProvider::object_path() const {
+  return object_path_;
 }
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
index 4d70234..677b20a 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
@@ -6,13 +6,15 @@
 #define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_
 
 #include <stdint.h>
-
 #include <string>
 #include <vector>
 
+#include "base/callback_forward.h"
 #include "base/macros.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/bluetooth_local_gatt_service.h"
+#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h"
 
 namespace bluez {
@@ -25,7 +27,7 @@
  public:
   FakeBluetoothGattCharacteristicServiceProvider(
       const dbus::ObjectPath& object_path,
-      Delegate* delegate,
+      std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
       const std::string& uuid,
       const std::vector<std::string>& flags,
       const std::vector<std::string>& permissions,
@@ -38,13 +40,18 @@
   // Methods to simulate value get/set requests issued from a remote device. The
   // methods do nothing, if the associated service was not registered with the
   // GATT manager.
-  void GetValue(const Delegate::ValueCallback& callback,
-                const Delegate::ErrorCallback& error_callback);
-  void SetValue(const std::vector<uint8_t>& value,
-                const base::Closure& callback,
-                const Delegate::ErrorCallback& error_callback);
+  void GetValue(
+      const device::BluetoothLocalGattService::Delegate::ValueCallback&
+          callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback);
+  void SetValue(
+      const std::vector<uint8_t>& value,
+      const base::Closure& callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback);
 
-  const dbus::ObjectPath& object_path() const { return object_path_; }
+  const dbus::ObjectPath& object_path() const override;
   const std::string& uuid() const { return uuid_; }
   const dbus::ObjectPath& service_path() const { return service_path_; }
 
@@ -59,7 +66,7 @@
   dbus::ObjectPath service_path_;
 
   // The delegate that method calls are passed on to.
-  Delegate* delegate_;
+  std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattCharacteristicServiceProvider);
 };
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc
index 434e97ff..88922dc5 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc
@@ -4,8 +4,14 @@
 
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
 
+#include <vector>
+
 #include "base/bind.h"
+#include "base/callback.h"
+#include "base/callback_forward.h"
 #include "base/logging.h"
+#include "dbus/bus.h"
+#include "dbus/property.h"
 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
index 78a504e..97f9882 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc
@@ -4,6 +4,7 @@
 
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
 
+#include "base/callback.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
@@ -15,14 +16,14 @@
 FakeBluetoothGattDescriptorServiceProvider::
     FakeBluetoothGattDescriptorServiceProvider(
         const dbus::ObjectPath& object_path,
-        Delegate* delegate,
+        std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
         const std::string& uuid,
         const std::vector<std::string>& permissions,
         const dbus::ObjectPath& characteristic_path)
     : object_path_(object_path),
       uuid_(uuid),
       characteristic_path_(characteristic_path),
-      delegate_(delegate) {
+      delegate_(std::move(delegate)) {
   VLOG(1) << "Creating Bluetooth GATT descriptor: " << object_path_.value();
 
   DCHECK(object_path_.IsValid());
@@ -32,7 +33,6 @@
   DCHECK(base::StartsWith(object_path_.value(),
                           characteristic_path_.value() + "/",
                           base::CompareCase::SENSITIVE));
-
   // TODO(armansito): Do something with |permissions|.
 
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
@@ -58,11 +58,11 @@
 }
 
 void FakeBluetoothGattDescriptorServiceProvider::GetValue(
-    const Delegate::ValueCallback& callback,
-    const Delegate::ErrorCallback& error_callback) {
+    const device::BluetoothLocalGattService::Delegate::ValueCallback& callback,
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
   VLOG(1) << "GATT descriptor value Get request: " << object_path_.value()
           << " UUID: " << uuid_;
-
   // Check if this descriptor is registered.
   FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client =
       static_cast<FakeBluetoothGattManagerClient*>(
@@ -84,13 +84,14 @@
 
   // Pass on to the delegate.
   DCHECK(delegate_);
-  delegate_->GetDescriptorValue(callback, error_callback);
+  delegate_->GetValue(callback, error_callback);
 }
 
 void FakeBluetoothGattDescriptorServiceProvider::SetValue(
     const std::vector<uint8_t>& value,
     const base::Closure& callback,
-    const Delegate::ErrorCallback& error_callback) {
+    const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+        error_callback) {
   VLOG(1) << "GATT descriptor value Set request: " << object_path_.value()
           << " UUID: " << uuid_;
 
@@ -115,7 +116,12 @@
 
   // Pass on to the delegate.
   DCHECK(delegate_);
-  delegate_->SetDescriptorValue(value, callback, error_callback);
+  delegate_->SetValue(value, callback, error_callback);
+}
+
+const dbus::ObjectPath&
+FakeBluetoothGattDescriptorServiceProvider::object_path() const {
+  return object_path_;
 }
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
index ee82bcd4..ef0d54e 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
@@ -6,13 +6,15 @@
 #define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_
 
 #include <stdint.h>
-
 #include <string>
 #include <vector>
 
+#include "base/callback_forward.h"
 #include "base/macros.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_export.h"
+#include "device/bluetooth/bluetooth_local_gatt_service.h"
+#include "device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h"
 #include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h"
 
 namespace bluez {
@@ -25,7 +27,7 @@
  public:
   FakeBluetoothGattDescriptorServiceProvider(
       const dbus::ObjectPath& object_path,
-      Delegate* delegate,
+      std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate,
       const std::string& uuid,
       const std::vector<std::string>& permissions,
       const dbus::ObjectPath& characteristic_path);
@@ -37,13 +39,18 @@
   // Methods to simulate value get/set requests issued from a remote device. The
   // methods do nothing, if the associated service was not registered with the
   // GATT manager.
-  void GetValue(const Delegate::ValueCallback& callback,
-                const Delegate::ErrorCallback& error_callback);
-  void SetValue(const std::vector<uint8_t>& value,
-                const base::Closure& callback,
-                const Delegate::ErrorCallback& error_callback);
+  void GetValue(
+      const device::BluetoothLocalGattService::Delegate::ValueCallback&
+          callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback);
+  void SetValue(
+      const std::vector<uint8_t>& value,
+      const base::Closure& callback,
+      const device::BluetoothLocalGattService::Delegate::ErrorCallback&
+          error_callback);
 
-  const dbus::ObjectPath& object_path() const { return object_path_; }
+  const dbus::ObjectPath& object_path() const override;
   const std::string& uuid() const { return uuid_; }
   const dbus::ObjectPath& characteristic_path() const {
     return characteristic_path_;
@@ -60,7 +67,7 @@
   dbus::ObjectPath characteristic_path_;
 
   // The delegate that method calls are passed on to.
-  Delegate* delegate_;
+  std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorServiceProvider);
 };
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc
index 284a17c7..7faf1657 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc
@@ -4,14 +4,90 @@
 
 #include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h"
 
+#include <set>
+#include <string>
+
+#include "base/callback.h"
 #include "base/logging.h"
-#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
-#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
-#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h"
+#include "base/strings/string_util.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace bluez {
 
+std::set<dbus::ObjectPath> FakeBluetoothGattManagerClient::FindServiceProviders(
+    dbus::ObjectPath application_path) {
+  std::set<dbus::ObjectPath> services;
+  for (const auto& service : service_map_) {
+    if (base::StartsWith(service.first.value(), application_path.value(),
+                         base::CompareCase::SENSITIVE))
+      services.insert(service.first);
+  }
+  return services;
+}
+
+std::set<dbus::ObjectPath>
+FakeBluetoothGattManagerClient::FindCharacteristicProviders(
+    dbus::ObjectPath application_path) {
+  std::set<dbus::ObjectPath> characteristics;
+  for (const auto& characteristic : characteristic_map_) {
+    if (base::StartsWith(characteristic.first.value(), application_path.value(),
+                         base::CompareCase::SENSITIVE)) {
+      characteristics.insert(characteristic.first);
+    }
+  }
+  return characteristics;
+}
+
+std::set<dbus::ObjectPath>
+FakeBluetoothGattManagerClient::FindDescriptorProviders(
+    dbus::ObjectPath application_path) {
+  std::set<dbus::ObjectPath> descriptors;
+  for (const auto& descriptor : descriptor_map_) {
+    if (base::StartsWith(descriptor.first.value(), application_path.value(),
+                         base::CompareCase::SENSITIVE)) {
+      descriptors.insert(descriptor.first);
+    }
+  }
+  return descriptors;
+}
+
+bool FakeBluetoothGattManagerClient::VerifyProviderHierarchy(
+    FakeBluetoothGattApplicationServiceProvider* application_provider) {
+  dbus::ObjectPath application_path = application_provider->object_path();
+  std::set<dbus::ObjectPath> services = FindServiceProviders(application_path);
+  std::set<dbus::ObjectPath> characteristics =
+      FindCharacteristicProviders(application_path);
+  std::set<dbus::ObjectPath> descriptors =
+      FindDescriptorProviders(application_path);
+
+  VLOG(1) << "Verifying " << services.size()
+          << " services in application: " << application_path.value();
+
+  for (const auto& descriptor : descriptors) {
+    if (characteristics.count(
+            descriptor_map_[descriptor]->characteristic_path()) != 1) {
+      return false;
+    }
+    VLOG(1) << "Descriptor " << descriptor.value()
+            << " verified, has parent characteristic ("
+            << descriptor_map_[descriptor]->characteristic_path().value()
+            << ")  in hierarchy.";
+  }
+
+  for (const auto& characteristic : characteristics) {
+    if (services.count(characteristic_map_[characteristic]->service_path()) !=
+        1) {
+      return false;
+    }
+    VLOG(1) << "Characteristic " << characteristic.value()
+            << " verified, has parent service ("
+            << characteristic_map_[characteristic]->service_path().value()
+            << ") in hierarchy.";
+  }
+
+  return true;
+}
+
 FakeBluetoothGattManagerClient::FakeBluetoothGattManagerClient() {}
 
 FakeBluetoothGattManagerClient::~FakeBluetoothGattManagerClient() {}
@@ -20,62 +96,58 @@
 void FakeBluetoothGattManagerClient::Init(dbus::Bus* bus) {}
 
 // BluetoothGattManagerClient overrides.
-void FakeBluetoothGattManagerClient::RegisterService(
-    const dbus::ObjectPath& service_path,
+void FakeBluetoothGattManagerClient::RegisterApplication(
+    const dbus::ObjectPath& application_path,
     const Options& options,
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
-  VLOG(1) << "Register GATT service: " << service_path.value();
-
-  // If a service provider wasn't created before, return error.
-  ServiceMap::iterator iter = service_map_.find(service_path);
-  if (iter == service_map_.end()) {
-    error_callback.Run(bluetooth_gatt_manager::kErrorInvalidArguments,
-                       "GATT service doesn't exist: " + service_path.value());
-    return;
-  }
-
-  // Check to see if this GATT service was already registered.
-  ServiceProvider* provider = &iter->second;
-  if (provider->first) {
-    error_callback.Run(
-        bluetooth_gatt_manager::kErrorAlreadyExists,
-        "GATT service already registered: " + service_path.value());
-    return;
-  }
-
-  // Success!
-  provider->first = true;
+  VLOG(1) << "Register GATT application: " << application_path.value();
+  ApplicationProvider* provider =
+      GetApplicationServiceProvider(application_path);
+  if (!provider || provider->second)
+    error_callback.Run(bluetooth_gatt_service::kErrorFailed, "");
+  if (!VerifyProviderHierarchy(provider->first))
+    error_callback.Run(bluetooth_gatt_service::kErrorFailed, "");
+  provider->second = true;
   callback.Run();
 }
 
-void FakeBluetoothGattManagerClient::UnregisterService(
-    const dbus::ObjectPath& service_path,
+// BluetoothGattManagerClient overrides.
+void FakeBluetoothGattManagerClient::UnregisterApplication(
+    const dbus::ObjectPath& application_path,
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
-  VLOG(1) << "Unregister GATT service: " << service_path.value();
-
-  // If a service provider wasn't created before, return error.
-  ServiceMap::iterator iter = service_map_.find(service_path);
-  if (iter == service_map_.end()) {
-    error_callback.Run(bluetooth_gatt_manager::kErrorInvalidArguments,
-                       "GATT service doesn't exist: " + service_path.value());
-    return;
-  }
-
-  // Return error if the GATT service wasn't registered before.
-  ServiceProvider* provider = &iter->second;
-  if (!provider->first) {
-    error_callback.Run(bluetooth_gatt_manager::kErrorDoesNotExist,
-                       "GATT service not registered: " + service_path.value());
-    return;
-  }
-
-  // Success!
-  provider->first = false;
+  VLOG(1) << "Unregister GATT application: " << application_path.value();
+  ApplicationProvider* provider =
+      GetApplicationServiceProvider(application_path);
+  if (!provider || !provider->second)
+    error_callback.Run(bluetooth_gatt_service::kErrorFailed, "");
+  provider->second = false;
   callback.Run();
 }
 
+void FakeBluetoothGattManagerClient::RegisterApplicationServiceProvider(
+    FakeBluetoothGattApplicationServiceProvider* provider) {
+  application_map_[provider->object_path()] =
+      std::pair<FakeBluetoothGattApplicationServiceProvider*, bool>(provider,
+                                                                    false);
+}
+
+void FakeBluetoothGattManagerClient::UnregisterApplicationServiceProvider(
+    FakeBluetoothGattApplicationServiceProvider* provider) {
+  ApplicationMap::iterator iter =
+      application_map_.find(provider->object_path());
+  if (iter != application_map_.end() && iter->second.first == provider)
+    application_map_.erase(iter);
+}
+
+FakeBluetoothGattManagerClient::ApplicationProvider*
+FakeBluetoothGattManagerClient::GetApplicationServiceProvider(
+    const dbus::ObjectPath& object_path) {
+  ApplicationMap::iterator iter = application_map_.find(object_path);
+  return (iter != application_map_.end()) ? &iter->second : nullptr;
+}
+
 void FakeBluetoothGattManagerClient::RegisterServiceServiceProvider(
     FakeBluetoothGattServiceServiceProvider* provider) {
   // Ignore, if a service provider is already registered for the object path.
@@ -85,7 +157,7 @@
             << "object path: " << provider->object_path().value();
     return;
   }
-  service_map_[provider->object_path()] = std::make_pair(false, provider);
+  service_map_[provider->object_path()] = provider;
 }
 
 void FakeBluetoothGattManagerClient::RegisterCharacteristicServiceProvider(
@@ -116,7 +188,7 @@
 void FakeBluetoothGattManagerClient::UnregisterServiceServiceProvider(
     FakeBluetoothGattServiceServiceProvider* provider) {
   ServiceMap::iterator iter = service_map_.find(provider->object_path());
-  if (iter != service_map_.end() && iter->second.second == provider)
+  if (iter != service_map_.end() && iter->second == provider)
     service_map_.erase(iter);
 }
 
@@ -136,7 +208,7 @@
   ServiceMap::const_iterator iter = service_map_.find(object_path);
   if (iter == service_map_.end())
     return NULL;
-  return iter->second.second;
+  return iter->second;
 }
 
 FakeBluetoothGattCharacteristicServiceProvider*
@@ -159,11 +231,19 @@
 }
 
 bool FakeBluetoothGattManagerClient::IsServiceRegistered(
-    const dbus::ObjectPath& object_path) const {
-  ServiceMap::const_iterator iter = service_map_.find(object_path);
-  if (iter == service_map_.end())
+    const dbus::ObjectPath& service_path) const {
+  const auto& service = service_map_.find(service_path);
+  if (service == service_map_.end())
     return false;
-  return iter->second.first;
+
+  for (const auto& application : application_map_) {
+    if (base::StartsWith(service_path.value(),
+                         application.second.first->object_path().value(),
+                         base::CompareCase::SENSITIVE)) {
+      return application.second.second;
+    }
+  }
+  return false;
 }
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
index 65082ae9..64206528 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
@@ -6,17 +6,23 @@
 #define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_
 
 #include <map>
-#include <string>
+#include <set>
 #include <utility>
 
-#include "base/callback.h"
+#include "base/callback_forward.h"
 #include "base/macros.h"
+#include "dbus/bus.h"
 #include "dbus/object_path.h"
 #include "device/bluetooth/bluetooth_export.h"
 #include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h"
+#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h"
 
 namespace bluez {
 
+class FakeBluetoothGattApplicationServiceProvider;
 class FakeBluetoothGattCharacteristicServiceProvider;
 class FakeBluetoothGattDescriptorServiceProvider;
 class FakeBluetoothGattServiceServiceProvider;
@@ -34,17 +40,19 @@
   void Init(dbus::Bus* bus) override;
 
   // BluetoothGattManagerClient overrides.
-  void RegisterService(const dbus::ObjectPath& service_path,
-                       const Options& options,
-                       const base::Closure& callback,
-                       const ErrorCallback& error_callback) override;
-  void UnregisterService(const dbus::ObjectPath& service_path,
-                         const base::Closure& callback,
-                         const ErrorCallback& error_callback) override;
+  void RegisterApplication(const dbus::ObjectPath& application_path,
+                           const Options& options,
+                           const base::Closure& callback,
+                           const ErrorCallback& error_callback) override;
+  void UnregisterApplication(const dbus::ObjectPath& application_path,
+                             const base::Closure& callback,
+                             const ErrorCallback& error_callback) override;
 
-  // Register, unregister, and retrieve pointers to service, characteristic, and
-  // descriptor service providers. Automatically called from the service
-  // provider constructor and destructors.
+  // Register, unregister, and retrieve pointers to application service
+  // providers. Automatically called from the application provider constructor
+  // and destructors.
+  void RegisterApplicationServiceProvider(
+      FakeBluetoothGattApplicationServiceProvider* provider);
   void RegisterServiceServiceProvider(
       FakeBluetoothGattServiceServiceProvider* provider);
   void RegisterCharacteristicServiceProvider(
@@ -52,6 +60,8 @@
   void RegisterDescriptorServiceProvider(
       FakeBluetoothGattDescriptorServiceProvider* provider);
 
+  void UnregisterApplicationServiceProvider(
+      FakeBluetoothGattApplicationServiceProvider* provider);
   void UnregisterServiceServiceProvider(
       FakeBluetoothGattServiceServiceProvider* provider);
   void UnregisterCharacteristicServiceProvider(
@@ -68,27 +78,46 @@
   FakeBluetoothGattDescriptorServiceProvider* GetDescriptorServiceProvider(
       const dbus::ObjectPath& object_path) const;
 
-  // Returns true, if a GATT service with object path |object_path| was
-  // registered with the GATT manager using RegisterService.
   bool IsServiceRegistered(const dbus::ObjectPath& object_path) const;
 
  private:
-  // Mappings for GATT service, characteristic, and descriptor service
-  // providers. The fake GATT manager stores references to all instances
-  // created so that they can be obtained by tests.
-  typedef std::map<dbus::ObjectPath,
-                   FakeBluetoothGattCharacteristicServiceProvider*>
-      CharacteristicMap;
-  typedef std::map<dbus::ObjectPath,
-                   FakeBluetoothGattDescriptorServiceProvider*> DescriptorMap;
+  // The boolean indicates whether this application service provider is
+  // registered or not.
+  using ApplicationProvider =
+      std::pair<FakeBluetoothGattApplicationServiceProvider*, bool>;
 
-  // The mapping for services is from object paths to pairs of boolean and
-  // service provider pointer, where the boolean denotes whether or not the
-  // service is already registered.
-  typedef std::pair<bool, FakeBluetoothGattServiceServiceProvider*>
-      ServiceProvider;
-  typedef std::map<dbus::ObjectPath, ServiceProvider> ServiceMap;
+  // Mappings for GATT application, service, characteristic, and descriptor
+  // service providers. The fake GATT manager stores references to all
+  // instances created so that they can be obtained by tests.
+  using ApplicationMap = std::map<dbus::ObjectPath, ApplicationProvider>;
+  using ServiceMap =
+      std::map<dbus::ObjectPath, FakeBluetoothGattServiceServiceProvider*>;
+  using CharacteristicMap =
+      std::map<dbus::ObjectPath,
+               FakeBluetoothGattCharacteristicServiceProvider*>;
+  using DescriptorMap =
+      std::map<dbus::ObjectPath, FakeBluetoothGattDescriptorServiceProvider*>;
 
+  // Return a pointer to the Application provider that corresponds to the object
+  // path |object_path| if it exists.
+  ApplicationProvider* GetApplicationServiceProvider(
+      const dbus::ObjectPath& object_path);
+
+  // Find attribute providers in this application.
+  std::set<dbus::ObjectPath> FindServiceProviders(
+      dbus::ObjectPath application_path);
+  std::set<dbus::ObjectPath> FindCharacteristicProviders(
+      dbus::ObjectPath application_path);
+  std::set<dbus::ObjectPath> FindDescriptorProviders(
+      dbus::ObjectPath application_path);
+
+  // Verify that the attribute hierarchy exposed by this application provider
+  // is correct. i.e., all descriptors have a characteristic, which all have a
+  // service and all the attributes are under this application's object path.
+  bool VerifyProviderHierarchy(
+      FakeBluetoothGattApplicationServiceProvider* application_provider);
+
+  ApplicationMap application_map_;
   ServiceMap service_map_;
   CharacteristicMap characteristic_map_;
   DescriptorMap descriptor_map_;
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc
index 8d724058..44fb44f 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc
@@ -34,4 +34,9 @@
   fake_bluetooth_gatt_manager_client->UnregisterServiceServiceProvider(this);
 }
 
+const dbus::ObjectPath& FakeBluetoothGattServiceServiceProvider::object_path()
+    const {
+  return object_path_;
+}
+
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
index ca8b52e0..7337a946 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
@@ -27,7 +27,7 @@
       const std::vector<dbus::ObjectPath>& includes);
   ~FakeBluetoothGattServiceServiceProvider() override;
 
-  const dbus::ObjectPath& object_path() const { return object_path_; }
+  const dbus::ObjectPath& object_path() const override;
   const std::string& uuid() const { return uuid_; }
 
  private:
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index f7c55d0..6908207f 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -115,6 +115,7 @@
             'bluetooth/bluez/bluetooth_bluez_unittest.cc',
             'bluetooth/bluez/bluetooth_gatt_bluez_unittest.cc',
             'bluetooth/bluez/bluetooth_socket_bluez_unittest.cc',
+            'bluetooth/dbus/bluetooth_gatt_application_service_provider_unittest.cc',
             'bluetooth/test/bluetooth_test_bluez.cc',
             'bluetooth/test/bluetooth_test_bluez.h',
           ],
diff --git a/device/usb/public/interfaces/OWNERS b/device/usb/public/interfaces/OWNERS
new file mode 100644
index 0000000..9e621796
--- /dev/null
+++ b/device/usb/public/interfaces/OWNERS
@@ -0,0 +1,13 @@
+# Changes to Mojo interfaces require a security review to avoid
+# introducing new sandbox escapes.
+per-file *.mojom=set noparent
+per-file *.mojom=dcheng@chromium.org
+per-file *.mojom=inferno@chromium.org
+per-file *.mojom=jln@chromium.org
+per-file *.mojom=jschuh@chromium.org
+per-file *.mojom=kenrb@chromium.org
+per-file *.mojom=mkwst@chromium.org
+per-file *.mojom=nasko@chromium.org
+per-file *.mojom=palmer@chromium.org
+per-file *.mojom=tsepez@chromium.org
+per-file *.mojom=wfh@chromium.org
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 5f267cc..b01106a0 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -102,7 +102,7 @@
           sources += win_or_mac_sources
         }
       }
-      if (enable_wifi_display) {
+      if (proprietary_codecs && enable_wifi_display) {
         wifi_display_sources = rebase_path(
                 extensions_gypi_values.extensions_browser_sources_wifi_display,
                 ".",
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index 91ec453..488da669 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -22,7 +22,7 @@
     sources = rebase_path(extensions_gypi_values.extensions_common_mojo_sources,
                           ".",
                           "//extensions")
-    if (enable_wifi_display) {
+    if (proprietary_codecs && enable_wifi_display) {
       wifi_display_sources = rebase_path(
               extensions_gypi_values.extensions_common_mojo_sources_wifi_display,
               ".",
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index ac2435cc..c081b927 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -38,7 +38,7 @@
         '<@(extensions_common_mojo_sources)',
       ],
       'conditions': [
-        ['enable_wifi_display==1', {
+        ['proprietary_codecs==1 and enable_wifi_display==1', {
           'sources': [
             '<@(extensions_common_mojo_sources_wifi_display)',
           ],
@@ -187,7 +187,7 @@
             '<@(extensions_browser_sources_linux_nonchromeos)',
           ],
         }],
-        ['enable_wifi_display == 1', {
+        ['proprietary_codecs==1 and enable_wifi_display == 1', {
           'sources': [
             '<@(extensions_browser_sources_wifi_display)',
             '<(SHARED_INTERMEDIATE_DIR)/extensions/common/mojo/wifi_display_session_service.mojom.cc',
@@ -220,8 +220,9 @@
       # Disable c4267 warnings until we fix size_t to int truncations.
       'msvs_disabled_warnings': [ 4267, ],
       'conditions': [
-        ['enable_wifi_display==1', {
+        ['proprietary_codecs==1 and enable_wifi_display==1', {
           'dependencies': [
+            '../third_party/openh264/openh264.gyp:openh264_encoder',
             '../third_party/wds/wds.gyp:libwds',
           ],
           'sources': [
diff --git a/extensions/extensions.gypi b/extensions/extensions.gypi
index 28a605f..cb13bfd8 100644
--- a/extensions/extensions.gypi
+++ b/extensions/extensions.gypi
@@ -1045,6 +1045,7 @@
     'extensions_renderer_sources_wifi_display': [
       'renderer/api/display_source/wifi_display/wifi_display_audio_encoder.cc',
       'renderer/api/display_source/wifi_display/wifi_display_audio_encoder.h',
+      'renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc',
       'renderer/api/display_source/wifi_display/wifi_display_elementary_stream_descriptor.cc',
       'renderer/api/display_source/wifi_display/wifi_display_elementary_stream_descriptor.h',
       'renderer/api/display_source/wifi_display/wifi_display_elementary_stream_info.cc',
@@ -1066,6 +1067,7 @@
       'renderer/api/display_source/wifi_display/wifi_display_transport_stream_packetizer.h',
       'renderer/api/display_source/wifi_display/wifi_display_video_encoder.cc',
       'renderer/api/display_source/wifi_display/wifi_display_video_encoder.h',
+      'renderer/api/display_source/wifi_display/wifi_display_video_encoder_svc.cc',
       'renderer/api/display_source/wifi_display/wifi_display_video_encoder_vea.cc',
     ],
     'extensions_utility_sources': [
diff --git a/extensions/extensions_tests.gyp b/extensions/extensions_tests.gyp
index e9bca65..694dd52 100644
--- a/extensions/extensions_tests.gyp
+++ b/extensions/extensions_tests.gyp
@@ -61,7 +61,7 @@
             'browser/api/webcam_private/visca_webcam_unittest.cc',
           ],
         }],
-        ['enable_wifi_display==1', {
+        ['proprietary_codecs==1 and enable_wifi_display==1', {
           'sources': [
             '<@(extensions_unittests_sources_wifi_display)',
           ],
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn
index 1b8f7d0..0c3f8ec 100644
--- a/extensions/renderer/BUILD.gn
+++ b/extensions/renderer/BUILD.gn
@@ -32,13 +32,16 @@
     "//third_party/WebKit/public:blink",
   ]
 
-  if (enable_wifi_display) {
+  if (proprietary_codecs && enable_wifi_display) {
     wifi_display_sources = rebase_path(
             extensions_gypi_values.extensions_renderer_sources_wifi_display,
             ".",
             "//extensions")
     sources += wifi_display_sources
 
-    deps += [ "//third_party/wds:libwds" ]
+    deps += [
+      "//third_party/openh264/openh264.gyp:openh264_encoder",
+      "//third_party/wds:libwds",
+    ]
   }
 }
diff --git a/extensions/renderer/api/display_source/wifi_display/DEPS b/extensions/renderer/api/display_source/wifi_display/DEPS
index c571dab4..4e30f49a 100644
--- a/extensions/renderer/api/display_source/wifi_display/DEPS
+++ b/extensions/renderer/api/display_source/wifi_display/DEPS
@@ -2,5 +2,6 @@
   # TODO(Mikhail): Consider removing when https://crbug.com/432381 is fixed.
   "+media/base",
   "+media/video",
+  "+third_party/openh264/src/codec/api",
   "+third_party/wds/src/libwds/public",
 ]
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.cc
index bc19efd..9ea450b 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.cc
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.cc
@@ -17,6 +17,15 @@
 void WiFiDisplayAudioEncoder::Create(
     const wds::AudioCodec& audio_codec,
     const AudioEncoderCallback& encoder_callback) {
+  // Create a format specific encoder.
+  switch (audio_codec.format) {
+    case wds::LPCM:
+      CreateLPCM(audio_codec, encoder_callback);
+      return;
+    default:
+      break;
+  }
+
   // Report failure.
   encoder_callback.Run(nullptr);
 }
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.h
index 2c0f6dd..51c7aa73 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.h
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.h
@@ -26,6 +26,11 @@
  protected:
   static const size_t kInvalidCodecModeValue = ~static_cast<size_t>(0u);
 
+  // A factory method that creates a new encoder instance for Linear Pulse-Code
+  // Modulation (LPCM) audio encoding.
+  static void CreateLPCM(const wds::AudioCodec& audio_codec,
+                         const AudioEncoderCallback& encoder_callback);
+
   explicit WiFiDisplayAudioEncoder(const wds::AudioCodec& audio_codec);
   ~WiFiDisplayAudioEncoder() override;
 
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc
new file mode 100644
index 0000000..4e91de2
--- /dev/null
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc
@@ -0,0 +1,237 @@
+// 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 "extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/sys_byteorder.h"
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_elementary_stream_descriptor.h"
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_elementary_stream_info.h"
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer.h"
+#include "media/base/audio_bus.h"
+#include "media/base/audio_converter.h"
+#include "media/base/audio_parameters.h"
+
+namespace extensions {
+
+namespace {
+
+using LPCMAudioStreamDescriptor =
+    WiFiDisplayElementaryStreamDescriptor::LPCMAudioStream;
+
+// This audio encoder implements Linear Pulse-Code Modulation (LPCM) audio
+// encoding.
+class WiFiDisplayAudioEncoderLPCM final
+    : public WiFiDisplayAudioEncoder,
+      private media::AudioConverter::InputCallback {
+ public:
+  enum {
+    kOutputBitsPerSample = 16,
+    kOutputBytesPerSample = kOutputBitsPerSample / 8,
+    kOutputChannels = 2
+  };
+
+  explicit WiFiDisplayAudioEncoderLPCM(const wds::AudioCodec& audio_codec);
+
+ protected:
+  ~WiFiDisplayAudioEncoderLPCM() override = default;
+
+  // WiFiDisplayMediaEncoder
+  WiFiDisplayElementaryStreamInfo CreateElementaryStreamInfo() const override;
+
+  // content::MediaStreamAudioSink
+  void OnData(const media::AudioBus& input_bus,
+              base::TimeTicks estimated_capture_time) override;
+  void OnSetFormat(const media::AudioParameters& params) override;
+
+  // media::AudioConverter::InputCallback
+  double ProvideInput(media::AudioBus* audio_bus,
+                      base::TimeDelta buffer_delay) override;
+
+  LPCMAudioStreamDescriptor::SamplingFrequency GetOutputSamplingFrequency()
+      const;
+
+ private:
+  const int output_sample_rate_;
+
+  // These members are accessed on the real-time audio time only.
+  std::unique_ptr<media::AudioConverter> converter_;
+  const media::AudioBus* current_input_bus_;
+  int64_t input_frames_in_;
+  media::AudioParameters input_params_;
+  std::unique_ptr<media::AudioBus> fifo_bus_;
+  int fifo_end_frame_;
+  int64_t fifo_frames_out_;
+};
+
+WiFiDisplayAudioEncoderLPCM::WiFiDisplayAudioEncoderLPCM(
+    const wds::AudioCodec& audio_codec)
+    : WiFiDisplayAudioEncoder(audio_codec),
+      output_sample_rate_(
+          GetOutputSamplingFrequency() ==
+                  LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_48K
+              ? 48000
+              : 44100),
+      current_input_bus_(nullptr),
+      input_frames_in_(0),
+      fifo_end_frame_(0),
+      fifo_frames_out_(0) {}
+
+WiFiDisplayElementaryStreamInfo
+WiFiDisplayAudioEncoderLPCM::CreateElementaryStreamInfo() const {
+  DCHECK(client_thread_checker_.CalledOnValidThread());
+  std::vector<WiFiDisplayElementaryStreamDescriptor> descriptors;
+  descriptors.push_back(LPCMAudioStreamDescriptor::Create(
+      GetOutputSamplingFrequency(),
+      LPCMAudioStreamDescriptor::BITS_PER_SAMPLE_16,
+      false,  // emphasis_flag
+      LPCMAudioStreamDescriptor::NUMBER_OF_CHANNELS_STEREO));
+  return WiFiDisplayElementaryStreamInfo(
+      WiFiDisplayElementaryStreamInfo::AUDIO_LPCM, std::move(descriptors));
+}
+
+// Called on real-time audio thread.
+void WiFiDisplayAudioEncoderLPCM::OnData(
+    const media::AudioBus& input_bus,
+    base::TimeTicks estimated_capture_time) {
+  DCHECK(input_params_.IsValid());
+  DCHECK_EQ(input_bus.channels(), input_params_.channels());
+  DCHECK_EQ(input_bus.frames(), input_params_.frames_per_buffer());
+  DCHECK(!estimated_capture_time.is_null());
+
+  const media::AudioBus* source_bus = &input_bus;
+
+  std::unique_ptr<media::AudioBus> converted_input_bus;
+  if (converter_) {
+    // Convert the entire input signal.
+    // Note that while the number of sample frames provided as input is always
+    // the same, the chunk size (and the size of the |converted_input_bus|
+    // here) can be variable.
+    converted_input_bus =
+        media::AudioBus::Create(kOutputChannels, converter_->ChunkSize());
+    current_input_bus_ = &input_bus;
+    converter_->Convert(converted_input_bus.get());
+    DCHECK(!current_input_bus_);
+    source_bus = converted_input_bus.get();
+  }
+
+  // Loop in order to handle frame number differences between |source_bus| and
+  // |fifo_bus_|.
+  int source_start_frame = 0;
+  do {
+    // Copy as many source frames (either raw or converted input frames) as
+    // possible to |fifo_bus_|.
+    int frame_count = std::min(source_bus->frames() - source_start_frame,
+                               fifo_bus_->frames() - fifo_end_frame_);
+    DCHECK_GT(frame_count, 0);
+    source_bus->CopyPartialFramesTo(source_start_frame, frame_count,
+                                    fifo_end_frame_, fifo_bus_.get());
+    fifo_end_frame_ += frame_count;
+    source_start_frame += frame_count;
+
+    if (fifo_end_frame_ == fifo_bus_->frames()) {
+      // There are enough frames in |fifo_bus_| for one encoded unit.
+
+      // Determine the duration of the audio signal enqueued within
+      // |converter_| and |fifo_bus_|.
+      const base::TimeDelta signal_duration_already_buffered =
+          (input_frames_in_ * base::TimeDelta::FromSeconds(1) /
+           input_params_.sample_rate()) -
+          (fifo_frames_out_ * base::TimeDelta::FromSeconds(1) /
+           output_sample_rate_);
+      DVLOG(2) << "Audio reference time adjustment: -("
+               << signal_duration_already_buffered.InMicroseconds() << " us)";
+      const base::TimeTicks capture_time_of_first_converted_sample =
+          estimated_capture_time - signal_duration_already_buffered;
+
+      // Encode frames in |fifo_bus_|.
+      std::string data;
+      int sample_count = fifo_bus_->channels() * fifo_bus_->frames();
+      data.resize(sample_count * sizeof(uint16_t));
+      uint16_t* encoded_samples =
+          reinterpret_cast<uint16_t*>(string_as_array(&data));
+      fifo_bus_->ToInterleaved(fifo_bus_->frames(), kOutputBytesPerSample,
+                               encoded_samples);
+      for (int i = 0; i < sample_count; ++i)
+        encoded_samples[i] = base::HostToNet16(encoded_samples[i]);
+      fifo_end_frame_ = 0;
+      fifo_frames_out_ += fifo_bus_->frames();
+
+      // Pass the encoded unit to the client.
+      encoded_callback_.Run(
+          std::unique_ptr<WiFiDisplayEncodedUnit>(new WiFiDisplayEncodedUnit(
+              std::move(data), capture_time_of_first_converted_sample, true)));
+    }
+  } while (source_start_frame < source_bus->frames());
+}
+
+// Called on real-time audio thread.
+void WiFiDisplayAudioEncoderLPCM::OnSetFormat(
+    const media::AudioParameters& params) {
+  if (input_params_.Equals(params))
+    return;
+  input_params_ = params;
+
+  if (output_sample_rate_ != input_params_.sample_rate()) {
+    const media::AudioParameters output_params(
+        media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+        media::CHANNEL_LAYOUT_STEREO, output_sample_rate_, kOutputBitsPerSample,
+        WiFiDisplayMediaPacketizer::LPCM::kChannelSamplesPerUnit);
+    DVLOG(2) << "Setting up audio resampling: "
+             << input_params_.sample_rate() << " Hz --> "
+             << output_sample_rate_ << " Hz";
+    converter_.reset(
+        new media::AudioConverter(input_params_, output_params, false));
+    converter_->AddInput(this);
+  } else {
+    // Do not use an AudioConverter if that is not needed in order to avoid
+    // additional copyings caused by additional intermediate audio busses
+    // needed for capturing enough samples for each encoded unit.
+    converter_.reset();
+  }
+
+  fifo_bus_ = media::AudioBus::Create(
+      kOutputChannels,
+      WiFiDisplayMediaPacketizer::LPCM::kChannelSamplesPerUnit);
+  fifo_end_frame_ = 0;
+  fifo_frames_out_ = 0;
+  input_frames_in_ = 0;
+}
+
+// Called on real-time audio thread by |converter_| invoked by |OnData|.
+double WiFiDisplayAudioEncoderLPCM::ProvideInput(media::AudioBus* audio_bus,
+                                                 base::TimeDelta buffer_delay) {
+  DCHECK(current_input_bus_);
+  current_input_bus_->CopyTo(audio_bus);
+  current_input_bus_ = nullptr;
+  return 1.0;
+}
+
+LPCMAudioStreamDescriptor::SamplingFrequency
+WiFiDisplayAudioEncoderLPCM::GetOutputSamplingFrequency() const {
+  switch (GetAudioCodecMode()) {
+    case wds::LPCM_44_1K_16B_2CH:
+      return LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_44_1K;
+    case wds::LPCM_48K_16B_2CH:
+      return LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_48K;
+    default:
+      NOTREACHED();
+      return LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_44_1K;
+  }
+}
+
+}  // namespace
+
+void WiFiDisplayAudioEncoder::CreateLPCM(
+    const wds::AudioCodec& audio_codec,
+    const AudioEncoderCallback& encoder_callback) {
+  encoder_callback.Run(
+      make_scoped_refptr(new WiFiDisplayAudioEncoderLPCM(audio_codec)));
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_encoder.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_encoder.h
index 788f3e6..d205719 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_encoder.h
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_encoder.h
@@ -14,6 +14,7 @@
 #include "base/move.h"
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_elementary_stream_info.h"
 
 namespace extensions {
 
@@ -51,6 +52,13 @@
   using EncodedUnitCallback =
       base::Callback<void(std::unique_ptr<WiFiDisplayEncodedUnit>)>;
 
+  // Creates an elementary stream info describing the stream of encoded units
+  // which this encoder generates and passes to a callback set using
+  // |SetCallbacks|. The created elementary stream info should be passed to
+  // a Wi-Fi Display media packetizer.
+  virtual WiFiDisplayElementaryStreamInfo CreateElementaryStreamInfo()
+      const = 0;
+
   // Sets callbacks for the obtained encoder instance:
   // |encoded_callback| is invoked to return the next encoded unit
   // |error_callback| is invoked to report a fatal encoder error
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc
index 2b9334a..20070fe 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.cc
@@ -31,6 +31,33 @@
     "Failed to initialize media pipeline for the session";
 }  // namespace
 
+class WiFiDisplayAudioSink {
+ public:
+  WiFiDisplayAudioSink(const blink::WebMediaStreamTrack& track,
+                       content::MediaStreamAudioSink* delegate)
+      : track_(track), delegate_(delegate), sink_added_(false) {}
+
+  ~WiFiDisplayAudioSink() { Stop(); }
+
+  void Start() {
+    DCHECK(!sink_added_);
+    sink_added_ = true;
+    delegate_->AddToAudioTrack(delegate_, track_);
+  }
+
+  void Stop() {
+    if (sink_added_) {
+      delegate_->RemoveFromAudioTrack(delegate_, track_);
+      sink_added_ = false;
+    }
+  }
+
+ private:
+  blink::WebMediaStreamTrack track_;
+  content::MediaStreamAudioSink* delegate_;
+  bool sink_added_;
+};
+
 class WiFiDisplayVideoSink : public content::MediaStreamVideoSink {
  public:
   WiFiDisplayVideoSink(
@@ -106,6 +133,12 @@
     return;  // Waiting for initialization being completed.
   }
 
+  if (!audio_track_.isNull()) {
+    audio_sink_.reset(
+        new WiFiDisplayAudioSink(audio_track_, player_->audio_sink()));
+    audio_sink_->Start();
+  }
+
   if (!video_track_.isNull()) {
     // To be called on IO thread.
     auto on_raw_video_frame = base::Bind(
@@ -129,6 +162,7 @@
 
 void WiFiDisplayMediaManager::Pause() {
   is_playing_ = false;
+  audio_sink_.reset();
   video_sink_.reset();
 }
 
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h
index bb23784e..4506ff7 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_manager.h
@@ -23,6 +23,7 @@
 }  // namespace content
 
 namespace extensions {
+class WiFiDisplayAudioSink;
 class WiFiDisplayVideoSink;
 class WiFiDisplayMediaPipeline;
 class WiFiDisplaySessionService;
@@ -75,6 +76,7 @@
   blink::WebMediaStreamTrack video_track_;
   blink::WebMediaStreamTrack audio_track_;
 
+  std::unique_ptr<WiFiDisplayAudioSink> audio_sink_;
   std::unique_ptr<WiFiDisplayVideoSink> video_sink_;
 
   content::ServiceRegistry* service_registry_;
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.cc
index 1b3d4b1..f0d6b29 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.cc
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.cc
@@ -7,13 +7,12 @@
 #include "base/logging.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/video_encode_accelerator.h"
-#include "extensions/renderer/api/display_source/wifi_display/wifi_display_elementary_stream_descriptor.h"
-#include "extensions/renderer/api/display_source/wifi_display/wifi_display_elementary_stream_info.h"
 
 namespace extensions {
 
 namespace {
 
+const char kErrorAudioEncoderError[] = "Unrepairable audio encoder error";
 const char kErrorVideoEncoderError[] = "Unrepairable video encoder error";
 const char kErrorUnableSendMedia[] = "Unable to send media";
 
@@ -73,15 +72,16 @@
 
 enum WiFiDisplayMediaPipeline::InitializationStep : unsigned {
   INITIALIZE_FIRST,
-  INITIALIZE_MEDIA_PACKETIZER = INITIALIZE_FIRST,
+  INITIALIZE_AUDIO_ENCODER = INITIALIZE_FIRST,
   INITIALIZE_VIDEO_ENCODER,
+  INITIALIZE_MEDIA_PACKETIZER,
   INITIALIZE_MEDIA_SERVICE,
   INITIALIZE_LAST = INITIALIZE_MEDIA_SERVICE
 };
 
 void WiFiDisplayMediaPipeline::Initialize(
     const InitCompletionCallback& callback) {
-  DCHECK(!video_encoder_ && !packetizer_);
+  DCHECK(!audio_encoder_ && !video_encoder_ && !packetizer_);
   OnInitialize(callback, INITIALIZE_FIRST, true);
 }
 
@@ -103,10 +103,16 @@
   }
 
   switch (current_step) {
-    case INITIALIZE_MEDIA_PACKETIZER:
-      DCHECK(!packetizer_);
-      CreateMediaPacketizer();
-      init_step_callback.Run(true);
+    case INITIALIZE_AUDIO_ENCODER:
+      DCHECK(!audio_encoder_);
+      if (type_ & wds::AudioSession) {
+        auto result_callback =
+            base::Bind(&WiFiDisplayMediaPipeline::OnAudioEncoderCreated,
+                       weak_factory_.GetWeakPtr(), init_step_callback);
+        WiFiDisplayAudioEncoder::Create(audio_codec_, result_callback);
+      } else {
+        init_step_callback.Run(true);
+      }
       break;
     case INITIALIZE_VIDEO_ENCODER:
       DCHECK(!video_encoder_);
@@ -119,6 +125,11 @@
         init_step_callback.Run(true);
       }
       break;
+    case INITIALIZE_MEDIA_PACKETIZER:
+      DCHECK(!packetizer_);
+      CreateMediaPacketizer();
+      init_step_callback.Run(true);
+      break;
     case INITIALIZE_MEDIA_SERVICE:
       service_callback_.Run(
           mojo::GetProxy(&media_service_),
@@ -131,37 +142,43 @@
 void WiFiDisplayMediaPipeline::CreateMediaPacketizer() {
   DCHECK(!packetizer_);
   std::vector<WiFiDisplayElementaryStreamInfo> stream_infos;
+
   if (type_ & wds::VideoSession) {
-    std::vector<WiFiDisplayElementaryStreamDescriptor> descriptors;
-    descriptors.emplace_back(
-        WiFiDisplayElementaryStreamDescriptor::AVCTimingAndHRD::Create());
-    stream_infos.emplace_back(WiFiDisplayElementaryStreamInfo::VIDEO_H264,
-                              std::move(descriptors));
+    DCHECK(video_encoder_);
+    stream_infos.push_back(video_encoder_->CreateElementaryStreamInfo());
   }
 
   if (type_ & wds::AudioSession) {
-    using LPCMAudioStreamDescriptor =
-        WiFiDisplayElementaryStreamDescriptor::LPCMAudioStream;
-    std::vector<WiFiDisplayElementaryStreamDescriptor> descriptors;
-    descriptors.emplace_back(
-        LPCMAudioStreamDescriptor::Create(
-            audio_codec_.modes.test(wds::LPCM_48K_16B_2CH)
-                ? LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_48K
-                : LPCMAudioStreamDescriptor::SAMPLING_FREQUENCY_44_1K,
-            LPCMAudioStreamDescriptor::BITS_PER_SAMPLE_16,
-            false,  // emphasis_flag
-            LPCMAudioStreamDescriptor::NUMBER_OF_CHANNELS_STEREO));
-    stream_infos.emplace_back(WiFiDisplayElementaryStreamInfo::AUDIO_LPCM,
-                              std::move(descriptors));
+    DCHECK(audio_encoder_);
+    stream_infos.push_back(audio_encoder_->CreateElementaryStreamInfo());
   }
 
   packetizer_.reset(new WiFiDisplayMediaPacketizer(
-      base::TimeDelta::FromMilliseconds(200),
-      std::move(stream_infos),
+      base::TimeDelta::FromMilliseconds(200), stream_infos,
       base::Bind(&WiFiDisplayMediaPipeline::OnPacketizedMediaDatagramPacket,
                  base::Unretained(this))));
 }
 
+void WiFiDisplayMediaPipeline::OnAudioEncoderCreated(
+    const InitStepCompletionCallback& callback,
+    scoped_refptr<WiFiDisplayAudioEncoder> audio_encoder) {
+  DCHECK(!audio_encoder_);
+
+  if (!audio_encoder) {
+    callback.Run(false);
+    return;
+  }
+
+  audio_encoder_ = std::move(audio_encoder);
+  auto encoded_callback =
+      base::Bind(&WiFiDisplayMediaPipeline::OnEncodedAudioUnit,
+                 weak_factory_.GetWeakPtr());
+  auto error_callback = base::Bind(error_callback_, kErrorAudioEncoderError);
+  audio_encoder_->SetCallbacks(encoded_callback, error_callback);
+
+  callback.Run(true);
+}
+
 void WiFiDisplayMediaPipeline::OnVideoEncoderCreated(
     const InitStepCompletionCallback& callback,
     scoped_refptr<WiFiDisplayVideoEncoder> video_encoder) {
@@ -193,6 +210,17 @@
       callback);
 }
 
+void WiFiDisplayMediaPipeline::OnEncodedAudioUnit(
+    std::unique_ptr<WiFiDisplayEncodedFrame> unit) {
+  DCHECK(packetizer_);
+  const unsigned stream_index = (type_ & wds::VideoSession) ? 1u : 0u;
+  if (!packetizer_->EncodeElementaryStreamUnit(stream_index, unit->bytes(),
+                                               unit->size(), unit->key_frame,
+                                               unit->pts, unit->dts, true)) {
+    DVLOG(1) << "Couldn't write audio mpegts packet";
+  }
+}
+
 void WiFiDisplayMediaPipeline::OnEncodedVideoFrame(
     std::unique_ptr<WiFiDisplayEncodedFrame> frame) {
   DCHECK(packetizer_);
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.h
index 7d9fc39..d1b9e255 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.h
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_pipeline.h
@@ -15,6 +15,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/synchronization/lock.h"
 #include "extensions/common/mojo/wifi_display_session_service.mojom.h"
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder.h"
 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer.h"
 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.h"
 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
@@ -56,6 +57,8 @@
 
   void RequestIDRPicture();
 
+  WiFiDisplayAudioEncoder* audio_sink() { return audio_encoder_.get(); }
+
  private:
   using InitStepCompletionCallback = InitCompletionCallback;
   enum InitializationStep : unsigned;
@@ -73,16 +76,21 @@
   void OnInitialize(const InitCompletionCallback& callback,
                     InitializationStep current_step,
                     bool success);
+  void OnAudioEncoderCreated(
+      const InitStepCompletionCallback& callback,
+      scoped_refptr<WiFiDisplayAudioEncoder> audio_encoder);
   void OnVideoEncoderCreated(
       const InitStepCompletionCallback& callback,
       scoped_refptr<WiFiDisplayVideoEncoder> video_encoder);
   void OnMediaServiceRegistered(const InitCompletionCallback& callback);
 
+  void OnEncodedAudioUnit(std::unique_ptr<WiFiDisplayEncodedUnit> unit);
   void OnEncodedVideoFrame(std::unique_ptr<WiFiDisplayEncodedFrame> frame);
 
   bool OnPacketizedMediaDatagramPacket(
      WiFiDisplayMediaDatagramPacket media_datagram_packet);
 
+  scoped_refptr<WiFiDisplayAudioEncoder> audio_encoder_;
   scoped_refptr<WiFiDisplayVideoEncoder> video_encoder_;
   std::unique_ptr<WiFiDisplayMediaPacketizer> packetizer_;
 
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.cc
index 70833fb..e4ca9aff 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.cc
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.cc
@@ -4,8 +4,11 @@
 
 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.h"
 
+#include "base/bind.h"
 #include "base/logging.h"
 
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_elementary_stream_descriptor.h"
+
 namespace extensions {
 
 WiFiDisplayVideoEncoder::InitParameters::InitParameters() = default;
@@ -17,6 +20,10 @@
     scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
     : media_task_runner_(std::move(media_task_runner)), send_idr_(false) {
   DCHECK(media_task_runner_);
+
+  // Add descriptors common to all H.264 video encoders.
+  descriptors_.push_back(
+      WiFiDisplayElementaryStreamDescriptor::AVCTimingAndHRD::Create());
 }
 
 WiFiDisplayVideoEncoder::~WiFiDisplayVideoEncoder() = default;
@@ -25,7 +32,28 @@
 void WiFiDisplayVideoEncoder::Create(
     const InitParameters& params,
     const VideoEncoderCallback& encoder_callback) {
-  CreateVEA(params, encoder_callback);
+  CreateVEA(params, base::Bind(&OnCreatedVEA, params, encoder_callback));
+}
+
+// static
+void WiFiDisplayVideoEncoder::OnCreatedVEA(
+    const InitParameters& params,
+    const VideoEncoderCallback& encoder_callback,
+    scoped_refptr<WiFiDisplayVideoEncoder> vea_encoder) {
+  if (vea_encoder) {
+    // An accelerated encoder was created successfully. Pass it on.
+    encoder_callback.Run(vea_encoder);
+  } else {
+    // An accelerated encoder was not created. Fall back to a software encoder.
+    CreateSVC(params, encoder_callback);
+  }
+}
+
+WiFiDisplayElementaryStreamInfo
+WiFiDisplayVideoEncoder::CreateElementaryStreamInfo() const {
+  DCHECK(client_thread_checker_.CalledOnValidThread());
+  return WiFiDisplayElementaryStreamInfo(
+      WiFiDisplayElementaryStreamInfo::VIDEO_H264, descriptors_);
 }
 
 void WiFiDisplayVideoEncoder::InsertRawVideoFrame(
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.h b/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.h
index d992d47..995920f5 100644
--- a/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.h
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.h
@@ -5,6 +5,8 @@
 #ifndef EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_VIDEO_ENCODER_H_
 #define EXTENSIONS_RENDERER_API_DISPLAY_SOURCE_WIFI_DISPLAY_WIFI_DISPLAY_VIDEO_ENCODER_H_
 
+#include <vector>
+
 #include "base/memory/shared_memory.h"
 #include "extensions/renderer/api/display_source/wifi_display/wifi_display_media_encoder.h"
 #include "media/base/video_frame.h"
@@ -13,6 +15,8 @@
 
 namespace extensions {
 
+class WiFiDisplayElementaryStreamDescriptor;
+
 using WiFiDisplayEncodedFrame = WiFiDisplayEncodedUnit;
 
 // This interface represents H.264 video encoder used by the
@@ -54,6 +58,9 @@
   static void Create(const InitParameters& params,
                      const VideoEncoderCallback& encoder_callback);
 
+  // WiFiDisplayMediaEncoder
+  WiFiDisplayElementaryStreamInfo CreateElementaryStreamInfo() const final;
+
   // Encodes the given raw frame. The resulting encoded frame is passed
   // as an |encoded_callback|'s argument which is set via 'SetCallbacks'
   // method.
@@ -65,10 +72,18 @@
   void RequestIDRPicture();
 
  protected:
+  // A factory method that creates a new encoder instance which uses OpenH264
+  // SVC encoder for encoding.
+  static void CreateSVC(const InitParameters& params,
+                        const VideoEncoderCallback& encoder_callback);
+
   // A factory method that creates a new encoder instance which uses Video
   // Encode Accelerator (VEA) for encoding.
   static void CreateVEA(const InitParameters& params,
                         const VideoEncoderCallback& encoder_callback);
+  static void OnCreatedVEA(const InitParameters& params,
+                           const VideoEncoderCallback& encoder_callback,
+                           scoped_refptr<WiFiDisplayVideoEncoder> vea_encoder);
 
   explicit WiFiDisplayVideoEncoder(
       scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
@@ -79,6 +94,7 @@
       base::TimeTicks reference_time,
       bool send_idr) = 0;
 
+  std::vector<WiFiDisplayElementaryStreamDescriptor> descriptors_;
   scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
   bool send_idr_;
 };
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder_svc.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder_svc.cc
new file mode 100644
index 0000000..3a62e90
--- /dev/null
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder_svc.cc
@@ -0,0 +1,208 @@
+// 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 <memory>
+
+#include "base/bind.h"
+#include "base/task_runner_util.h"
+#include "base/thread_task_runner_handle.h"
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_video_encoder.h"
+#include "third_party/openh264/src/codec/api/svc/codec_api.h"
+#include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
+#include "third_party/openh264/src/codec/api/svc/codec_def.h"
+
+namespace extensions {
+
+namespace {
+
+size_t CalculateLayerBitStreamLength(const SLayerBSInfo& layer_info) {
+  size_t length = 0u;
+  for (int i = 0; i < layer_info.iNalCount; ++i)
+    length += static_cast<size_t>(layer_info.pNalLengthInByte[i]);
+  return length;
+}
+
+size_t CalculateFrameBitStreamLength(const SFrameBSInfo& frame_info) {
+  size_t length = 0u;
+  for (int i = 0; i < frame_info.iLayerNum; ++i)
+    length += CalculateLayerBitStreamLength(frame_info.sLayerInfo[i]);
+  return length;
+}
+
+// This video encoder implements software H.264 video encoding using OpenH264
+// library.
+class WiFiDisplayVideoEncoderSVC final : public WiFiDisplayVideoEncoder {
+ public:
+  static void Create(const InitParameters& params,
+                     const VideoEncoderCallback& encoder_callback);
+
+ private:
+  WiFiDisplayVideoEncoderSVC(
+      scoped_refptr<base::SingleThreadTaskRunner> client_task_runner,
+      std::unique_ptr<base::Thread> media_thread);
+  ~WiFiDisplayVideoEncoderSVC() override;
+
+  scoped_refptr<WiFiDisplayVideoEncoder> InitOnMediaThread(
+      const InitParameters& params);
+  void InsertFrameOnMediaThread(scoped_refptr<media::VideoFrame> video_frame,
+                                base::TimeTicks reference_time,
+                                bool send_idr) override;
+
+  scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_;
+  std::unique_ptr<base::Thread> media_thread_;
+  ISVCEncoder* openh264_encoder_;
+  base::TimeTicks start_time_;
+};
+
+// static
+void WiFiDisplayVideoEncoderSVC::Create(
+    const InitParameters& params,
+    const VideoEncoderCallback& encoder_callback) {
+  // TODO(e_hakkinen): Use normal media thread once it is exposed to extensions
+  // and can be passed to this class.
+  std::unique_ptr<base::Thread> media_thread(
+      new base::Thread("WiFiDisplaySVCMedia"));
+  media_thread->Start();
+
+  base::PostTaskAndReplyWithResult(
+      media_thread->task_runner().get(), FROM_HERE,
+      base::Bind(
+          &WiFiDisplayVideoEncoderSVC::InitOnMediaThread,
+          make_scoped_refptr(new WiFiDisplayVideoEncoderSVC(
+              base::ThreadTaskRunnerHandle::Get(), std::move(media_thread))),
+          params),
+      encoder_callback);
+}
+
+WiFiDisplayVideoEncoderSVC::WiFiDisplayVideoEncoderSVC(
+    scoped_refptr<base::SingleThreadTaskRunner> client_task_runner,
+    std::unique_ptr<base::Thread> media_thread)
+    : WiFiDisplayVideoEncoder(media_thread->task_runner()),
+      client_task_runner_(std::move(client_task_runner)),
+      media_thread_(std::move(media_thread)),
+      openh264_encoder_(nullptr) {}
+
+WiFiDisplayVideoEncoderSVC::~WiFiDisplayVideoEncoderSVC() {
+  if (openh264_encoder_) {
+    if (int err = openh264_encoder_->Uninitialize()) {
+      DVLOG(1) << "Failed to uninit OpenH264 encoder: error=" << err;
+    }
+    WelsDestroySVCEncoder(openh264_encoder_);
+  }
+  client_task_runner_->DeleteSoon(FROM_HERE, media_thread_.release());
+}
+
+scoped_refptr<WiFiDisplayVideoEncoder>
+WiFiDisplayVideoEncoderSVC::InitOnMediaThread(const InitParameters& params) {
+  DCHECK(!openh264_encoder_);
+
+  if (int err = WelsCreateSVCEncoder(&openh264_encoder_)) {
+    DVLOG(1) << "Failed to create OpenH264 encoder: error=" << err;
+    return nullptr;
+  }
+
+  SEncParamExt svc_params;
+  if (int err = openh264_encoder_->GetDefaultParams(&svc_params)) {
+    DVLOG(1) << "Failed to get default OpenH264 parameters: error=" << err;
+    return nullptr;
+  }
+
+  svc_params.fMaxFrameRate = params.frame_rate;
+  svc_params.iPicHeight = params.frame_size.height();
+  svc_params.iPicWidth = params.frame_size.width();
+  svc_params.iTargetBitrate = params.bit_rate;
+  svc_params.iUsageType = SCREEN_CONTENT_REAL_TIME;
+  svc_params.sSpatialLayers[0].fFrameRate = svc_params.fMaxFrameRate;
+  svc_params.sSpatialLayers[0].iMaxSpatialBitrate = svc_params.iTargetBitrate;
+  svc_params.sSpatialLayers[0].iSpatialBitrate = svc_params.iTargetBitrate;
+  svc_params.sSpatialLayers[0].iVideoHeight = svc_params.iPicHeight;
+  svc_params.sSpatialLayers[0].iVideoWidth = svc_params.iPicWidth;
+
+  if (int err = openh264_encoder_->InitializeExt(&svc_params)) {
+    DVLOG(1) << "Failed to init OpenH264 encoder: error=" << err;
+    return nullptr;
+  }
+
+  int video_format = EVideoFormatType::videoFormatI420;
+  if (int err = openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT,
+                                             &video_format)) {
+    DVLOG(1) << "Failed to set data format for OpenH264 encoder: error=" << err;
+    return nullptr;
+  }
+
+  return this;
+}
+
+void WiFiDisplayVideoEncoderSVC::InsertFrameOnMediaThread(
+    scoped_refptr<media::VideoFrame> video_frame,
+    base::TimeTicks reference_time,
+    bool send_idr) {
+  DCHECK_EQ(media::PIXEL_FORMAT_I420, video_frame->format());
+
+  if (start_time_.is_null())
+    start_time_ = reference_time;
+
+  SSourcePicture picture;
+  std::memset(&picture, 0, sizeof(picture));
+  picture.iColorFormat = EVideoFormatType::videoFormatI420;
+  picture.iPicHeight = video_frame->coded_size().height();
+  picture.iPicWidth = video_frame->coded_size().width();
+  picture.uiTimeStamp = (reference_time - start_time_).InMilliseconds();
+  for (size_t plane_count = video_frame->NumPlanes(video_frame->format()),
+              plane = 0u;
+       plane < plane_count; ++plane) {
+    picture.pData[plane] = video_frame->data(plane);
+    picture.iStride[plane] = video_frame->stride(plane);
+  }
+
+  if (send_idr) {
+    if (int err = openh264_encoder_->ForceIntraFrame(true)) {
+      DVLOG(1) << "Failed to force intra frame using OpenH264 encoder: error="
+               << err;
+    }
+  }
+
+  SFrameBSInfo info;
+  std::memset(&info, 0, sizeof(info));
+  if (int err = openh264_encoder_->EncodeFrame(&picture, &info)) {
+    DVLOG(1) << "Failed to encode frame using OpenH264 encoder: error=" << err;
+    return;
+  }
+
+  if (encoded_callback_.is_null())
+    return;
+
+  switch (info.eFrameType) {
+    case EVideoFrameType::videoFrameTypeInvalid:
+    case EVideoFrameType::videoFrameTypeSkip:
+      return;
+    default:
+      break;
+  }
+
+  std::string data;
+  data.reserve(CalculateFrameBitStreamLength(info));
+
+  for (int i = 0; i < info.iLayerNum; ++i) {
+    const SLayerBSInfo& layer_info = info.sLayerInfo[i];
+    data.append(reinterpret_cast<const char*>(layer_info.pBsBuf),
+                CalculateLayerBitStreamLength(layer_info));
+  }
+
+  const bool key_frame = info.eFrameType == EVideoFrameType::videoFrameTypeIDR;
+  encoded_callback_.Run(
+      std::unique_ptr<WiFiDisplayEncodedFrame>(new WiFiDisplayEncodedFrame(
+          std::move(data), reference_time, base::TimeTicks::Now(), key_frame)));
+}
+
+}  // namespace
+
+// static
+void WiFiDisplayVideoEncoder::CreateSVC(
+    const InitParameters& params,
+    const VideoEncoderCallback& encoder_callback) {
+  WiFiDisplayVideoEncoderSVC::Create(params, encoder_callback);
+}
+
+}  // namespace extensions
diff --git a/extensions/renderer/resources/event.js b/extensions/renderer/resources/event.js
index 105f7114..2f9aa3c 100644
--- a/extensions/renderer/resources/event.js
+++ b/extensions/renderer/resources/event.js
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(robwu): Fix indentation.
+
   var exceptionHandler = require('uncaught_exception_handler');
   var eventNatives = requireNative('event_natives');
   var logging = requireNative('logging');
@@ -13,6 +15,7 @@
   // Schemas for the rule-style functions on the events API that
   // only need to be generated occasionally, so populate them lazily.
   var ruleFunctionSchemas = {
+    __proto__: null,
     // These values are set lazily:
     // addRules: {},
     // getRules: {},
@@ -35,18 +38,20 @@
   }
 
   // A map of event names to the event object that is registered to that name.
-  var attachedNamedEvents = {};
+  var attachedNamedEvents = {__proto__: null};
 
   // A map of functions that massage event arguments before they are dispatched.
   // Key is event name, value is function.
-  var eventArgumentMassagers = {};
+  var eventArgumentMassagers = {__proto__: null};
 
   // An attachment strategy for events that aren't attached to the browser.
   // This applies to events with the "unmanaged" option and events without
   // names.
-  var NullAttachmentStrategy = function(event) {
+  function NullAttachmentStrategy(event) {
     this.event_ = event;
-  };
+  }
+  $Object.setPrototypeOf(NullAttachmentStrategy.prototype, null);
+
   NullAttachmentStrategy.prototype.onAddedListener =
       function(listener) {
   };
@@ -61,9 +66,10 @@
   };
 
   // Handles adding/removing/dispatching listeners for unfiltered events.
-  var UnfilteredAttachmentStrategy = function(event) {
+  function UnfilteredAttachmentStrategy(event) {
     this.event_ = event;
-  };
+  }
+  $Object.setPrototypeOf(UnfilteredAttachmentStrategy.prototype, null);
 
   UnfilteredAttachmentStrategy.prototype.onAddedListener =
       function(listener) {
@@ -87,12 +93,14 @@
     return this.event_.listeners;
   };
 
-  var FilteredAttachmentStrategy = function(event) {
+  function FilteredAttachmentStrategy(event) {
     this.event_ = event;
-    this.listenerMap_ = {};
-  };
+    this.listenerMap_ = {__proto__: null};
+  }
+  $Object.setPrototypeOf(FilteredAttachmentStrategy.prototype, null);
 
-  FilteredAttachmentStrategy.idToEventMap = {};
+  utils.defineProperty(FilteredAttachmentStrategy, 'idToEventMap',
+      {__proto__: null});
 
   FilteredAttachmentStrategy.prototype.onAddedListener = function(listener) {
     var id = eventNatives.AttachFilteredEvent(this.event_.eventName,
@@ -131,16 +139,9 @@
   };
 
   function parseEventOptions(opt_eventOptions) {
-    function merge(dest, src) {
-      for (var k in src) {
-        if (!$Object.hasOwnProperty(dest, k)) {
-          dest[k] = src[k];
-        }
-      }
-    }
-
-    var options = $Object.assign({}, opt_eventOptions || {});
-    merge(options, {
+    return $Object.assign({
+      __proto__: null,
+    }, {
       // Event supports adding listeners with filters ("filtered events"), for
       // example as used in the webNavigation API.
       //
@@ -166,9 +167,8 @@
       // events are unmanaged, though in the latter case the browser *does*
       // interact indirectly with them via IPCs written by hand.
       unmanaged: false,
-    });
-    return options;
-  };
+    }, opt_eventOptions);
+  }
 
   // Event object.  If opt_eventName is provided, this object represents
   // the unique instance of that named event, and dispatching an event
@@ -187,8 +187,8 @@
   // If opt_webViewInstanceId exists, it is an integer uniquely identifying a
   // <webview> tag within the embedder. If it does not exist, then this is an
   // extension event rather than a <webview> event.
-  var EventImpl = function(opt_eventName, opt_argSchemas, opt_eventOptions,
-                           opt_webViewInstanceId) {
+  function EventImpl(opt_eventName, opt_argSchemas, opt_eventOptions,
+                     opt_webViewInstanceId) {
     this.eventName = opt_eventName;
     this.argSchemas = opt_argSchemas;
     this.listeners = [];
@@ -216,7 +216,8 @@
       this.attachmentStrategy = new FilteredAttachmentStrategy(this);
     else
       this.attachmentStrategy = new UnfilteredAttachmentStrategy(this);
-  };
+  }
+  $Object.setPrototypeOf(EventImpl.prototype, null);
 
   // callback is a function(args, dispatch). args are the args we receive from
   // dispatchEvent(), and dispatch is a function(args) that dispatches args to
@@ -413,12 +414,19 @@
     // data types.
     function buildArrayOfChoicesSchema(typesList) {
       return {
+        __proto__: null,
         'type': 'array',
         'items': {
-          'choices': $Array.map(typesList, function(el) {return {'$ref': el};})
+          __proto__: null,
+          'choices': $Array.map(typesList, function(el) {
+            return {
+              __proto__: null,
+              '$ref': el,
+            };
+          }),
         }
       };
-    };
+    }
 
     // Validate conditions and actions against specific schemas of this
     // event object type.
@@ -449,8 +457,7 @@
     // We remove the first parameter from the validation to give the user more
     // meaningful error messages.
     validate([this.webViewInstanceId, rules, opt_cb],
-             $Array.splice(
-                 $Array.slice(ruleFunctionSchemas.addRules.parameters), 1));
+        $Array.slice(ruleFunctionSchemas.addRules.parameters, 1));
     sendRequest(
       "events.addRules",
       [this.eventName, this.webViewInstanceId, rules,  opt_cb],
@@ -464,8 +471,7 @@
     // We remove the first parameter from the validation to give the user more
     // meaningful error messages.
     validate([this.webViewInstanceId, ruleIdentifiers, opt_cb],
-             $Array.splice(
-                 $Array.slice(ruleFunctionSchemas.removeRules.parameters), 1));
+        $Array.slice(ruleFunctionSchemas.removeRules.parameters, 1));
     sendRequest("events.removeRules",
                 [this.eventName,
                  this.webViewInstanceId,
@@ -481,8 +487,7 @@
     // We remove the first parameter from the validation to give the user more
     // meaningful error messages.
     validate([this.webViewInstanceId, ruleIdentifiers, cb],
-             $Array.splice(
-                 $Array.slice(ruleFunctionSchemas.getRules.parameters), 1));
+        $Array.slice(ruleFunctionSchemas.getRules.parameters, 1));
 
     sendRequest(
       "events.getRules",
diff --git a/extensions/renderer/resources/messaging.js b/extensions/renderer/resources/messaging.js
index afd7244e..8ca84ea 100644
--- a/extensions/renderer/resources/messaging.js
+++ b/extensions/renderer/resources/messaging.js
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 // chrome.runtime.messaging API implementation.
+// TODO(robwu): Fix this indentation.
 
   // TODO(kalman): factor requiring chrome out of here.
   var chrome = requireNative('chrome').GetChrome();
@@ -22,7 +23,7 @@
   var kNativeMessageChannel = "chrome.runtime.sendNativeMessage";
 
   // Map of port IDs to port object.
-  var ports = {};
+  var ports = {__proto__: null};
 
   // Change even to odd and vice versa, to get the other side of a given
   // channel.
@@ -34,15 +35,27 @@
     this.portId_ = portId;
     this.name = opt_name;
 
-    var portSchema = {name: 'port', $ref: 'runtime.Port'};
-    var options = {unmanaged: true};
+    // Note: Keep these schemas in sync with the documentation in runtime.json
+    var portSchema = {
+      __proto__: null,
+      name: 'port',
+      $ref: 'runtime.Port',
+    };
+    var messageSchema = {
+      __proto__: null,
+      name: 'message',
+      type: 'any',
+      optional: true,
+    };
+    var options = {
+      __proto__: null,
+      unmanaged: true,
+    };
     this.onDisconnect = new Event(null, [portSchema], options);
-    this.onMessage = new Event(
-        null,
-        [{name: 'message', type: 'any', optional: true}, portSchema],
-        options);
+    this.onMessage = new Event(null, [messageSchema, portSchema], options);
     this.onDestroy_ = null;
   }
+  $Object.setPrototypeOf(PortImpl.prototype, null);
 
   // Sends a message asynchronously to the context on the other end of this
   // port.
@@ -72,8 +85,10 @@
   };
 
   PortImpl.prototype.destroy_ = function() {
-    if (this.onDestroy_)
+    if (this.onDestroy_) {
       this.onDestroy_();
+      this.onDestroy_ = null;
+    }
     privates(this.onDisconnect).impl.destroy_();
     privates(this.onMessage).impl.destroy_();
     // TODO(robwu): Remove port lifetime management because it is completely
@@ -114,23 +129,24 @@
                                   sourceExtensionId,
                                   targetExtensionId,
                                   sourceUrl) {
-    var errorMsg = [];
-    var eventName = isSendMessage ? "runtime.onMessage" : "extension.onRequest";
+    var errorMsg;
+    var eventName = isSendMessage ? 'runtime.onMessage' : 'extension.onRequest';
     if (isSendMessage && !responseCallbackPreserved) {
-      $Array.push(errorMsg,
-          "The chrome." + eventName + " listener must return true if you " +
-          "want to send a response after the listener returns");
+      errorMsg =
+        'The chrome.' + eventName + ' listener must return true if you ' +
+        'want to send a response after the listener returns';
     } else {
-      $Array.push(errorMsg,
-          "Cannot send a response more than once per chrome." + eventName +
-          " listener per document");
+      errorMsg =
+        'Cannot send a response more than once per chrome.' + eventName +
+        ' listener per document';
     }
-    $Array.push(errorMsg, "(message was sent by extension" + sourceExtensionId);
-    if (sourceExtensionId != "" && sourceExtensionId != targetExtensionId)
-      $Array.push(errorMsg, "for extension " + targetExtensionId);
-    if (sourceUrl != "")
-      $Array.push(errorMsg, "for URL " + sourceUrl);
-    lastError.set(eventName, errorMsg.join(" ") + ").", null, chrome);
+    errorMsg += ' (message was sent by extension' + sourceExtensionId;
+    if (sourceExtensionId && sourceExtensionId !== targetExtensionId)
+      errorMsg += ' for extension ' + targetExtensionId;
+    if (sourceUrl)
+      errorMsg += ' for URL ' + sourceUrl;
+    errorMsg += ').';
+    lastError.set(eventName, errorMsg, null, chrome);
   }
 
   // Helper function for dispatchOnConnect
diff --git a/extensions/renderer/resources/utils.js b/extensions/renderer/resources/utils.js
index fd70c60..26aa5e8 100644
--- a/extensions/renderer/resources/utils.js
+++ b/extensions/renderer/resources/utils.js
@@ -64,6 +64,23 @@
 }
 
 /**
+ * Sets a property |value| on |obj| with property name |key|. Like
+ *
+ *     obj[key] = value;
+ *
+ * but without triggering setters.
+ */
+function defineProperty(obj, key, value) {
+  $Object.defineProperty(obj, key, {
+    __proto__: null,
+    configurable: true,
+    enumerable: true,
+    writable: true,
+    value: value,
+  });
+}
+
+/**
  * Takes a private class implementation |privateClass| and exposes a subset of
  * its methods |functions| and properties |properties| and |readonly| to a
  * public wrapper class that should be passed in. Within bindings code, you can
@@ -90,8 +107,7 @@
  *     properties and |readonly| are read-only properties.
  */
 function expose(publicClass, privateClass, exposed) {
-  // TODO(robwu): Fix callers and uncomment this assertion.
-  // DCHECK(!(privateClass instanceof $Object.self));
+  DCHECK(!(privateClass.prototype instanceof $Object.self));
 
   $Object.setPrototypeOf(exposed, null);
 
@@ -218,6 +234,7 @@
 exports.$set('forEach', forEach);
 exports.$set('loadTypeSchema', loadTypeSchema);
 exports.$set('lookup', lookup);
+exports.$set('defineProperty', defineProperty);
 exports.$set('expose', expose);
 exports.$set('deepCopy', deepCopy);
 exports.$set('promise', promise);
diff --git a/extensions/renderer/resources/web_request_internal_custom_bindings.js b/extensions/renderer/resources/web_request_internal_custom_bindings.js
index c78ae91..3c74a67 100644
--- a/extensions/renderer/resources/web_request_internal_custom_bindings.js
+++ b/extensions/renderer/resources/web_request_internal_custom_bindings.js
@@ -14,7 +14,7 @@
 var webRequestInternal;
 
 function GetUniqueSubEventName(eventName) {
-  return eventName + "/" + idGeneratorNatives.GetNextId();
+  return eventName + '/' + idGeneratorNatives.GetNextId();
 }
 
 // WebRequestEventImpl object. This is used for special webRequest events
@@ -44,6 +44,7 @@
                                 opt_webViewInstanceId);
   }
 }
+$Object.setPrototypeOf(WebRequestEventImpl.prototype, null);
 
 // Test if the given callback is registered for this event.
 WebRequestEventImpl.prototype.hasListener = function(cb) {
diff --git a/extensions/renderer/safe_builtins.cc b/extensions/renderer/safe_builtins.cc
index f86d92f..c079b40 100644
--- a/extensions/renderer/safe_builtins.cc
+++ b/extensions/renderer/safe_builtins.cc
@@ -76,7 +76,7 @@
     "            ['apply', 'bind', 'call']);\n"
     "saveBuiltin(Array,\n"
     "            ['concat', 'forEach', 'indexOf', 'join', 'push', 'slice',\n"
-    "             'splice', 'map', 'filter', 'unshift'],\n"
+    "             'splice', 'map', 'filter', 'unshift', 'pop', 'reverse'],\n"
     "            ['isArray']);\n"
     "saveBuiltin(String,\n"
     "            ['indexOf', 'slice', 'split', 'substr', 'toUpperCase',\n"
diff --git a/gin/BUILD.gn b/gin/BUILD.gn
index ef74101..c0adbc990 100644
--- a/gin/BUILD.gn
+++ b/gin/BUILD.gn
@@ -156,6 +156,9 @@
     "test/v8_test.cc",
     "test/v8_test.h",
   ]
+  data = [
+    "test/expect.js",
+  ]
 
   public_deps = [
     ":gin",
@@ -195,7 +198,6 @@
   data = [
     "modules/module_registry_unittests.js",
     "shell/hello_world.js",
-    "test/expect.js",
     "test/file_unittests.js",
     "test/gtest_unittests.js",
     "../OWNERS",
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h
index b3809af..fed547a 100644
--- a/gpu/command_buffer/client/client_test_helper.h
+++ b/gpu/command_buffer/client/client_test_helper.h
@@ -114,7 +114,6 @@
                void(uint32_t query, const base::Closure& callback));
   MOCK_METHOD1(CreateStreamTexture, uint32_t(uint32_t));
   MOCK_METHOD1(SetLock, void(base::Lock*));
-  MOCK_METHOD0(IsGpuChannelLost, bool());
   MOCK_METHOD0(EnsureWorkVisible, void());
   MOCK_CONST_METHOD0(GetNamespaceID, CommandBufferNamespace());
   MOCK_CONST_METHOD0(GetCommandBufferID, CommandBufferId());
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index cad26ab7..84f8ef73 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -327,15 +327,21 @@
 }
 
 void GLES2Implementation::OnGpuControlLostContext() {
-#if DCHECK_IS_ON()
   // This should never occur more than once.
-  DCHECK(!lost_context_);
-  lost_context_ = true;
-#endif
+  DCHECK(!lost_context_callback_run_);
+  lost_context_callback_run_ = true;
+  share_group_->Lose();
   if (!lost_context_callback_.is_null())
     lost_context_callback_.Run();
 }
 
+void GLES2Implementation::OnGpuControlLostContextMaybeReentrant() {
+  // Queries for lost context state should immediately reflect reality,
+  // but don't call out to clients yet to avoid them re-entering this
+  // class.
+  share_group_->Lose();
+}
+
 void GLES2Implementation::OnGpuControlErrorMessage(const char* message,
                                                    int32_t id) {
   if (!error_message_callback_.is_null())
@@ -367,7 +373,7 @@
 }
 
 void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) {
-  if (!helper_->IsContextLost())
+  if (!lost_context_callback_run_)
     callback.Run();
 }
 
@@ -4637,15 +4643,10 @@
 GLenum GLES2Implementation::GetGraphicsResetStatusKHR() {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
   GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetGraphicsResetStatusKHR()");
-  // If we can't make command buffers then the context is lost.
-  if (gpu_control_->IsGpuChannelLost())
+  // If any context (including ourselves) has seen itself become lost,
+  // then it will have told the ShareGroup, so just report its status.
+  if (share_group_->IsLost())
     return GL_UNKNOWN_CONTEXT_RESET_KHR;
-  // Otherwise, check the command buffer if it is lost.
-  if (helper_->IsContextLost()) {
-    // TODO(danakj): We could GetLastState() off the CommandBuffer and return
-    // the actual reason here if we cared to.
-    return GL_UNKNOWN_CONTEXT_RESET_KHR;
-  }
   return GL_NO_ERROR;
 }
 
@@ -5382,11 +5383,6 @@
   GPU_CLIENT_SINGLE_THREAD_CHECK();
   GPU_CLIENT_LOG("[" << GetLogPrefix() << "] EndQueryEXT("
                  << GLES2Util::GetStringQueryTarget(target) << ")");
-  // Don't do anything if the context is lost.
-  if (helper_->IsContextLost()) {
-    return;
-  }
-
   if (query_tracker_->EndQuery(target, this))
     CheckGLError();
 }
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 3cdeb014..489bf7d 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -413,6 +413,7 @@
 
   // GpuControlClient implementation.
   void OnGpuControlLostContext() final;
+  void OnGpuControlLostContextMaybeReentrant() final;
   void OnGpuControlErrorMessage(const char* message, int32_t id) final;
 
   void* GetResultBuffer();
@@ -817,9 +818,7 @@
 
   base::Callback<void(const char*, int32_t)> error_message_callback_;
   base::Closure lost_context_callback_;
-#if DCHECK_IS_ON()
-  bool lost_context_ = false;
-#endif
+  bool lost_context_callback_run_ = false;
 
   int current_trace_stack_;
 
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index e75b9b2..a088537 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -672,7 +672,7 @@
   // Sets the ProgramInfoManager. The manager will be owned
   // by the ShareGroup.
   void SetProgramInfoManager(ProgramInfoManager* manager) {
-    gl_->share_group()->set_program_info_manager(manager);
+    gl_->share_group()->SetProgramInfoManagerForTesting(manager);
   }
 
   int CheckError() {
@@ -4487,9 +4487,7 @@
   EXPECT_EQ(1, signaled_count);
 }
 
-// TODO(danakj): Re-enable after/during re-land of https://crrev.com/389947.
-// This test depends on r389947 but that CL was reverted in r389980.
-TEST_F(GLES2ImplementationTest, DISABLED_SignalSyncTokenAfterContextLoss) {
+TEST_F(GLES2ImplementationTest, SignalSyncTokenAfterContextLoss) {
   EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease()).WillOnce(Return(1));
   const uint64_t fence_sync = gl_->InsertFenceSyncCHROMIUM();
   gl_->ShallowFlushCHROMIUM();
@@ -4526,6 +4524,34 @@
   EXPECT_EQ(0, signaled_count);
 }
 
+TEST_F(GLES2ImplementationTest, ReportLoss) {
+  GpuControlClient* gl_as_client = gl_;
+  int lost_count = 0;
+  gl_->SetLostContextCallback(base::Bind(&CountCallback, &lost_count));
+  EXPECT_EQ(0, lost_count);
+
+  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
+  gl_as_client->OnGpuControlLostContext();
+  EXPECT_NE(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
+  // The lost context callback should be run when GLES2Implementation is
+  // notified of the loss.
+  EXPECT_EQ(1, lost_count);
+}
+
+TEST_F(GLES2ImplementationTest, ReportLossReentrant) {
+  GpuControlClient* gl_as_client = gl_;
+  int lost_count = 0;
+  gl_->SetLostContextCallback(base::Bind(&CountCallback, &lost_count));
+  EXPECT_EQ(0, lost_count);
+
+  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
+  gl_as_client->OnGpuControlLostContextMaybeReentrant();
+  EXPECT_NE(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
+  // The lost context callback should not be run yet to avoid calling back into
+  // clients re-entrantly, and having them re-enter GLES2Implementation.
+  EXPECT_EQ(0, lost_count);
+}
+
 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
   ContextInitOptions init_options;
   init_options.lose_context_when_out_of_memory = true;
diff --git a/gpu/command_buffer/client/gpu_control.h b/gpu/command_buffer/client/gpu_control.h
index 7baf62c..813d5630 100644
--- a/gpu/command_buffer/client/gpu_control.h
+++ b/gpu/command_buffer/client/gpu_control.h
@@ -69,10 +69,6 @@
   // may not be supported with all implementations.
   virtual void SetLock(base::Lock*) = 0;
 
-  // Returns true if the channel to the Gpu is lost. When true, all contexts
-  // should be considered as lost.
-  virtual bool IsGpuChannelLost() = 0;
-
   // When this function returns it ensures all previously flushed work is
   // visible by the service. This command does this by sending a synchronous
   // IPC. Note just because the work is visible to the server does not mean
diff --git a/gpu/command_buffer/client/gpu_control_client.h b/gpu/command_buffer/client/gpu_control_client.h
index aaee9b1..75d84ec 100644
--- a/gpu/command_buffer/client/gpu_control_client.h
+++ b/gpu/command_buffer/client/gpu_control_client.h
@@ -11,7 +11,16 @@
 
 class GpuControlClient {
  public:
+  // Informs the client that the context was lost. It should inform its own
+  // clients or take actions as needed. This will only be called a single time
+  // for any GpuControl.
   virtual void OnGpuControlLostContext() = 0;
+  // This may happen inside calls from the client to the GpuControl, so this
+  // function is reentrant. It informs the client of loss, but the client will
+  // also receive a OnGpuControlLostContext (non-re-entrantly) in the future.
+  // Use this only to update internal state if needed to make lost context be
+  // visible immediately while unwinding the call stack.
+  virtual void OnGpuControlLostContextMaybeReentrant() = 0;
   virtual void OnGpuControlErrorMessage(const char* message, int32_t id) = 0;
 };
 
diff --git a/gpu/command_buffer/client/query_tracker.cc b/gpu/command_buffer/client/query_tracker.cc
index bf71645..4e241d6 100644
--- a/gpu/command_buffer/client/query_tracker.cc
+++ b/gpu/command_buffer/client/query_tracker.cc
@@ -175,9 +175,17 @@
 bool QueryTracker::Query::CheckResultsAvailable(
     CommandBufferHelper* helper) {
   if (Pending()) {
-    if (base::subtle::Acquire_Load(&info_.sync->process_count) ==
-            submit_count_ ||
-        helper->IsContextLost()) {
+    bool processed_all =
+        base::subtle::Acquire_Load(&info_.sync->process_count) == submit_count_;
+    // We check lost on the command buffer itself here instead of checking the
+    // GLES2Implementation because the GLES2Implementation will not hear about
+    // the loss until we exit out of this call stack (to avoid re-entrancy), and
+    // we need be able to enter kComplete state on context loss.
+    // TODO(danakj): If GLES2Implementation can handle being notified of loss
+    // re-entrantly (without calling its clients re-entrantly), then we could
+    // call GLES2Implementation::GetGraphicsResetStatusKHR() here and remove
+    // this method from CommandBufferHelper.
+    if (processed_all || helper->IsContextLost()) {
       switch (target()) {
         case GL_COMMANDS_ISSUED_CHROMIUM:
           result_ = info_.sync->result;
diff --git a/gpu/command_buffer/client/share_group.cc b/gpu/command_buffer/client/share_group.cc
index 2ba790a..d1041c0 100644
--- a/gpu/command_buffer/client/share_group.cc
+++ b/gpu/command_buffer/client/share_group.cc
@@ -374,7 +374,17 @@
   }
 }
 
-void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
+void ShareGroup::Lose() {
+  base::AutoLock hold(lost_lock_);
+  lost_ = true;
+}
+
+bool ShareGroup::IsLost() const {
+  base::AutoLock hold(lost_lock_);
+  return lost_;
+}
+
+void ShareGroup::SetProgramInfoManagerForTesting(ProgramInfoManager* manager) {
   program_info_manager_.reset(manager);
 }
 
diff --git a/gpu/command_buffer/client/share_group.h b/gpu/command_buffer/client/share_group.h
index 066c6e6..091b69f2 100644
--- a/gpu/command_buffer/client/share_group.h
+++ b/gpu/command_buffer/client/share_group.h
@@ -11,6 +11,7 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "base/synchronization/lock.h"
 #include "gles2_impl_export.h"
 #include "gpu/command_buffer/client/ref_counted.h"
 #include "gpu/command_buffer/common/gles2_cmd_format.h"
@@ -146,13 +147,20 @@
 
   uint64_t TracingGUID() const { return tracing_guid_; }
 
+  // Mark the ShareGroup as lost when an error occurs on any context in the
+  // group. This is thread safe as contexts may be on different threads.
+  void Lose();
+  // Report if any context in the ShareGroup has reported itself lost. This is
+  // thread safe as contexts may be on different threads.
+  bool IsLost() const;
+
  private:
   friend class gpu::RefCountedThreadSafe<ShareGroup>;
   friend class gpu::gles2::GLES2ImplementationTest;
   ~ShareGroup();
 
   // Install a new program info manager. Used for testing only;
-  void set_program_info_manager(ProgramInfoManager* manager);
+  void SetProgramInfoManagerForTesting(ProgramInfoManager* manager);
 
   std::unique_ptr<IdHandlerInterface>
       id_handlers_[id_namespaces::kNumIdNamespaces];
@@ -163,6 +171,9 @@
   bool bind_generates_resource_;
   uint64_t tracing_guid_;
 
+  mutable base::Lock lost_lock_;
+  bool lost_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(ShareGroup);
 };
 
diff --git a/gpu/command_buffer/common/BUILD.gn b/gpu/command_buffer/common/BUILD.gn
index 970b6d9..e42bb736 100644
--- a/gpu/command_buffer/common/BUILD.gn
+++ b/gpu/command_buffer/common/BUILD.gn
@@ -6,7 +6,6 @@
 # "command_buffer_common" just forwarding) and goes into a static library in
 # non-component build. This needs to match the GYP build which was likely an
 # attempt to make larger components to help with loading.
-import("//mojo/public/tools/bindings/mojom.gni")
 
 group("common") {
   if (is_component_build) {
@@ -84,13 +83,3 @@
 
   all_dependent_configs = [ "//third_party/khronos:khronos_headers" ]
 }
-
-mojom("interfaces") {
-  sources = [
-    "capabilities.mojom",
-    "command_buffer.mojom",
-    "mailbox.mojom",
-    "mailbox_holder.mojom",
-    "sync_token.mojom",
-  ]
-}
diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h
index 77232aa..68f0948 100644
--- a/gpu/command_buffer/common/constants.h
+++ b/gpu/command_buffer/common/constants.h
@@ -13,7 +13,6 @@
 typedef int32_t CommandBufferOffset;
 const CommandBufferOffset kInvalidCommandBufferOffset = -1;
 
-// This enum must stay in sync with NPDeviceContext3DError.
 namespace error {
   enum Error {
     kNoError,
diff --git a/gpu/command_buffer/common/typemaps.gni b/gpu/command_buffer/common/typemaps.gni
deleted file mode 100644
index 0d8aff9..0000000
--- a/gpu/command_buffer/common/typemaps.gni
+++ /dev/null
@@ -1,11 +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.
-
-typemaps = [
-  "//gpu/command_buffer/common/capabilities.typemap",
-  "//gpu/command_buffer/common/command_buffer.typemap",
-  "//gpu/command_buffer/common/mailbox.typemap",
-  "//gpu/command_buffer/common/mailbox_holder.typemap",
-  "//gpu/command_buffer/common/sync_token.typemap",
-]
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 94919829..e8b9c308 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -593,7 +593,8 @@
                   const std::vector<int32_t>& attribs) override;
   void Destroy(bool have_context) override;
   void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
-  void ProduceFrontBuffer(const Mailbox& mailbox) override;
+  void TakeFrontBuffer(const Mailbox& mailbox) override;
+  void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override;
   bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
   void UpdateParentTextureInfo();
   bool MakeCurrent() override;
@@ -1995,6 +1996,33 @@
   scoped_refptr<TextureRef>
       offscreen_saved_color_texture_info_;
 
+  // When a client requests ownership of the swapped front buffer, all
+  // information is saved in this structure, and |in_use| is set to true. When a
+  // client releases ownership, |in_use| is set to false.
+  //
+  // An instance of this struct, with |in_use| = false may be reused instead of
+  // making a new BackTexture.
+  struct SavedBackTexture {
+    std::unique_ptr<BackTexture> back_texture;
+    scoped_refptr<TextureRef> texture_ref;
+    bool in_use;
+  };
+  std::vector<SavedBackTexture> saved_back_textures_;
+
+  // If there's a SavedBackTexture that's not in use, takes that. Otherwise,
+  // generates a new back texture.
+  void CreateBackTexture();
+  size_t create_back_texture_count_for_test_ = 0;
+
+  // Releases all saved BackTextures that are not in use by a client.
+  void ReleaseNotInUseBackTextures();
+
+  // Releases all saved BackTextures.
+  void ReleaseAllBackTextures();
+
+  size_t GetSavedBackTextureCountForTest() override;
+  size_t GetCreatedBackTextureCountForTest() override;
+
   // The copy that is used as the destination for multi-sample resolves.
   std::unique_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
   std::unique_ptr<BackTexture> offscreen_resolved_color_texture_;
@@ -4068,6 +4096,7 @@
     offscreen_saved_color_texture_->Invalidate();
     offscreen_saved_color_texture_info_ = NULL;
   }
+  ReleaseAllBackTextures();
   if (have_context) {
     if (copy_texture_CHROMIUM_.get()) {
       copy_texture_CHROMIUM_->Destroy();
@@ -4206,11 +4235,12 @@
   RestoreCurrentFramebufferBindings();
 }
 
-void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
+void GLES2DecoderImpl::TakeFrontBuffer(const Mailbox& mailbox) {
   if (!offscreen_saved_color_texture_.get()) {
-    LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
+    DLOG(ERROR) << "Called TakeFrontBuffer on a non-offscreen context";
     return;
   }
+
   if (!offscreen_saved_color_texture_info_.get()) {
     GLuint service_id = offscreen_saved_color_texture_->id();
     offscreen_saved_color_texture_info_ = TextureRef::Create(
@@ -4219,8 +4249,92 @@
                                  GL_TEXTURE_2D);
     UpdateParentTextureInfo();
   }
+
   mailbox_manager()->ProduceTexture(
       mailbox, offscreen_saved_color_texture_info_->texture());
+
+  // Save the BackTexture and TextureRef.
+  SavedBackTexture save;
+  save.back_texture.swap(offscreen_saved_color_texture_);
+  save.texture_ref = offscreen_saved_color_texture_info_;
+  offscreen_saved_color_texture_info_ = nullptr;
+  save.in_use = true;
+  saved_back_textures_.push_back(std::move(save));
+
+  CreateBackTexture();
+}
+
+void GLES2DecoderImpl::ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) {
+  Texture* texture = mailbox_manager()->ConsumeTexture(mailbox);
+  for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end();
+       ++it) {
+    if (texture != it->texture_ref->texture())
+      continue;
+
+    if (is_lost || it->back_texture->size() != offscreen_size_) {
+      it->back_texture->Invalidate();
+      saved_back_textures_.erase(it);
+      return;
+    }
+
+    it->in_use = false;
+    return;
+  }
+
+  DLOG(ERROR) << "Attempting to return a frontbuffer that was not saved.";
+}
+
+void GLES2DecoderImpl::CreateBackTexture() {
+  for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end();
+       ++it) {
+    if (it->in_use)
+      continue;
+
+    if (it->back_texture->size() != offscreen_size_)
+      continue;
+    offscreen_saved_color_texture_ = std::move(it->back_texture);
+    offscreen_saved_color_texture_info_ = it->texture_ref;
+    saved_back_textures_.erase(it);
+    return;
+  }
+
+  ++create_back_texture_count_for_test_;
+  offscreen_saved_color_texture_.reset(
+      new BackTexture(memory_tracker(), &state_));
+  offscreen_saved_color_texture_->Create();
+  offscreen_saved_color_texture_->AllocateStorage(
+      offscreen_size_, offscreen_saved_color_format_, false);
+  offscreen_saved_frame_buffer_->AttachRenderTexture(
+      offscreen_saved_color_texture_.get());
+}
+
+void GLES2DecoderImpl::ReleaseNotInUseBackTextures() {
+  for (auto& saved_back_texture : saved_back_textures_) {
+    if (!saved_back_texture.in_use)
+      saved_back_texture.back_texture->Invalidate();
+  }
+
+  std::remove_if(saved_back_textures_.begin(), saved_back_textures_.end(),
+                 [](const SavedBackTexture& saved_back_texture) {
+                   return !saved_back_texture.in_use;
+                 });
+}
+
+void GLES2DecoderImpl::ReleaseAllBackTextures() {
+  for (auto& saved_back_texture : saved_back_textures_) {
+    // The texture will be destroyed by texture_ref's destructor.
+    DCHECK(saved_back_texture.texture_ref);
+    saved_back_texture.back_texture->Invalidate();
+  }
+  saved_back_textures_.clear();
+}
+
+size_t GLES2DecoderImpl::GetSavedBackTextureCountForTest() {
+  return saved_back_textures_.size();
+}
+
+size_t GLES2DecoderImpl::GetCreatedBackTextureCountForTest() {
+  return create_back_texture_count_for_test_;
 }
 
 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
@@ -12708,6 +12822,10 @@
         glFinish();
       }
 
+      // The size has changed, so none of the cached BackTextures are useful
+      // anymore.
+      ReleaseNotInUseBackTextures();
+
       // Allocate the offscreen saved color texture.
       DCHECK(offscreen_saved_color_format_);
       offscreen_saved_color_texture_->AllocateStorage(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index b689a0ca..668fbcf 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -158,7 +158,8 @@
   // Set the surface associated with the default FBO.
   virtual void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) = 0;
 
-  virtual void ProduceFrontBuffer(const Mailbox& mailbox) = 0;
+  virtual void TakeFrontBuffer(const Mailbox& mailbox) = 0;
+  virtual void ReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) = 0;
 
   // Resize an offscreen frame buffer.
   virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) = 0;
@@ -200,6 +201,8 @@
   virtual void SetIgnoreCachedStateForTest(bool ignore) = 0;
   virtual void SetForceShaderNameHashingForTest(bool force) = 0;
   virtual uint32_t GetAndClearBackbufferClearBitsForTest();
+  virtual size_t GetSavedBackTextureCountForTest() = 0;
+  virtual size_t GetCreatedBackTextureCountForTest() = 0;
 
   // Gets the QueryManager for this context.
   virtual QueryManager* GetQueryManager() = 0;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index afb8fd7..32dc5e6 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -52,7 +52,10 @@
                     const std::vector<int32_t>& attribs));
   MOCK_METHOD1(Destroy, void(bool have_context));
   MOCK_METHOD1(SetSurface, void(const scoped_refptr<gfx::GLSurface>& surface));
-  MOCK_METHOD1(ProduceFrontBuffer, void(const Mailbox& mailbox));
+  MOCK_METHOD1(TakeFrontBuffer, void(const Mailbox& mailbox));
+  MOCK_METHOD2(ReturnFrontBuffer, void(const Mailbox& mailbox, bool is_lost));
+  MOCK_METHOD0(GetSavedBackTextureCountForTest, size_t());
+  MOCK_METHOD0(GetCreatedBackTextureCountForTest, size_t());
   MOCK_METHOD1(ResizeOffscreenFrameBuffer, bool(const gfx::Size& size));
   MOCK_METHOD0(MakeCurrent, bool());
   MOCK_METHOD1(GetServiceIdForTesting, uint32_t(uint32_t client_id));
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index 2f54583..ceb8d6a 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -918,12 +918,6 @@
   NOTREACHED();
 }
 
-bool InProcessCommandBuffer::IsGpuChannelLost() {
-  // There is no such channel to lose for in-process contexts. This only
-  // makes sense for out-of-process command buffers.
-  return false;
-}
-
 void InProcessCommandBuffer::EnsureWorkVisible() {
   // This is only relevant for out-of-process command buffers.
 }
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 5d77244..a731bf1 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -116,7 +116,6 @@
                                      unsigned usage) override;
   void SignalQuery(uint32_t query_id, const base::Closure& callback) override;
   void SetLock(base::Lock*) override;
-  bool IsGpuChannelLost() override;
   void EnsureWorkVisible() override;
   CommandBufferNamespace GetNamespaceID() const override;
   CommandBufferId GetCommandBufferID() const override;
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 182e58d..f11ea71f 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -584,11 +584,6 @@
   NOTIMPLEMENTED();
 }
 
-bool GLManager::IsGpuChannelLost() {
-  NOTIMPLEMENTED();
-  return false;
-}
-
 void GLManager::EnsureWorkVisible() {
   // This is only relevant for out-of-process command buffers.
 }
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index 993472ba..a14cffe 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -136,7 +136,6 @@
                                      unsigned usage) override;
   void SignalQuery(uint32_t query, const base::Closure& callback) override;
   void SetLock(base::Lock*) override;
-  bool IsGpuChannelLost() override;
   void EnsureWorkVisible() override;
   gpu::CommandBufferNamespace GetNamespaceID() const override;
   CommandBufferId GetCommandBufferID() const override;
diff --git a/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc b/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc
index beacdfb..81298299 100644
--- a/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc
+++ b/gpu/command_buffer/tests/gl_texture_mailbox_unittest.cc
@@ -68,6 +68,29 @@
     gl2_.Destroy();
   }
 
+  // The second GL context takes and consumes a mailbox from the first GL
+  // context. Assumes that |gl1_| is current.
+  Mailbox TakeAndConsumeMailbox() {
+    glResizeCHROMIUM(10, 10, 1, true);
+    glClearColor(0, 1, 1, 1);
+    glClear(GL_COLOR_BUFFER_BIT);
+    ::gles2::GetGLContext()->SwapBuffers();
+
+    Mailbox mailbox;
+    glGenMailboxCHROMIUM(mailbox.name);
+    gl1_.decoder()->TakeFrontBuffer(mailbox);
+
+    gl2_.MakeCurrent();
+    GLuint tex;
+    glGenTextures(1, &tex);
+    glBindTexture(GL_TEXTURE_2D, tex);
+    glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
+    glDeleteTextures(1, &tex);
+    glFlush();
+    gl1_.MakeCurrent();
+    return mailbox;
+  }
+
   GLManager gl1_;
   GLManager gl2_;
 };
@@ -327,13 +350,17 @@
   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
 }
 
-TEST_F(GLTextureMailboxTest, ProduceFrontBuffer) {
+TEST_F(GLTextureMailboxTest, TakeFrontBuffer) {
   gl1_.MakeCurrent();
   Mailbox mailbox;
   glGenMailboxCHROMIUM(mailbox.name);
 
   gl2_.MakeCurrent();
-  gl2_.decoder()->ProduceFrontBuffer(mailbox);
+  glResizeCHROMIUM(10, 10, 1, true);
+  glClearColor(0, 1, 1, 1);
+  glClear(GL_COLOR_BUFFER_BIT);
+  ::gles2::GetGLContext()->SwapBuffers();
+  gl2_.decoder()->TakeFrontBuffer(mailbox);
 
   gl1_.MakeCurrent();
   GLuint tex1;
@@ -341,41 +368,85 @@
   glBindTexture(GL_TEXTURE_2D, tex1);
   glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+  EXPECT_EQ(0xFFFFFF00u, ReadTexel(tex1, 0, 0));
 
   gl2_.MakeCurrent();
-  glResizeCHROMIUM(10, 10, 1, true);
   glClearColor(1, 0, 0, 1);
   glClear(GL_COLOR_BUFFER_BIT);
   ::gles2::GetGLContext()->SwapBuffers();
 
   gl1_.MakeCurrent();
-  EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
-  EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 9, 9));
-  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+  EXPECT_EQ(0xFFFFFF00u, ReadTexel(tex1, 0, 0));
+
+  glDeleteTextures(1, &tex1);
+
+  Mailbox mailbox2;
+  glGenMailboxCHROMIUM(mailbox2.name);
 
   gl2_.MakeCurrent();
+  gl2_.decoder()->ReturnFrontBuffer(mailbox, false);
+
+  // Flushing doesn't matter, only SwapBuffers().
   glClearColor(0, 1, 0, 1);
   glClear(GL_COLOR_BUFFER_BIT);
   glFlush();
 
+  gl2_.decoder()->TakeFrontBuffer(mailbox2);
+
   gl1_.MakeCurrent();
+  glGenTextures(1, &tex1);
+  glBindTexture(GL_TEXTURE_2D, tex1);
+  glConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox2.name);
+  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
 
   gl2_.MakeCurrent();
-  ::gles2::GetGLContext()->SwapBuffers();
-
-  gl1_.MakeCurrent();
-  EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
-
-  gl2_.MakeCurrent();
   gl2_.Destroy();
 
   gl1_.MakeCurrent();
-  EXPECT_EQ(0xFF00FF00u, ReadTexel(tex1, 0, 0));
+  EXPECT_EQ(0xFF0000FFu, ReadTexel(tex1, 0, 0));
   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
   glDeleteTextures(1, &tex1);
 }
 
+// The client, represented by |gl2_|, will request 5 frontbuffers, and then
+// start returning them.
+TEST_F(GLTextureMailboxTest, FrontBufferCache) {
+  gl1_.MakeCurrent();
+
+  std::vector<Mailbox> mailboxes;
+  for (int i = 0; i < 5; ++i) {
+    Mailbox mailbox = TakeAndConsumeMailbox();
+    mailboxes.push_back(mailbox);
+  }
+  EXPECT_EQ(5u, gl1_.decoder()->GetSavedBackTextureCountForTest());
+  EXPECT_EQ(5u, gl1_.decoder()->GetCreatedBackTextureCountForTest());
+
+  // If the textures aren't lost, they're reused.
+  for (int i = 0; i < 100; ++i) {
+    gl1_.decoder()->ReturnFrontBuffer(mailboxes[0], false);
+    mailboxes.erase(mailboxes.begin());
+
+    Mailbox mailbox = TakeAndConsumeMailbox();
+    mailboxes.push_back(mailbox);
+  }
+
+  EXPECT_EQ(5u, gl1_.decoder()->GetSavedBackTextureCountForTest());
+  EXPECT_EQ(5u, gl1_.decoder()->GetCreatedBackTextureCountForTest());
+
+  // If the textures are lost, they're not reused.
+  for (int i = 0; i < 100; ++i) {
+    gl1_.decoder()->ReturnFrontBuffer(mailboxes[0], true);
+    mailboxes.erase(mailboxes.begin());
+
+    Mailbox mailbox = TakeAndConsumeMailbox();
+    mailboxes.push_back(mailbox);
+  }
+
+  EXPECT_EQ(5u, gl1_.decoder()->GetSavedBackTextureCountForTest());
+  EXPECT_EQ(105u, gl1_.decoder()->GetCreatedBackTextureCountForTest());
+}
+
 TEST_F(GLTextureMailboxTest, ProduceTextureDirectInvalidTarget) {
   gl1_.MakeCurrent();
 
@@ -402,7 +473,7 @@
 
 // http://crbug.com/281565
 #if !defined(OS_ANDROID)
-TEST_F(GLTextureMailboxTest, ProduceFrontBufferMultipleContexts) {
+TEST_F(GLTextureMailboxTest, TakeFrontBufferMultipleContexts) {
   gl1_.MakeCurrent();
   Mailbox mailbox[2];
   glGenMailboxCHROMIUM(mailbox[0].name);
@@ -416,13 +487,16 @@
   for (size_t i = 0; i < 2; ++i) {
     other_gl[i].Initialize(options);
     other_gl[i].MakeCurrent();
-    other_gl[i].decoder()->ProduceFrontBuffer(mailbox[i]);
+    glResizeCHROMIUM(10, 10, 1, true);
+    glClearColor(1 - i % 2, i % 2, 0, 1);
+    glClear(GL_COLOR_BUFFER_BIT);
+    ::gles2::GetGLContext()->SwapBuffers();
+    other_gl[i].decoder()->TakeFrontBuffer(mailbox[i]);
     // Make sure both "other gl" are in the same share group.
     if (!options.share_group_manager)
       options.share_group_manager = other_gl+i;
   }
 
-
   gl1_.MakeCurrent();
   for (size_t i = 0; i < 2; ++i) {
     glBindTexture(GL_TEXTURE_2D, tex[i]);
@@ -430,14 +504,6 @@
     EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
   }
 
-  for (size_t i = 0; i < 2; ++i) {
-    other_gl[i].MakeCurrent();
-    glResizeCHROMIUM(10, 10, 1, true);
-    glClearColor(1-i%2, i%2, 0, 1);
-    glClear(GL_COLOR_BUFFER_BIT);
-    ::gles2::GetGLContext()->SwapBuffers();
-  }
-
   gl1_.MakeCurrent();
   EXPECT_EQ(0xFF0000FFu, ReadTexel(tex[0], 0, 0));
   EXPECT_EQ(0xFF00FF00u, ReadTexel(tex[1], 9, 9));
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index db8a237..83a8a87 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -359,11 +359,6 @@
   NOTIMPLEMENTED();
 }
 
-bool Display::IsGpuChannelLost() {
-  NOTIMPLEMENTED();
-  return false;
-}
-
 void Display::EnsureWorkVisible() {
   // This is only relevant for out-of-process command buffers.
 }
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h
index 7e724fc..bb77001 100644
--- a/gpu/gles2_conform_support/egl/display.h
+++ b/gpu/gles2_conform_support/egl/display.h
@@ -93,7 +93,6 @@
                                      unsigned usage) override;
   void SignalQuery(uint32_t query, const base::Closure& callback) override;
   void SetLock(base::Lock*) override;
-  bool IsGpuChannelLost() override;
   void EnsureWorkVisible() override;
   gpu::CommandBufferNamespace GetNamespaceID() const override;
   gpu::CommandBufferId GetCommandBufferID() const override;
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc
index ddd9d005..9e95c50e 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.cc
+++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -10,6 +10,7 @@
 #include "base/callback.h"
 #include "base/logging.h"
 #include "base/memory/shared_memory.h"
+#include "base/optional.h"
 #include "base/stl_util.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/trace_event/trace_event.h"
@@ -85,8 +86,9 @@
   IPC_END_MESSAGE_MAP()
 
   if (!handled) {
-    DLOG(ERROR) << "Gpu process sent invalid message.";
-    InvalidGpuMessage();
+    LOG(ERROR) << "Gpu process sent invalid message.";
+    OnGpuAsyncMessageError(gpu::error::kInvalidGpuMessage,
+                           gpu::error::kLostContext);
   }
   return handled;
 }
@@ -99,32 +101,18 @@
   gpu::error::ContextLostReason context_lost_reason =
       gpu::error::kGpuChannelLost;
   if (shared_state_shm_ && shared_state_shm_->memory()) {
-    TryUpdateState();
     // The GPU process might have intentionally been crashed
     // (exit_on_context_lost), so try to find out the original reason.
+    TryUpdateStateDontReportError();
     if (last_state_.error == gpu::error::kLostContext)
       context_lost_reason = last_state_.context_lost_reason;
   }
-  OnDestroyed(context_lost_reason, gpu::error::kLostContext);
+  OnGpuAsyncMessageError(context_lost_reason, gpu::error::kLostContext);
 }
 
 void CommandBufferProxyImpl::OnDestroyed(gpu::error::ContextLostReason reason,
                                          gpu::error::Error error) {
-  CheckLock();
-
-  // When the client sees that the context is lost, they should delete this
-  // CommandBufferProxyImpl and create a new one.
-  last_state_.error = error;
-  last_state_.context_lost_reason = reason;
-
-  // Prevent any further messages from being sent, and ensure we only call
-  // the client for lost context a single time.
-  if (channel_) {
-    channel_->DestroyCommandBuffer(this);
-    channel_ = nullptr;
-    if (gpu_control_client_)
-      gpu_control_client_->OnGpuControlLostContext();
-  }
+  OnGpuAsyncMessageError(reason, error);
 }
 
 void CommandBufferProxyImpl::OnConsoleMessage(
@@ -152,8 +140,9 @@
 void CommandBufferProxyImpl::OnSignalAck(uint32_t id) {
   SignalTaskMap::iterator it = signal_tasks_.find(id);
   if (it == signal_tasks_.end()) {
-    DLOG(ERROR) << "Gpu process sent invalid SignalAck.";
-    InvalidGpuMessage();
+    LOG(ERROR) << "Gpu process sent invalid SignalAck.";
+    OnGpuAsyncMessageError(gpu::error::kInvalidGpuMessage,
+                           gpu::error::kLostContext);
     return;
   }
   base::Closure callback = it->second;
@@ -240,6 +229,7 @@
 }
 
 void CommandBufferProxyImpl::OrderingBarrier(int32_t put_offset) {
+  CheckLock();
   if (last_state_.error != gpu::error::kNoError)
     return;
 
@@ -297,12 +287,12 @@
     gpu::CommandBuffer::State state;
     if (Send(new GpuCommandBufferMsg_WaitForTokenInRange(route_id_, start, end,
                                                          &state)))
-      OnUpdateState(state);
+      SetStateFromSyncReply(state);
   }
   if (!InRange(start, end, last_state_.token) &&
       last_state_.error == gpu::error::kNoError) {
-    DLOG(ERROR) << "GPU state invalid after WaitForTokenInRange.";
-    InvalidGpuReply();
+    LOG(ERROR) << "GPU state invalid after WaitForTokenInRange.";
+    OnGpuSyncReplyError();
   }
 }
 
@@ -317,12 +307,12 @@
     gpu::CommandBuffer::State state;
     if (Send(new GpuCommandBufferMsg_WaitForGetOffsetInRange(route_id_, start,
                                                              end, &state)))
-      OnUpdateState(state);
+      SetStateFromSyncReply(state);
   }
   if (!InRange(start, end, last_state_.get_offset) &&
       last_state_.error == gpu::error::kNoError) {
-    DLOG(ERROR) << "GPU state invalid after WaitForGetOffsetInRange.";
-    InvalidGpuReply();
+    LOG(ERROR) << "GPU state invalid after WaitForGetOffsetInRange.";
+    OnGpuSyncReplyError();
   }
 }
 
@@ -350,14 +340,14 @@
       channel_->factory()->AllocateSharedMemory(size));
   if (!shared_memory) {
     if (last_state_.error == gpu::error::kNoError)
-      last_state_.error = gpu::error::kOutOfBounds;
+      OnClientError(gpu::error::kOutOfBounds);
     return NULL;
   }
 
   DCHECK(!shared_memory->memory());
   if (!shared_memory->Map(size)) {
     if (last_state_.error == gpu::error::kNoError)
-      last_state_.error = gpu::error::kOutOfBounds;
+      OnClientError(gpu::error::kOutOfBounds);
     return NULL;
   }
 
@@ -368,7 +358,7 @@
       channel_->ShareToGpuProcess(shared_memory->handle());
   if (!base::SharedMemory::IsHandleValid(handle)) {
     if (last_state_.error == gpu::error::kNoError)
-      last_state_.error = gpu::error::kLostContext;
+      OnClientError(gpu::error::kLostContext);
     return NULL;
   }
 
@@ -426,7 +416,7 @@
     image_fence_sync = GenerateFenceSyncRelease();
 
     // Make sure fence syncs were flushed before CreateImage() was called.
-    DCHECK_LE(image_fence_sync - 1, flushed_fence_sync_release_);
+    DCHECK_EQ(image_fence_sync, flushed_fence_sync_release_ + 1);
   }
 
   DCHECK(gpu::IsGpuMemoryBufferFormatSupported(gpu_memory_buffer->GetFormat(),
@@ -506,10 +496,6 @@
   lock_ = lock;
 }
 
-bool CommandBufferProxyImpl::IsGpuChannelLost() {
-  return !channel_ || channel_->IsLost();
-}
-
 void CommandBufferProxyImpl::EnsureWorkVisible() {
   if (channel_)
     channel_->ValidateFlushIDReachedServer(stream_id_, true);
@@ -528,14 +514,17 @@
 }
 
 uint64_t CommandBufferProxyImpl::GenerateFenceSyncRelease() {
+  CheckLock();
   return next_fence_sync_release_++;
 }
 
 bool CommandBufferProxyImpl::IsFenceSyncRelease(uint64_t release) {
+  CheckLock();
   return release != 0 && release < next_fence_sync_release_;
 }
 
 bool CommandBufferProxyImpl::IsFenceSyncFlushed(uint64_t release) {
+  CheckLock();
   return release != 0 && release <= flushed_fence_sync_release_;
 }
 
@@ -617,13 +606,23 @@
   signal_tasks_.insert(std::make_pair(signal_id, callback));
 }
 
-bool CommandBufferProxyImpl::ProduceFrontBuffer(const gpu::Mailbox& mailbox) {
+void CommandBufferProxyImpl::TakeFrontBuffer(const gpu::Mailbox& mailbox) {
   CheckLock();
   if (last_state_.error != gpu::error::kNoError)
-    return false;
+    return;
 
-  Send(new GpuCommandBufferMsg_ProduceFrontBuffer(route_id_, mailbox));
-  return true;
+  Send(new GpuCommandBufferMsg_TakeFrontBuffer(route_id_, mailbox));
+}
+
+void CommandBufferProxyImpl::ReturnFrontBuffer(const gpu::Mailbox& mailbox,
+                                               const gpu::SyncToken& sync_token,
+                                               bool is_lost) {
+  CheckLock();
+  if (last_state_.error != gpu::error::kNoError)
+    return;
+
+  Send(new GpuCommandBufferMsg_ReturnFrontBuffer(route_id_, mailbox, sync_token,
+                                                 is_lost));
 }
 
 gpu::error::Error CommandBufferProxyImpl::GetLastError() {
@@ -649,19 +648,30 @@
   // OnChannelError is called after returning to the message loop in case
   // it is referenced elsewhere.
   DVLOG(1) << "CommandBufferProxyImpl::Send failed. Losing context.";
-  last_state_.error = gpu::error::kLostContext;
+  OnClientError(gpu::error::kLostContext);
   return false;
 }
 
-void CommandBufferProxyImpl::OnUpdateState(
+void CommandBufferProxyImpl::SetStateFromSyncReply(
     const gpu::CommandBuffer::State& state) {
+  DCHECK(last_state_.error == gpu::error::kNoError);
   // Handle wraparound. It works as long as we don't have more than 2B state
   // updates in flight across which reordering occurs.
   if (state.generation - last_state_.generation < 0x80000000U)
     last_state_ = state;
+  if (last_state_.error != gpu::error::kNoError)
+    OnGpuStateError();
 }
 
 void CommandBufferProxyImpl::TryUpdateState() {
+  if (last_state_.error == gpu::error::kNoError) {
+    shared_state()->Read(&last_state_);
+    if (last_state_.error != gpu::error::kNoError)
+      OnGpuStateError();
+  }
+}
+
+void CommandBufferProxyImpl::TryUpdateStateDontReportError() {
   if (last_state_.error == gpu::error::kNoError)
     shared_state()->Read(&last_state_);
 }
@@ -702,27 +712,75 @@
     update_vsync_parameters_completion_callback_.Run(timebase, interval);
 }
 
-void CommandBufferProxyImpl::InvalidGpuMessage() {
-  LOG(ERROR) << "Received invalid message from the GPU process.";
-  OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext);
-}
-
-void CommandBufferProxyImpl::InvalidGpuReply() {
-  CheckLock();
-  LOG(ERROR) << "Received invalid reply from the GPU process.";
+void CommandBufferProxyImpl::OnGpuSyncReplyError() {
   last_state_.error = gpu::error::kLostContext;
   last_state_.context_lost_reason = gpu::error::kInvalidGpuMessage;
-  callback_thread_->PostTask(
-      FROM_HERE,
-      base::Bind(&CommandBufferProxyImpl::InvalidGpuReplyOnClientThread,
-                 weak_this_));
+  // This method may be inside a callstack from the GpuControlClient (we got a
+  // bad reply to something we are sending to the GPU process). So avoid
+  // re-entering the GpuControlClient here.
+  DisconnectChannelInFreshCallStack();
 }
 
-void CommandBufferProxyImpl::InvalidGpuReplyOnClientThread() {
-  std::unique_ptr<base::AutoLock> lock;
+void CommandBufferProxyImpl::OnGpuAsyncMessageError(
+    gpu::error::ContextLostReason reason,
+    gpu::error::Error error) {
+  CheckLock();
+  last_state_.error = error;
+  last_state_.context_lost_reason = reason;
+  // This method only occurs when receiving IPC messages, so we know it's not in
+  // a callstack from the GpuControlClient.
+  DisconnectChannel();
+}
+
+void CommandBufferProxyImpl::OnGpuStateError() {
+  DCHECK(last_state_.error != gpu::error::kNoError);
+  // This method may be inside a callstack from the GpuControlClient (we
+  // encountered an error while trying to perform some action). So avoid
+  // re-entering the GpuControlClient here.
+  DisconnectChannelInFreshCallStack();
+}
+
+void CommandBufferProxyImpl::OnClientError(gpu::error::Error error) {
+  CheckLock();
+  last_state_.error = error;
+  last_state_.context_lost_reason = gpu::error::kUnknown;
+  // This method may be inside a callstack from the GpuControlClient (we
+  // encountered an error while trying to perform some action). So avoid
+  // re-entering the GpuControlClient here.
+  DisconnectChannelInFreshCallStack();
+}
+
+void CommandBufferProxyImpl::DisconnectChannelInFreshCallStack() {
+  CheckLock();
+  // Inform the GpuControlClient of the lost state immediately, though this may
+  // be a re-entrant call to the client so we use the MaybeReentrant variant.
+  if (gpu_control_client_)
+    gpu_control_client_->OnGpuControlLostContextMaybeReentrant();
+  // Create a fresh call stack to keep the |channel_| alive while we unwind the
+  // stack in case things will use it, and give the GpuChannelClient a chance to
+  // act fully on the lost context.
+  callback_thread_->PostTask(
+      FROM_HERE, base::Bind(&CommandBufferProxyImpl::LockAndDisconnectChannel,
+                            weak_this_));
+}
+
+void CommandBufferProxyImpl::LockAndDisconnectChannel() {
+  base::Optional<base::AutoLock> hold;
   if (lock_)
-    lock.reset(new base::AutoLock(*lock_));
-  OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext);
+    hold.emplace(*lock_);
+  DisconnectChannel();
+}
+
+void CommandBufferProxyImpl::DisconnectChannel() {
+  CheckLock();
+  // Prevent any further messages from being sent, and ensure we only call
+  // the client for lost context a single time.
+  if (!channel_)
+    return;
+  channel_->DestroyCommandBuffer(this);
+  channel_ = nullptr;
+  if (gpu_control_client_)
+    gpu_control_client_->OnGpuControlLostContext();
 }
 
 }  // namespace gpu
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h
index 453d7b79..0fd2e93 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.h
+++ b/gpu/ipc/client/command_buffer_proxy_impl.h
@@ -21,6 +21,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "base/threading/thread_checker.h"
 #include "gpu/command_buffer/client/gpu_control.h"
 #include "gpu/command_buffer/common/command_buffer.h"
 #include "gpu/command_buffer/common/command_buffer_id.h"
@@ -101,7 +102,6 @@
                                      unsigned usage) override;
   void SignalQuery(uint32_t query, const base::Closure& callback) override;
   void SetLock(base::Lock* lock) override;
-  bool IsGpuChannelLost() override;
   void EnsureWorkVisible() override;
   gpu::CommandBufferNamespace GetNamespaceID() const override;
   gpu::CommandBufferId GetCommandBufferID() const override;
@@ -114,7 +114,10 @@
                        const base::Closure& callback) override;
   bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override;
 
-  bool ProduceFrontBuffer(const gpu::Mailbox& mailbox);
+  void TakeFrontBuffer(const gpu::Mailbox& mailbox);
+  void ReturnFrontBuffer(const gpu::Mailbox& mailbox,
+                         const gpu::SyncToken& sync_token,
+                         bool is_lost);
 
   void AddDeletionObserver(DeletionObserver* observer);
   void RemoveDeletionObserver(DeletionObserver* observer);
@@ -157,8 +160,11 @@
   typedef base::hash_map<uint32_t, base::Closure> SignalTaskMap;
 
   void CheckLock() {
-    if (lock_)
+    if (lock_) {
       lock_->AssertAcquired();
+    } else {
+      DCHECK(lockless_thread_checker_.CalledOnValidThread());
+    }
   }
 
   // Send an IPC message over the GPU channel. This is private to fully
@@ -167,7 +173,6 @@
   bool Send(IPC::Message* msg);
 
   // Message handlers:
-  void OnUpdateState(const gpu::CommandBuffer::State& state);
   void OnDestroyed(gpu::error::ContextLostReason reason,
                    gpu::error::Error error);
   void OnConsoleMessage(const GPUCommandBufferConsoleMessage& message);
@@ -177,26 +182,46 @@
   void OnUpdateVSyncParameters(base::TimeTicks timebase,
                                base::TimeDelta interval);
 
-  // Try to read an updated copy of the state from shared memory.
-  void TryUpdateState();
-
   // Updates the highest verified release fence sync.
   void UpdateVerifiedReleases(uint32_t verified_flush);
 
-  // Loses the context after we received an invalid message from the GPU
-  // process. Will call the lost context callback reentrantly if any.
-  void InvalidGpuMessage();
+  // Try to read an updated copy of the state from shared memory, and calls
+  // OnGpuStateError() if the new state has an error.
+  void TryUpdateState();
+  // Like the above but does not call the error event handler if the new state
+  // has an error.
+  void TryUpdateStateDontReportError();
+  // Sets the state, and calls OnGpuStateError() if the new state has an error.
+  void SetStateFromSyncReply(const gpu::CommandBuffer::State& state);
 
   // Loses the context after we received an invalid reply from the GPU
-  // process. Will post a task to call the lost context callback if any.
-  void InvalidGpuReply();
+  // process.
+  void OnGpuSyncReplyError();
 
-  void InvalidGpuReplyOnClientThread();
+  // Loses the context when receiving a message from the GPU process.
+  void OnGpuAsyncMessageError(gpu::error::ContextLostReason reason,
+                              gpu::error::Error error);
+
+  // Loses the context after we receive an error state from the GPU process.
+  void OnGpuStateError();
+
+  // Sets an error on the last_state_ and loses the context due to client-side
+  // errors.
+  void OnClientError(gpu::error::Error error);
+
+  // Helper methods, don't call these directly.
+  void DisconnectChannelInFreshCallStack();
+  void LockAndDisconnectChannel();
+  void DisconnectChannel();
 
   // The shared memory area used to update state.
   gpu::CommandBufferSharedState* shared_state() const;
 
+  // There should be a lock_ if this is going to be used across multiple
+  // threads, or we guarantee it is used by a single thread by using a thread
+  // checker if no lock_ is set.
   base::Lock* lock_;
+  base::ThreadChecker lockless_thread_checker_;
 
   // Client that wants to listen for important events on the GpuControl.
   gpu::GpuControlClient* gpu_control_client_;
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn
index 9d45e2f..7b31e89 100644
--- a/gpu/ipc/common/BUILD.gn
+++ b/gpu/ipc/common/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/ui.gni")
+import("//mojo/public/tools/bindings/mojom.gni")
 
 group("common") {
   if (is_component_build) {
@@ -114,3 +115,13 @@
     deps += [ "//ui/ozone" ]
   }
 }
+
+mojom("interfaces") {
+  sources = [
+    "capabilities.mojom",
+    "command_buffer.mojom",
+    "mailbox.mojom",
+    "mailbox_holder.mojom",
+    "sync_token.mojom",
+  ]
+}
diff --git a/gpu/command_buffer/common/capabilities.mojom b/gpu/ipc/common/capabilities.mojom
similarity index 100%
rename from gpu/command_buffer/common/capabilities.mojom
rename to gpu/ipc/common/capabilities.mojom
diff --git a/gpu/command_buffer/common/capabilities.typemap b/gpu/ipc/common/capabilities.typemap
similarity index 87%
rename from gpu/command_buffer/common/capabilities.typemap
rename to gpu/ipc/common/capabilities.typemap
index 5b574e0b..c518ba92 100644
--- a/gpu/command_buffer/common/capabilities.typemap
+++ b/gpu/ipc/common/capabilities.typemap
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-mojom = "//gpu/command_buffer/common/capabilities.mojom"
+mojom = "//gpu/ipc/common/capabilities.mojom"
 public_headers = [ "//gpu/command_buffer/common/capabilities.h" ]
 traits_headers = [ "//gpu/ipc/common/gpu_command_buffer_traits.h" ]
 deps = [
diff --git a/gpu/command_buffer/common/command_buffer.mojom b/gpu/ipc/common/command_buffer.mojom
similarity index 100%
rename from gpu/command_buffer/common/command_buffer.mojom
rename to gpu/ipc/common/command_buffer.mojom
diff --git a/gpu/command_buffer/common/command_buffer.typemap b/gpu/ipc/common/command_buffer.typemap
similarity index 87%
rename from gpu/command_buffer/common/command_buffer.typemap
rename to gpu/ipc/common/command_buffer.typemap
index 78ddbbd..154169269 100644
--- a/gpu/command_buffer/common/command_buffer.typemap
+++ b/gpu/ipc/common/command_buffer.typemap
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-mojom = "//gpu/command_buffer/common/command_buffer.mojom"
+mojom = "//gpu/ipc/common/command_buffer.mojom"
 public_headers = [ "//gpu/command_buffer/common/command_buffer.h" ]
 traits_headers = [ "//gpu/ipc/common/gpu_command_buffer_traits.h" ]
 deps = [
diff --git a/gpu/ipc/common/gpu_messages.h b/gpu/ipc/common/gpu_messages.h
index 8580054..3d658a56 100644
--- a/gpu/ipc/common/gpu_messages.h
+++ b/gpu/ipc/common/gpu_messages.h
@@ -138,11 +138,18 @@
 IPC_SYNC_MESSAGE_ROUTED1_0(GpuCommandBufferMsg_SetGetBuffer,
                            int32_t /* shm_id */)
 
-// Produces the front buffer into a mailbox. This allows another context to draw
+// Takes the front buffer into a mailbox. This allows another context to draw
 // the output of this context.
-IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_ProduceFrontBuffer,
+IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_TakeFrontBuffer,
                     gpu::Mailbox /* mailbox */)
 
+// Returns a front buffer taken with GpuCommandBufferMsg_TakeFrontBuffer. This
+// allows it to be reused.
+IPC_MESSAGE_ROUTED3(GpuCommandBufferMsg_ReturnFrontBuffer,
+                    gpu::Mailbox /* mailbox */,
+                    gpu::SyncToken /* sync_token */,
+                    bool /* is_lost */)
+
 // Wait until the token is in a specific range, inclusive.
 IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_WaitForTokenInRange,
                            int32_t /* start */,
diff --git a/gpu/command_buffer/common/mailbox.mojom b/gpu/ipc/common/mailbox.mojom
similarity index 100%
rename from gpu/command_buffer/common/mailbox.mojom
rename to gpu/ipc/common/mailbox.mojom
diff --git a/gpu/command_buffer/common/mailbox.typemap b/gpu/ipc/common/mailbox.typemap
similarity index 88%
rename from gpu/command_buffer/common/mailbox.typemap
rename to gpu/ipc/common/mailbox.typemap
index 8c6bff4..5072f0e 100644
--- a/gpu/command_buffer/common/mailbox.typemap
+++ b/gpu/ipc/common/mailbox.typemap
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-mojom = "//gpu/command_buffer/common/mailbox.mojom"
+mojom = "//gpu/ipc/common/mailbox.mojom"
 public_headers = [ "//gpu/command_buffer/common/mailbox.h" ]
 traits_headers = [ "//gpu/ipc/common/gpu_command_buffer_traits.h" ]
 deps = [
diff --git a/gpu/command_buffer/common/mailbox_holder.mojom b/gpu/ipc/common/mailbox_holder.mojom
similarity index 100%
rename from gpu/command_buffer/common/mailbox_holder.mojom
rename to gpu/ipc/common/mailbox_holder.mojom
diff --git a/gpu/command_buffer/common/mailbox_holder.typemap b/gpu/ipc/common/mailbox_holder.typemap
similarity index 87%
rename from gpu/command_buffer/common/mailbox_holder.typemap
rename to gpu/ipc/common/mailbox_holder.typemap
index 1430e4e..a0a8ee4 100644
--- a/gpu/command_buffer/common/mailbox_holder.typemap
+++ b/gpu/ipc/common/mailbox_holder.typemap
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-mojom = "//gpu/command_buffer/common/mailbox_holder.mojom"
+mojom = "//gpu/ipc/common/mailbox_holder.mojom"
 public_headers = [ "//gpu/command_buffer/common/mailbox_holder.h" ]
 traits_headers = [ "//gpu/ipc/common/gpu_command_buffer_traits.h" ]
 deps = [
diff --git a/gpu/command_buffer/common/sync_token.mojom b/gpu/ipc/common/sync_token.mojom
similarity index 100%
rename from gpu/command_buffer/common/sync_token.mojom
rename to gpu/ipc/common/sync_token.mojom
diff --git a/gpu/command_buffer/common/sync_token.typemap b/gpu/ipc/common/sync_token.typemap
similarity index 87%
rename from gpu/command_buffer/common/sync_token.typemap
rename to gpu/ipc/common/sync_token.typemap
index 9100ff9..63acf60 100644
--- a/gpu/command_buffer/common/sync_token.typemap
+++ b/gpu/ipc/common/sync_token.typemap
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-mojom = "//gpu/command_buffer/common/sync_token.mojom"
+mojom = "//gpu/ipc/common/sync_token.mojom"
 public_headers = [ "//gpu/command_buffer/common/sync_token.h" ]
 traits_headers = [ "//gpu/ipc/common/gpu_command_buffer_traits.h" ]
 deps = [
diff --git a/gpu/ipc/common/typemaps.gni b/gpu/ipc/common/typemaps.gni
new file mode 100644
index 0000000..1eac9c78
--- /dev/null
+++ b/gpu/ipc/common/typemaps.gni
@@ -0,0 +1,11 @@
+# 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.
+
+typemaps = [
+  "//gpu/ipc/common/capabilities.typemap",
+  "//gpu/ipc/common/command_buffer.typemap",
+  "//gpu/ipc/common/mailbox.typemap",
+  "//gpu/ipc/common/mailbox_holder.typemap",
+  "//gpu/ipc/common/sync_token.typemap",
+]
diff --git a/gpu/ipc/service/gpu_command_buffer_stub.cc b/gpu/ipc/service/gpu_command_buffer_stub.cc
index b90275a..90818f6 100644
--- a/gpu/ipc/service/gpu_command_buffer_stub.cc
+++ b/gpu/ipc/service/gpu_command_buffer_stub.cc
@@ -295,8 +295,9 @@
                                     OnInitialize);
     IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer,
                                     OnSetGetBuffer);
-    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ProduceFrontBuffer,
-                        OnProduceFrontBuffer);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_TakeFrontBuffer, OnTakeFrontBuffer);
+    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ReturnFrontBuffer,
+                        OnReturnFrontBuffer);
     IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForTokenInRange,
                                     OnWaitForTokenInRange);
     IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForGetOffsetInRange,
@@ -714,14 +715,22 @@
   Send(reply_message);
 }
 
-void GpuCommandBufferStub::OnProduceFrontBuffer(const Mailbox& mailbox) {
-  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnProduceFrontBuffer");
+void GpuCommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) {
+  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnTakeFrontBuffer");
   if (!decoder_) {
-    LOG(ERROR) << "Can't produce front buffer before initialization.";
+    LOG(ERROR) << "Can't take front buffer before initialization.";
     return;
   }
 
-  decoder_->ProduceFrontBuffer(mailbox);
+  decoder_->TakeFrontBuffer(mailbox);
+}
+
+void GpuCommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox,
+                                               const SyncToken& sync_token,
+                                               bool is_lost) {
+  OnWaitFenceSync(sync_token.namespace_id(), sync_token.command_buffer_id(),
+                  sync_token.release_count());
+  decoder_->ReturnFrontBuffer(mailbox, is_lost);
 }
 
 void GpuCommandBufferStub::OnParseError() {
@@ -1033,6 +1042,8 @@
 
   image_manager->AddImage(image.get(), id);
   if (image_release_count) {
+    DCHECK_EQ(image_release_count,
+              sync_point_client_->client_state()->fence_sync_release() + 1);
     sync_point_client_->ReleaseFenceSync(image_release_count);
   }
 }
diff --git a/gpu/ipc/service/gpu_command_buffer_stub.h b/gpu/ipc/service/gpu_command_buffer_stub.h
index bf40d4f..d99f59b4 100644
--- a/gpu/ipc/service/gpu_command_buffer_stub.h
+++ b/gpu/ipc/service/gpu_command_buffer_stub.h
@@ -160,7 +160,10 @@
   void OnInitialize(base::SharedMemoryHandle shared_state_shm,
                     IPC::Message* reply_message);
   void OnSetGetBuffer(int32_t shm_id, IPC::Message* reply_message);
-  void OnProduceFrontBuffer(const Mailbox& mailbox);
+  void OnTakeFrontBuffer(const Mailbox& mailbox);
+  void OnReturnFrontBuffer(const Mailbox& mailbox,
+                           const SyncToken& sync_token,
+                           bool is_lost);
   void OnGetState(IPC::Message* reply_message);
   void OnWaitForTokenInRange(int32_t start,
                              int32_t end,
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg
index dd9d67733..1512160 100644
--- a/infra/config/cq.cfg
+++ b/infra/config/cq.cfg
@@ -55,6 +55,22 @@
     }
     buckets {
       name: "tryserver.chromium.mac"
+      builders {
+        name: "ios-device"
+        experiment_percentage: 10
+      }
+      builders {
+        name: "ios-device-gn"
+        experiment_percentage: 10
+      }
+      builders {
+        name: "ios-simulator"
+        experiment_percentage: 10
+      }
+      builders {
+        name: "ios-simulator-gn"
+        experiment_percentage: 10
+      }
       builders { name: "ios_dbg_simulator_ninja" }
       builders { name: "ios_dbg_simulator_gn" }
       builders { name: "ios_rel_device_ninja" }
diff --git a/ios/build/bots/chromium.mac/ios-device-gn.json b/ios/build/bots/chromium.mac/ios-device-gn.json
new file mode 100644
index 0000000..2b73b4c
--- /dev/null
+++ b/ios/build/bots/chromium.mac/ios-device-gn.json
@@ -0,0 +1,28 @@
+{
+  "owners": [
+    "dpranke",
+    "smut"
+  ],
+  "comments": [
+    "GN + Ninja fat binary builder."
+  ],
+  "xcode version": "7.0",
+  "GYP_DEFINES": {
+    "chromium_ios_signing": "0",
+    "target_subarch": "both",
+    "use_goma": "1"
+  },
+  "gn_args": [
+    "ios_enable_code_signing=false",
+    "target_cpu=\"arm\"",
+    "target_os=\"ios\"",
+    "use_goma=true"
+  ],
+  "mb_type": "gn",
+  "compiler": "ninja",
+  "additional_compile_targets": ["gn_all"],
+  "configuration": "Release",
+  "sdk": "iphoneos9.0",
+  "tests": [
+  ]
+}
diff --git a/ios/build/bots/chromium.mac/ios-device.json b/ios/build/bots/chromium.mac/ios-device.json
new file mode 100644
index 0000000..350f9d7
--- /dev/null
+++ b/ios/build/bots/chromium.mac/ios-device.json
@@ -0,0 +1,18 @@
+{
+  "owners": [
+    "smut"
+  ],
+  "comments": [
+    "Builder for 32-bit devices."
+  ],
+  "xcode version": "7.0",
+  "GYP_DEFINES": {
+    "chromium_ios_signing": "0",
+    "target_subarch": "arm32"
+  },
+  "compiler": "ninja",
+  "configuration": "Release",
+  "sdk": "iphoneos9.0",
+  "tests": [
+  ]
+}
diff --git a/ios/build/bots/chromium.mac/ios-simulator-gn.json b/ios/build/bots/chromium.mac/ios-simulator-gn.json
new file mode 100644
index 0000000..e62ed39
--- /dev/null
+++ b/ios/build/bots/chromium.mac/ios-simulator-gn.json
@@ -0,0 +1,39 @@
+{
+  "owners": [
+    "dpranke",
+    "smut"
+  ],
+  "comments": [
+    "GN + Ninja simulator build."
+  ],
+  "xcode version": "7.0",
+  "GYP_DEFINES": {
+    "chromium_ios_signing": "0",
+    "gomadir": "$(goma_dir)",
+    "use_goma": "1"
+  },
+  "gn_args": [
+    "target_os=\"ios\"",
+    "target_cpu=\"x64\"",
+    "is_debug=true",
+    "use_goma=true",
+    "goma_dir=\"$(goma_dir)\""
+  ],
+  "mb_type": "gn",
+  "compiler": "ninja",
+  "additional_compile_targets": ["gn_all"],
+  "configuration": "Debug",
+  "sdk": "iphonesimulator9.0",
+  "tests": [
+    {
+      "include": "common_tests.json",
+      "device type": "iPhone 5s",
+      "os": "9.0"
+    },
+    {
+      "include": "common_tests.json",
+      "device type": "iPad Air",
+      "os": "9.0"
+    }
+  ]
+}
diff --git a/ios/build/bots/chromium.mac/ios-simulator.json b/ios/build/bots/chromium.mac/ios-simulator.json
new file mode 100644
index 0000000..c1b8f44
--- /dev/null
+++ b/ios/build/bots/chromium.mac/ios-simulator.json
@@ -0,0 +1,29 @@
+{
+  "owners": [
+    "smut"
+  ],
+  "comments": [
+    "Tests for 32- and 64-bit iOS 9.0 simulators.",
+    "Tests run on iPhone 5s (64-bit) and iPad Retina (32-bit)."
+  ],
+  "xcode version": "7.0",
+  "GYP_DEFINES": {
+    "chromium_ios_signing": "0",
+    "target_subarch": "both"
+  },
+  "compiler": "ninja",
+  "configuration": "Debug",
+  "sdk": "iphonesimulator9.0",
+  "tests": [
+    {
+      "include": "common_tests.json",
+      "device type": "iPhone 5s",
+      "os": "9.0"
+    },
+    {
+      "include": "common_tests.json",
+      "device type": "iPad Retina",
+      "os": "9.0"
+    }
+  ]
+}
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index ded101a0..8469c8d9 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -560,6 +560,7 @@
     "//components/google/core/browser",
     "//components/history/core/browser",
     "//components/history/ios/browser",
+    "//components/image_fetcher",
     "//components/infobars/core",
     "//components/invalidation/impl",
     "//components/invalidation/public",
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS
index 838606e..c51a8989 100644
--- a/ios/chrome/browser/DEPS
+++ b/ios/chrome/browser/DEPS
@@ -26,6 +26,7 @@
   "+components/google/core/browser",
   "+components/history/core/browser",
   "+components/history/ios/browser",
+  "+components/image_fetcher",
   "+components/infobars/core",
   "+components/invalidation",
   "+components/keyed_service/core",
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 a81fc522..ed24da0 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
@@ -45,7 +45,6 @@
 #include "ios/chrome/browser/net/proxy_service_factory.h"
 #include "ios/web/public/web_thread.h"
 #include "net/base/keygen_handler.h"
-#include "net/base/network_quality_estimator.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert/multi_log_ct_verifier.h"
 #include "net/cookies/canonical_cookie.h"
@@ -53,6 +52,7 @@
 #include "net/http/http_transaction_factory.h"
 #include "net/http/http_util.h"
 #include "net/http/transport_security_persister.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_config_service_fixed.h"
 #include "net/proxy/proxy_script_fetcher_impl.h"
 #include "net/proxy/proxy_service.h"
diff --git a/ios/chrome/browser/ios_chrome_io_thread.h b/ios/chrome/browser/ios_chrome_io_thread.h
index 7827dcca..f99b68f 100644
--- a/ios/chrome/browser/ios_chrome_io_thread.h
+++ b/ios/chrome/browser/ios_chrome_io_thread.h
@@ -156,7 +156,6 @@
     Optional<int> quic_max_number_of_lossy_connections;
     Optional<float> quic_packet_loss_threshold;
     Optional<int> quic_socket_receive_buffer_size;
-    Optional<bool> quic_delay_tcp_race;
     Optional<size_t> quic_max_packet_length;
     net::QuicTagVector quic_connection_options;
     Optional<std::string> quic_user_agent_id;
@@ -328,10 +327,6 @@
   static int GetQuicSocketReceiveBufferSize(
       const VariationParameters& quic_trial_params);
 
-  // Returns true if QUIC should delay TCP connection when QUIC works.
-  static bool ShouldQuicDelayTcpRace(
-      const VariationParameters& quic_trial_params);
-
   // Returns true if QUIC should close sessions when any of the client's
   // IP addresses change.
   static bool ShouldQuicCloseSessionsOnIpChange(
diff --git a/ios/chrome/browser/ios_chrome_io_thread.mm b/ios/chrome/browser/ios_chrome_io_thread.mm
index f0fa384..a3a1099 100644
--- a/ios/chrome/browser/ios_chrome_io_thread.mm
+++ b/ios/chrome/browser/ios_chrome_io_thread.mm
@@ -43,8 +43,6 @@
 #include "ios/web/public/user_agent.h"
 #include "ios/web/public/web_client.h"
 #include "ios/web/public/web_thread.h"
-#include "net/base/external_estimate_provider.h"
-#include "net/base/network_quality_estimator.h"
 #include "net/base/sdch_manager.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert/cert_verify_proc.h"
@@ -65,6 +63,8 @@
 #include "net/http/http_network_layer.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_server_properties_impl.h"
+#include "net/nqe/external_estimate_provider.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_config_service.h"
 #include "net/proxy/proxy_script_fetcher_impl.h"
 #include "net/proxy/proxy_service.h"
@@ -664,7 +664,6 @@
       &params->quic_packet_loss_threshold);
   globals.quic_socket_receive_buffer_size.CopyToIfSet(
       &params->quic_socket_receive_buffer_size);
-  globals.quic_delay_tcp_race.CopyToIfSet(&params->quic_delay_tcp_race);
   params->enable_quic_port_selection = false;
   globals.quic_max_packet_length.CopyToIfSet(&params->quic_max_packet_length);
   globals.quic_user_agent_id.CopyToIfSet(&params->quic_user_agent_id);
@@ -772,7 +771,6 @@
     if (receive_buffer_size != 0) {
       globals->quic_socket_receive_buffer_size.set(receive_buffer_size);
     }
-    globals->quic_delay_tcp_race.set(ShouldQuicDelayTcpRace(quic_trial_params));
     float load_server_info_timeout_srtt_multiplier =
         GetQuicLoadServerInfoTimeoutSrttMultiplier(quic_trial_params);
     if (load_server_info_timeout_srtt_multiplier != 0) {
@@ -945,12 +943,6 @@
   return 0;
 }
 
-bool IOSChromeIOThread::ShouldQuicDelayTcpRace(
-    const VariationParameters& quic_trial_params) {
-  return base::LowerCaseEqualsASCII(
-      GetVariationParam(quic_trial_params, "delay_tcp_race"), "true");
-}
-
 bool IOSChromeIOThread::ShouldQuicCloseSessionsOnIpChange(
     const VariationParameters& quic_trial_params) {
   return base::LowerCaseEqualsASCII(
diff --git a/ios/chrome/browser/net/image_fetcher.h b/ios/chrome/browser/net/image_fetcher.h
index e579a362..1f32077 100644
--- a/ios/chrome/browser/net/image_fetcher.h
+++ b/ios/chrome/browser/net/image_fetcher.h
@@ -24,8 +24,6 @@
 class URLRequestContextGetter;
 }
 
-namespace image_fetcher {
-
 // Callback that informs of the download of an image encoded in |data|,
 // downloaded from |url|, and with the http status |http_response_code|. If the
 // url is a data URL, |http_response_code| is always 200.
@@ -89,6 +87,4 @@
   base::WeakPtrFactory<ImageFetcher> weak_factory_;
 };
 
-}  // namespace image_fetcher
-
 #endif  // IOS_CHROME_BROWSER_NET_IMAGE_FETCHER_H_
diff --git a/ios/chrome/browser/net/image_fetcher.mm b/ios/chrome/browser/net/image_fetcher.mm
index 264120b..1f0dfb5 100644
--- a/ios/chrome/browser/net/image_fetcher.mm
+++ b/ios/chrome/browser/net/image_fetcher.mm
@@ -60,8 +60,6 @@
 
 }  // namespace
 
-namespace image_fetcher {
-
 ImageFetcher::ImageFetcher(const scoped_refptr<base::TaskRunner>& task_runner)
     : request_context_getter_(nullptr),
       task_runner_(task_runner),
@@ -174,5 +172,3 @@
     const scoped_refptr<net::URLRequestContextGetter>& request_context_getter) {
   request_context_getter_ = request_context_getter;
 }
-
-}  // namespace image_fetcher
diff --git a/ios/chrome/browser/net/image_fetcher_unittest.mm b/ios/chrome/browser/net/image_fetcher_unittest.mm
index d315669..b5b0d01 100644
--- a/ios/chrome/browser/net/image_fetcher_unittest.mm
+++ b/ios/chrome/browser/net/image_fetcher_unittest.mm
@@ -74,7 +74,7 @@
  protected:
   ImageFetcherTest()
       : pool_(new base::SequencedWorkerPool(1, "TestPool")),
-        image_fetcher_(new image_fetcher::ImageFetcher(pool_)),
+        image_fetcher_(new ImageFetcher(pool_)),
         result_(nil),
         called_(false) {
     callback_.reset(
@@ -100,10 +100,10 @@
   }
 
   base::MessageLoop loop_;
-  base::mac::ScopedBlock<image_fetcher::ImageFetchedCallback> callback_;
+  base::mac::ScopedBlock<ImageFetchedCallback> callback_;
   net::TestURLFetcherFactory factory_;
   scoped_refptr<base::SequencedWorkerPool> pool_;
-  std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher_;
+  std::unique_ptr<ImageFetcher> image_fetcher_;
   UIImage* result_;
   bool called_;
 };
diff --git a/ios/chrome/browser/net/mock_image_fetcher.h b/ios/chrome/browser/net/mock_image_fetcher.h
index 2b12af9..259eda62 100644
--- a/ios/chrome/browser/net/mock_image_fetcher.h
+++ b/ios/chrome/browser/net/mock_image_fetcher.h
@@ -9,8 +9,6 @@
 
 #include "testing/gmock/include/gmock/gmock.h"
 
-namespace image_fetcher {
-
 // Mock the ImageFetcher utility class, which can be used to asynchronously
 // retrieve an image from an URL.
 class MockImageFetcher : public ImageFetcher {
@@ -30,6 +28,4 @@
                         request_context_getter));
 };
 
-}  // namespace image_fetcher
-
 #endif  // IOS_CHROME_BROWSER_NET_MOCK_IMAGE_FETCHER_H_
diff --git a/ios/chrome/browser/net/mock_image_fetcher.mm b/ios/chrome/browser/net/mock_image_fetcher.mm
index 84fb327d..7b02b8c8 100644
--- a/ios/chrome/browser/net/mock_image_fetcher.mm
+++ b/ios/chrome/browser/net/mock_image_fetcher.mm
@@ -4,8 +4,6 @@
 
 #import "ios/chrome/browser/net/mock_image_fetcher.h"
 
-namespace image_fetcher {
-
 MockImageFetcher::MockImageFetcher(
     const scoped_refptr<base::TaskRunner>& task_runner)
     : ImageFetcher(task_runner) {
@@ -13,5 +11,3 @@
 
 MockImageFetcher::~MockImageFetcher() {
 }
-
-}  // namespace image_fetcher
diff --git a/ios/chrome/browser/ssl/ios_chrome_security_state_model_client.mm b/ios/chrome/browser/ssl/ios_chrome_security_state_model_client.mm
index 0d9c6f0..0e93841b 100644
--- a/ios/chrome/browser/ssl/ios_chrome_security_state_model_client.mm
+++ b/ios/chrome/browser/ssl/ios_chrome_security_state_model_client.mm
@@ -10,7 +10,7 @@
 #include "ios/web/public/cert_store.h"
 #include "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
-#include "ios/web/public/origin_util.h"
+#import "ios/web/public/origin_util.h"
 #include "ios/web/public/security_style.h"
 #include "ios/web/public/ssl_status.h"
 #include "ios/web/public/web_state/web_state.h"
diff --git a/ios/chrome/browser/suggestions/image_fetcher_impl.h b/ios/chrome/browser/suggestions/image_fetcher_impl.h
index a0f0036..f7fe4db 100644
--- a/ios/chrome/browser/suggestions/image_fetcher_impl.h
+++ b/ios/chrome/browser/suggestions/image_fetcher_impl.h
@@ -9,13 +9,14 @@
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
-#include "components/suggestions/image_fetcher.h"
+#include "components/image_fetcher/image_fetcher.h"
 
 class GURL;
+class ImageFetcher;
 class SkBitmap;
 
 namespace image_fetcher {
-class ImageFetcher;
+class ImageFetcherDelegate;
 }
 
 namespace base {
@@ -28,16 +29,15 @@
 
 namespace suggestions {
 
-class ImageFetcherDelegate;
-
 // A class used to fetch server images asynchronously.
-class ImageFetcherImpl : public suggestions::ImageFetcher {
+class ImageFetcherImpl : public image_fetcher::ImageFetcher {
  public:
   ImageFetcherImpl(net::URLRequestContextGetter* url_request_context,
                    base::SequencedWorkerPool* blocking_pool);
   ~ImageFetcherImpl() override;
 
-  void SetImageFetcherDelegate(ImageFetcherDelegate* delegate) override;
+  void SetImageFetcherDelegate(
+      image_fetcher::ImageFetcherDelegate* delegate) override;
 
   void StartOrQueueNetworkRequest(
       const GURL& url,
@@ -45,9 +45,9 @@
       base::Callback<void(const GURL&, const SkBitmap*)> callback) override;
 
  private:
-  std::unique_ptr<image_fetcher::ImageFetcher> imageFetcher_;
+  std::unique_ptr<::ImageFetcher> imageFetcher_;
 
-  ImageFetcherDelegate* delegate_;
+  image_fetcher::ImageFetcherDelegate* delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(ImageFetcherImpl);
 };
diff --git a/ios/chrome/browser/suggestions/image_fetcher_impl.mm b/ios/chrome/browser/suggestions/image_fetcher_impl.mm
index 02e398e..553f02c 100644
--- a/ios/chrome/browser/suggestions/image_fetcher_impl.mm
+++ b/ios/chrome/browser/suggestions/image_fetcher_impl.mm
@@ -7,6 +7,7 @@
 #include <UIKit/UIKit.h>
 
 #include "base/threading/sequenced_worker_pool.h"
+#include "components/image_fetcher/image_fetcher_delegate.h"
 #include "ios/chrome/browser/net/image_fetcher.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "skia/ext/skia_utils_ios.h"
@@ -16,14 +17,15 @@
 ImageFetcherImpl::ImageFetcherImpl(
     net::URLRequestContextGetter* url_request_context,
     base::SequencedWorkerPool* blocking_pool) {
-  imageFetcher_.reset(new image_fetcher::ImageFetcher(blocking_pool));
+  imageFetcher_.reset(new ::ImageFetcher(blocking_pool));
   imageFetcher_->SetRequestContextGetter(url_request_context);
 }
 
 ImageFetcherImpl::~ImageFetcherImpl() {
 }
 
-void ImageFetcherImpl::SetImageFetcherDelegate(ImageFetcherDelegate* delegate) {
+void ImageFetcherImpl::SetImageFetcherDelegate(
+    image_fetcher::ImageFetcherDelegate* delegate) {
   DCHECK(delegate);
   delegate_ = delegate;
 }
@@ -41,7 +43,7 @@
   }
   // Copy url reference so it's retained.
   const GURL page_url(url);
-  image_fetcher::ImageFetchedCallback fetcher_callback =
+  ImageFetchedCallback fetcher_callback =
       ^(const GURL& original_url, int response_code, NSData* data) {
       if (data) {
         // Most likely always returns 1x images.
diff --git a/ios/chrome/browser/suggestions/suggestions_service_factory.mm b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
index b771df4..1c2a5eaf 100644
--- a/ios/chrome/browser/suggestions/suggestions_service_factory.mm
+++ b/ios/chrome/browser/suggestions/suggestions_service_factory.mm
@@ -12,12 +12,12 @@
 #include "base/sequenced_task_runner.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "components/browser_sync/browser/profile_sync_service.h"
+#include "components/image_fetcher/image_fetcher.h"
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "components/leveldb_proto/proto_database_impl.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/suggestions/blacklist_store.h"
-#include "components/suggestions/image_fetcher.h"
 #include "components/suggestions/image_manager.h"
 #include "components/suggestions/suggestions_service.h"
 #include "components/suggestions/suggestions_store.h"
@@ -84,8 +84,9 @@
       new BlacklistStore(browser_state->GetPrefs()));
   std::unique_ptr<leveldb_proto::ProtoDatabaseImpl<ImageData>> db(
       new leveldb_proto::ProtoDatabaseImpl<ImageData>(background_task_runner));
-  std::unique_ptr<ImageFetcher> image_fetcher(new ImageFetcherImpl(
-      browser_state->GetRequestContext(), sequenced_worker_pool));
+  std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher(
+      new ImageFetcherImpl(browser_state->GetRequestContext(),
+                           sequenced_worker_pool));
   std::unique_ptr<ImageManager> thumbnail_manager(new ImageManager(
       std::move(image_fetcher), std::move(db), database_dir,
       web::WebThread::GetTaskRunnerForThread(web::WebThread::DB)));
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index acf6a2e..9619d45 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -66,6 +66,7 @@
         '../../components/components.gyp:google_core_browser',
         '../../components/components.gyp:history_core_browser',
         '../../components/components.gyp:history_ios_browser',
+        '../../components/components.gyp:image_fetcher',
         '../../components/components.gyp:infobars_core',
         '../../components/components.gyp:invalidation_impl',
         '../../components/components.gyp:invalidation_public',
@@ -148,6 +149,7 @@
           '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
           '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework',
           '$(SDKROOT)/System/Library/Frameworks/UIKit.framework',
+          '$(SDKROOT)/System/Library/Frameworks/Photos.framework',
         ],
       },
       'sources': [
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 014ff7e0..81d6a05 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -104,8 +104,8 @@
     "public/load_committed_details.h",
     "public/navigation_item.h",
     "public/navigation_manager.h",
-    "public/origin_util.cc",
     "public/origin_util.h",
+    "public/origin_util.mm",
     "public/referrer.h",
     "public/referrer_util.cc",
     "public/referrer_util.h",
@@ -388,6 +388,7 @@
     "net/request_group_util_unittest.mm",
     "net/request_tracker_impl_unittest.mm",
     "net/web_http_protocol_handler_delegate_unittest.mm",
+    "public/origin_util_unittest.mm",
     "public/referrer_util_unittest.cc",
     "public/web_state/page_viewport_state_unittest.mm",
     "string_util_unittest.cc",
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp
index f83573d..e6451c2b 100644
--- a/ios/web/ios_web.gyp
+++ b/ios/web/ios_web.gyp
@@ -140,8 +140,8 @@
         'public/load_committed_details.h',
         'public/navigation_item.h',
         'public/navigation_manager.h',
-        'public/origin_util.cc',
         'public/origin_util.h',
+        'public/origin_util.mm',
         'public/referrer.h',
         'public/referrer_util.cc',
         'public/referrer_util.h',
diff --git a/ios/web/ios_web_unittests.gyp b/ios/web/ios_web_unittests.gyp
index c73f44006e..ee4ad09b 100644
--- a/ios/web/ios_web_unittests.gyp
+++ b/ios/web/ios_web_unittests.gyp
@@ -42,6 +42,7 @@
         'net/request_group_util_unittest.mm',
         'net/request_tracker_impl_unittest.mm',
         'net/web_http_protocol_handler_delegate_unittest.mm',
+        'public/origin_util_unittest.mm',
         'public/referrer_util_unittest.cc',
         'public/web_state/page_viewport_state_unittest.mm',
         'string_util_unittest.cc',
diff --git a/ios/web/public/origin_util.cc b/ios/web/public/origin_util.cc
deleted file mode 100644
index 28b39a9..0000000
--- a/ios/web/public/origin_util.cc
+++ /dev/null
@@ -1,28 +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 "ios/web/public/origin_util.h"
-
-#include "net/base/url_util.h"
-#include "url/gurl.h"
-
-namespace web {
-
-bool IsOriginSecure(const GURL& url) {
-  if (url.SchemeIsCryptographic() || url.SchemeIsFile())
-    return true;
-
-  if (url.SchemeIsFileSystem() && url.inner_url() &&
-      IsOriginSecure(*url.inner_url())) {
-    return true;
-  }
-
-  std::string hostname = url.HostNoBrackets();
-  if (net::IsLocalhost(hostname))
-    return true;
-
-  return false;
-}
-
-}  // namespace web
diff --git a/ios/web/public/origin_util.h b/ios/web/public/origin_util.h
index 1701ee4..a731d089 100644
--- a/ios/web/public/origin_util.h
+++ b/ios/web/public/origin_util.h
@@ -6,6 +6,7 @@
 #define IOS_WEB_PUBLIC_ORIGIN_UTIL_H_
 
 class GURL;
+@class WKSecurityOrigin;
 
 namespace web {
 
@@ -16,6 +17,10 @@
 // See https://www.w3.org/TR/powerful-features/#is-origin-trustworthy.
 bool IsOriginSecure(const GURL& url);
 
+// Converts WKSecurityOrigin to GURL origin.
+// Returns empty url if |origin| is nil.
+GURL GURLOriginWithWKSecurityOrigin(WKSecurityOrigin* origin);
+
 }  // namespace web
 
 #endif  // IOS_WEB_PUBLIC_ORIGIN_UTIL_H_
diff --git a/ios/web/public/origin_util.mm b/ios/web/public/origin_util.mm
new file mode 100644
index 0000000..de1d594
--- /dev/null
+++ b/ios/web/public/origin_util.mm
@@ -0,0 +1,43 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/web/public/origin_util.h"
+
+#import <WebKit/WebKit.h>
+
+#include "base/numerics/safe_conversions.h"
+#include "base/strings/sys_string_conversions.h"
+#include "net/base/url_util.h"
+#include "url/gurl.h"
+#include "url/scheme_host_port.h"
+
+namespace web {
+
+bool IsOriginSecure(const GURL& url) {
+  if (url.SchemeIsCryptographic() || url.SchemeIsFile())
+    return true;
+
+  if (url.SchemeIsFileSystem() && url.inner_url() &&
+      IsOriginSecure(*url.inner_url())) {
+    return true;
+  }
+
+  std::string hostname = url.HostNoBrackets();
+  if (net::IsLocalhost(hostname))
+    return true;
+
+  return false;
+}
+
+GURL GURLOriginWithWKSecurityOrigin(WKSecurityOrigin* origin) {
+  if (!origin)
+    return GURL();
+
+  url::SchemeHostPort origin_tuple(base::SysNSStringToUTF8(origin.protocol),
+                                   base::SysNSStringToUTF8(origin.host),
+                                   base::checked_cast<uint16_t>(origin.port));
+  return GURL(origin_tuple.Serialize());
+}
+
+}  // namespace web
diff --git a/ios/web/public/origin_util_unittest.mm b/ios/web/public/origin_util_unittest.mm
new file mode 100644
index 0000000..c797864
--- /dev/null
+++ b/ios/web/public/origin_util_unittest.mm
@@ -0,0 +1,60 @@
+// 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/web/public/origin_util.h"
+
+#import <WebKit/WebKit.h>
+
+#include "base/mac/objc_property_releaser.h"
+#include "base/mac/scoped_nsobject.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+// WKSecurityOrigin can not be manually created, hence stub is needed.
+@interface WKSecurityOriginStub : NSObject
+// Methods from WKSecurityOrigin class.
+@property(nonatomic, copy) NSString* protocol;
+@property(nonatomic, copy) NSString* host;
+@property(nonatomic) NSInteger port;
+@end
+
+@implementation WKSecurityOriginStub {
+  base::mac::ObjCPropertyReleaser _propertyReleaser;
+}
+@synthesize protocol = _protocol;
+@synthesize host = _host;
+@synthesize port = _port;
+- (instancetype)init {
+  if (self = [super init]) {
+    _propertyReleaser.Init(self, [WKSecurityOriginStub class]);
+  }
+  return self;
+}
+@end
+
+namespace web {
+
+// Tests calling GURLOriginWithWKSecurityOrigin with nil.
+TEST(OriginUtilTest, GURLOriginWithNilWKSecurityOrigin) {
+  GURL url(GURLOriginWithWKSecurityOrigin(nil));
+
+  EXPECT_FALSE(url.is_valid());
+  EXPECT_TRUE(url.spec().empty());
+}
+
+// Tests calling GURLOriginWithWKSecurityOrigin with valid origin.
+TEST(OriginUtilTest, GURLOriginWithValidWKSecurityOrigin) {
+  base::scoped_nsobject<WKSecurityOriginStub> origin(
+      [[WKSecurityOriginStub alloc] init]);
+  [origin setProtocol:@"http"];
+  [origin setHost:@"chromium.org"];
+  [origin setPort:80];
+
+  GURL url(GURLOriginWithWKSecurityOrigin(
+      static_cast<WKSecurityOrigin*>(origin.get())));
+  EXPECT_EQ("http://chromium.org/", url.spec());
+  EXPECT_TRUE(url.port().empty());
+}
+
+}  // namespace web
diff --git a/ios/web/web_thread_impl.cc b/ios/web/web_thread_impl.cc
index 4d09d5c..38f4a33 100644
--- a/ios/web/web_thread_impl.cc
+++ b/ios/web/web_thread_impl.cc
@@ -24,7 +24,7 @@
 namespace {
 
 // Friendly names for the well-known threads.
-const char* g_web_thread_names[WebThread::ID_COUNT] = {
+const char* const g_web_thread_names[WebThread::ID_COUNT] = {
     "Web_UIThread",                // UI
     "Web_DBThread",                // DB
     "Web_FileThread",              // FILE
@@ -303,9 +303,10 @@
                                   : nullptr;
   if (message_loop) {
     if (nestable) {
-      message_loop->PostDelayedTask(from_here, task, delay);
+      message_loop->task_runner()->PostDelayedTask(from_here, task, delay);
     } else {
-      message_loop->PostNonNestableDelayedTask(from_here, task, delay);
+      message_loop->task_runner()->PostNonNestableDelayedTask(from_here, task,
+                                                              delay);
     }
   }
 
diff --git a/ipc/mojo/ipc_mojo.gyp b/ipc/mojo/ipc_mojo.gyp
index 75c85d9..e925d7b 100644
--- a/ipc/mojo/ipc_mojo.gyp
+++ b/ipc/mojo/ipc_mojo.gyp
@@ -103,4 +103,23 @@
       ],
     },
   ],
+  'conditions': [
+    ['test_isolation_mode != "noop"', {
+      'targets': [
+        {
+          'target_name': 'ipc_mojo_unittests_run',
+          'type': 'none',
+          'dependencies': [
+            'ipc_mojo_unittests',
+          ],
+          'includes': [
+            '../../build/isolate.gypi',
+          ],
+          'sources': [
+            'ipc_mojo_unittests.isolate',
+          ],
+        },
+      ],
+    }],
+  ],
 }
diff --git a/ipc/mojo/ipc_mojo_unittests.isolate b/ipc/mojo/ipc_mojo_unittests.isolate
new file mode 100644
index 0000000..d330957
--- /dev/null
+++ b/ipc/mojo/ipc_mojo_unittests.isolate
@@ -0,0 +1,23 @@
+# 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.
+{
+  'includes': [
+    '../../base/base.isolate',
+  ],
+  'conditions': [
+    ['OS=="win" or OS=="mac" or OS=="linux"', {
+      'variables': {
+        'command': [
+          '../../testing/test_env.py',
+          '<(PRODUCT_DIR)/ipc_mojo_unittests<(EXECUTABLE_SUFFIX)',
+          '--brave-new-test-launcher',
+          '--test-launcher-bot-mode',
+        ],
+        'files': [
+          '../../testing/test_env.py',
+        ],
+      },
+    }],
+  ],
+}
diff --git a/mash/browser_driver/manifest.json b/mash/browser_driver/manifest.json
index ed8a985..4882f475 100644
--- a/mash/browser_driver/manifest.json
+++ b/mash/browser_driver/manifest.json
@@ -4,7 +4,10 @@
   "display_name": "Browser Driver",
   "capabilities": {
     "required": {
-      "*": { "classes": [ "app" ] }
+      "*": { "classes": [ "mash:launchable" ] },
+      "mojo:desktop_wm": {
+        "interfaces": [ "mus::mojom::AcceleratorRegistrar" ]
+      }
     }
   }
 }
diff --git a/media/BUILD.gn b/media/BUILD.gn
index a83a588a..11a48e1d 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -238,6 +238,8 @@
   deps = [
     ":cdm_api",
   ]
+
+  public_configs = [ "//third_party/libwebm:libwebm_config" ]
   public_deps = []
 
   include_dirs = [ "." ]
diff --git a/media/DEPS b/media/DEPS
index c00fbef..4acd9bb 100644
--- a/media/DEPS
+++ b/media/DEPS
@@ -12,6 +12,7 @@
   "+third_party/libyuv",
   "+third_party/opus",
   "+third_party/skia",
+  "+ui/display",
   "+ui/events",
   "+ui/gfx",
   "+ui/gl",
diff --git a/media/base/key_system_properties.h b/media/base/key_system_properties.h
index fd443a9..67cb4f80 100644
--- a/media/base/key_system_properties.h
+++ b/media/base/key_system_properties.h
@@ -7,6 +7,7 @@
 
 #include <string>
 
+#include "build/build_config.h"
 #include "media/base/eme_constants.h"
 #include "media/base/key_system_info.h"
 #include "media/base/media_export.h"
diff --git a/media/blink/multibuffer_data_source_unittest.cc b/media/blink/multibuffer_data_source_unittest.cc
index 0adfc095..61b2b1ac 100644
--- a/media/blink/multibuffer_data_source_unittest.cc
+++ b/media/blink/multibuffer_data_source_unittest.cc
@@ -1317,4 +1317,26 @@
   Stop();
 }
 
+TEST_F(MultibufferDataSourceTest, Http_NotStreamingAfterRedirect) {
+  Initialize(kHttpUrl, true);
+
+  // Server responds with a redirect.
+  blink::WebURLRequest request((GURL(kHttpDifferentPathUrl)));
+  blink::WebURLResponse response((GURL(kHttpUrl)));
+  response.setHTTPStatusCode(307);
+  data_provider()->willFollowRedirect(url_loader(), request, response);
+
+  EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
+  Respond(response_generator_->Generate206(0));
+
+  EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize));
+  ReceiveData(kDataSize);
+
+  EXPECT_FALSE(data_source_->IsStreaming());
+
+  FinishLoading();
+  EXPECT_FALSE(loading());
+  Stop();
+}
+
 }  // namespace media
diff --git a/media/blink/resource_multibuffer_data_provider.cc b/media/blink/resource_multibuffer_data_provider.cc
index b9ae7e2..0acae61 100644
--- a/media/blink/resource_multibuffer_data_provider.cc
+++ b/media/blink/resource_multibuffer_data_provider.cc
@@ -262,7 +262,8 @@
     // If we have verified the partial response and it is correct.
     // It's also possible for a server to support range requests
     // without advertising "Accept-Ranges: bytes".
-    if (partial_response && VerifyPartialResponse(response)) {
+    if (partial_response &&
+        VerifyPartialResponse(response, destination_url_data)) {
       destination_url_data->set_range_supported();
     } else if (ok_response && pos_ == 0) {
       // We accept a 200 response for a Range:0- request, trusting the
@@ -483,7 +484,8 @@
 }
 
 bool ResourceMultiBufferDataProvider::VerifyPartialResponse(
-    const WebURLResponse& response) {
+    const WebURLResponse& response,
+    const scoped_refptr<UrlData>& url_data) {
   int64_t first_byte_position, last_byte_position, instance_size;
   if (!ParseContentRange(response.httpHeaderField("Content-Range").utf8(),
                          &first_byte_position, &last_byte_position,
@@ -492,7 +494,7 @@
   }
 
   if (url_data_->length() == kPositionNotSpecified) {
-    url_data_->set_length(instance_size);
+    url_data->set_length(instance_size);
   }
 
   if (byte_pos() != first_byte_position) {
diff --git a/media/blink/resource_multibuffer_data_provider.h b/media/blink/resource_multibuffer_data_provider.h
index 41b8c54..a70e87d8 100644
--- a/media/blink/resource_multibuffer_data_provider.h
+++ b/media/blink/resource_multibuffer_data_provider.h
@@ -89,7 +89,8 @@
   int64_t block_size() const;
 
   // If we have made a range request, verify the response from the server.
-  bool VerifyPartialResponse(const blink::WebURLResponse& response);
+  bool VerifyPartialResponse(const blink::WebURLResponse& response,
+                             const scoped_refptr<UrlData>& url_data);
 
   // Current Position.
   MultiBufferBlockId pos_;
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn
index af73e90..036a33c 100644
--- a/media/capture/BUILD.gn
+++ b/media/capture/BUILD.gn
@@ -83,6 +83,7 @@
     "//base",
     "//media/base",
     "//skia",
+    "//ui/display",
   ]
 
   configs += [
diff --git a/media/capture/video/linux/video_capture_device_chromeos.cc b/media/capture/video/linux/video_capture_device_chromeos.cc
index 5c5e397..b8051db 100644
--- a/media/capture/video/linux/video_capture_device_chromeos.cc
+++ b/media/capture/video/linux/video_capture_device_chromeos.cc
@@ -11,16 +11,16 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/display_observer.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/display_observer.h"
+#include "ui/display/screen.h"
 
 namespace media {
 
 // This is a delegate class used to transfer Display change events from the UI
 // thread to the media thread.
 class VideoCaptureDeviceChromeOS::ScreenObserverDelegate
-    : public gfx::DisplayObserver,
+    : public display::DisplayObserver,
       public base::RefCountedThreadSafe<ScreenObserverDelegate> {
  public:
   ScreenObserverDelegate(
@@ -47,9 +47,9 @@
 
   ~ScreenObserverDelegate() override { DCHECK(!capture_device_); }
 
-  void OnDisplayAdded(const gfx::Display& /*new_display*/) override {}
-  void OnDisplayRemoved(const gfx::Display& /*old_display*/) override {}
-  void OnDisplayMetricsChanged(const gfx::Display& display,
+  void OnDisplayAdded(const display::Display& /*new_display*/) override {}
+  void OnDisplayRemoved(const display::Display& /*old_display*/) override {}
+  void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t metrics) override {
     DCHECK(ui_task_runner_->BelongsToCurrentThread());
     if (!(metrics & DISPLAY_METRIC_ROTATION))
@@ -59,7 +59,7 @@
 
   void AddObserverOnUIThread() {
     DCHECK(ui_task_runner_->BelongsToCurrentThread());
-    gfx::Screen* screen = gfx::Screen::GetScreen();
+    display::Screen* screen = display::Screen::GetScreen();
     if (screen) {
       screen->AddObserver(this);
       SendDisplayRotation(screen->GetPrimaryDisplay());
@@ -68,13 +68,13 @@
 
   void RemoveObserverOnUIThread() {
     DCHECK(ui_task_runner_->BelongsToCurrentThread());
-    gfx::Screen* screen = gfx::Screen::GetScreen();
+    display::Screen* screen = display::Screen::GetScreen();
     if (screen)
       screen->RemoveObserver(this);
   }
 
   // Post the screen rotation change from the UI thread to capture thread
-  void SendDisplayRotation(const gfx::Display& display) {
+  void SendDisplayRotation(const display::Display& display) {
     DCHECK(ui_task_runner_->BelongsToCurrentThread());
     capture_task_runner_->PostTask(
         FROM_HERE,
@@ -82,7 +82,7 @@
                    this, display));
   }
 
-  void SendDisplayRotationOnCaptureThread(const gfx::Display& display) {
+  void SendDisplayRotationOnCaptureThread(const display::Display& display) {
     DCHECK(capture_task_runner_->BelongsToCurrentThread());
     if (capture_device_)
       capture_device_->SetDisplayRotation(display);
@@ -107,7 +107,7 @@
 }
 
 void VideoCaptureDeviceChromeOS::SetDisplayRotation(
-    const gfx::Display& display) {
+    const display::Display& display) {
   if (display.IsInternal())
     SetRotation(display.rotation() * 90);
 }
diff --git a/media/capture/video/linux/video_capture_device_chromeos.h b/media/capture/video/linux/video_capture_device_chromeos.h
index 8b5fafc..fce2988 100644
--- a/media/capture/video/linux/video_capture_device_chromeos.h
+++ b/media/capture/video/linux/video_capture_device_chromeos.h
@@ -12,6 +12,10 @@
 class Display;
 }  // namespace gfx
 
+namespace display {
+using Display = gfx::Display;
+}  // namespace display
+
 namespace media {
 
 // This class is functionally the same as VideoCaptureDeviceLinux, with the
@@ -27,7 +31,7 @@
  private:
   class ScreenObserverDelegate;
 
-  void SetDisplayRotation(const gfx::Display& display);
+  void SetDisplayRotation(const display::Display& display);
   scoped_refptr<ScreenObserverDelegate> screen_observer_delegate_;
   DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceChromeOS);
 };
diff --git a/media/media.gyp b/media/media.gyp
index ba963d2..7681aca7 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -90,6 +90,7 @@
         'shared_memory_support',
       ],
       'export_dependent_settings': [
+        '../third_party/libwebm/libwebm.gyp:libwebm',
         '../third_party/opus/opus.gyp:opus',
       ],
       'defines': [
diff --git a/media/muxers/webm_muxer.cc b/media/muxers/webm_muxer.cc
index b7ae483..d699b1cd 100644
--- a/media/muxers/webm_muxer.cc
+++ b/media/muxers/webm_muxer.cc
@@ -69,13 +69,29 @@
   return frame_rate;
 }
 
+static const char kH264CodecId[] = "V_MPEG4/ISO/AVC";
+
+static const char* MkvCodeIcForMediaVideoCodecId(VideoCodec video_codec) {
+  switch (video_codec) {
+    case kCodecVP8:
+      return mkvmuxer::Tracks::kVp8CodecId;
+    case kCodecVP9:
+      return mkvmuxer::Tracks::kVp9CodecId;
+    case kCodecH264:
+      return kH264CodecId;
+    default:
+      NOTREACHED() << "Unsupported codec " << GetCodecName(video_codec);
+      return "";
+  }
+}
+
 }  // anonymous namespace
 
 WebmMuxer::WebmMuxer(VideoCodec codec,
                      bool has_video,
                      bool has_audio,
                      const WriteDataCB& write_data_callback)
-    : use_vp9_(codec == kCodecVP9),
+    : video_codec_(codec),
       video_track_index_(0),
       audio_track_index_(0),
       has_video_(has_video),
@@ -84,8 +100,8 @@
       position_(0) {
   DCHECK(has_video_ || has_audio_);
   DCHECK(!write_data_callback_.is_null());
-  DCHECK(codec == kCodecVP8 || codec == kCodecVP9)
-      << " Only Vp8 and VP9 are supported in WebmMuxer";
+  DCHECK(codec == kCodecVP8 || codec == kCodecVP9 || codec == kCodecH264)
+      << " Unsupported codec: " << GetCodecName(codec);
 
   segment_.Init(this);
   segment_.set_mode(mkvmuxer::Segment::kLive);
@@ -208,8 +224,7 @@
       reinterpret_cast<mkvmuxer::VideoTrack*>(
           segment_.GetTrackByNumber(video_track_index_));
   DCHECK(video_track);
-  video_track->set_codec_id(use_vp9_ ? mkvmuxer::Tracks::kVp9CodecId
-                                     : mkvmuxer::Tracks::kVp8CodecId);
+  video_track->set_codec_id(MkvCodeIcForMediaVideoCodecId(video_codec_));
   DCHECK_EQ(0ull, video_track->crop_right());
   DCHECK_EQ(0ull, video_track->crop_left());
   DCHECK_EQ(0ull, video_track->crop_top());
diff --git a/media/muxers/webm_muxer.h b/media/muxers/webm_muxer.h
index ecc2594..afd8176 100644
--- a/media/muxers/webm_muxer.h
+++ b/media/muxers/webm_muxer.h
@@ -96,8 +96,8 @@
   // Used to DCHECK that we are called on the correct thread.
   base::ThreadChecker thread_checker_;
 
-  // Video Codec configured: VP9 if true, otherwise VP8 is used by default.
-  const bool use_vp9_;
+  // Video Codec configured on construction.
+  const VideoCodec video_codec_;
 
   // Caller-side identifiers to interact with |segment_|, initialised upon
   // first frame arrival to Add{Video, Audio}Track().
diff --git a/media/muxers/webm_muxer_unittest.cc b/media/muxers/webm_muxer_unittest.cc
index 8c59d0a..d71e0b9f 100644
--- a/media/muxers/webm_muxer_unittest.cc
+++ b/media/muxers/webm_muxer_unittest.cc
@@ -237,13 +237,15 @@
 }
 
 const kTestParams kTestCases[] = {
-    // TODO: consider not enumerating every combination by hand.
     {kCodecVP8, 1 /* num_video_tracks */, 0 /*num_audio_tracks*/},
     {kCodecVP8, 0, 1},
     {kCodecVP8, 1, 1},
     {kCodecVP9, 1, 0},
     {kCodecVP9, 0, 1},
     {kCodecVP9, 1, 1},
+    {kCodecH264, 1, 0},
+    {kCodecH264, 0, 1},
+    {kCodecH264, 1, 1},
 };
 
 INSTANTIATE_TEST_CASE_P(, WebmMuxerTest, ValuesIn(kTestCases));
diff --git a/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java b/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java
index c7348caa..3e81b7a8 100644
--- a/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java
+++ b/mojo/android/javatests/src/org/chromium/mojo/MojoTestCase.java
@@ -4,7 +4,6 @@
 
 package org.chromium.mojo;
 
-import android.content.Context;
 import android.test.InstrumentationTestCase;
 
 import org.chromium.base.ContextUtils;
@@ -26,9 +25,9 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        Context appContext = getInstrumentation().getTargetContext().getApplicationContext();
-        ContextUtils.initApplicationContext(appContext);
-        LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized(appContext);
+        LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER)
+                .ensureInitialized(getInstrumentation().getTargetContext());
+        ContextUtils.initApplicationContext(getInstrumentation().getTargetContext());
         nativeInit();
         mTestEnvironmentPointer = nativeSetupTestEnvironment();
     }
diff --git a/mojo/edk/js/test/BUILD.gn b/mojo/edk/js/test/BUILD.gn
index 3da5bc8b..c5a78c35 100644
--- a/mojo/edk/js/test/BUILD.gn
+++ b/mojo/edk/js/test/BUILD.gn
@@ -16,9 +16,11 @@
     "//mojo/public/cpp/system",
     "//mojo/public/interfaces/bindings/tests:test_interfaces",
     "//mojo/public/interfaces/bindings/tests:test_interfaces_experimental",
+    "//mojo/public/js:tests",
   ]
 
   sources = [
+    "//mojo/edk/js/handle_unittest.cc",
     "run_js_tests.cc",
   ]
 }
@@ -35,6 +37,7 @@
     "//mojo/edk/test:test_support",
     "//mojo/public/cpp/bindings",
     "//mojo/public/interfaces/bindings/tests:test_interfaces",
+    "//mojo/public/js:bindings",
   ]
 
   sources = [
diff --git a/mojo/edk/js/tests/BUILD.gn b/mojo/edk/js/tests/BUILD.gn
index 5761bcb3..b21cdbc 100644
--- a/mojo/edk/js/tests/BUILD.gn
+++ b/mojo/edk/js/tests/BUILD.gn
@@ -23,6 +23,12 @@
     "js_to_cpp_tests.cc",
   ]
 
+  data = [
+    "connection_tests.js",
+    "js_to_cpp_tests.js",
+    "sample_service_tests.js",
+  ]
+
   configs += [ "//v8:external_startup_data" ]
 }
 
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc
index 1aa4d310..1d78f85 100644
--- a/mojo/gles2/command_buffer_client_impl.cc
+++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -337,11 +337,6 @@
 void CommandBufferClientImpl::SetLock(base::Lock* lock) {
 }
 
-bool CommandBufferClientImpl::IsGpuChannelLost() {
-  // This is only possible for out-of-process command buffers.
-  return false;
-}
-
 void CommandBufferClientImpl::EnsureWorkVisible() {
   // This is only relevant for out-of-process command buffers.
 }
diff --git a/mojo/gles2/command_buffer_client_impl.h b/mojo/gles2/command_buffer_client_impl.h
index e4fabfb..1fd14ab 100644
--- a/mojo/gles2/command_buffer_client_impl.h
+++ b/mojo/gles2/command_buffer_client_impl.h
@@ -64,7 +64,6 @@
                                      unsigned usage) override;
   void SignalQuery(uint32_t query, const base::Closure& callback) override;
   void SetLock(base::Lock*) override;
-  bool IsGpuChannelLost() override;
   void EnsureWorkVisible() override;
   gpu::CommandBufferNamespace GetNamespaceID() const override;
   gpu::CommandBufferId GetCommandBufferID() const override;
diff --git a/mojo/mojo.isolate b/mojo/mojo.isolate
new file mode 100644
index 0000000..693e94a
--- /dev/null
+++ b/mojo/mojo.isolate
@@ -0,0 +1,31 @@
+# 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.
+{
+  'includes': [
+    '../base/base.isolate',
+  ],
+  'conditions': [
+    ['OS=="win"', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/mojo_public_test_support.dll',
+        ],
+      },
+    }],
+    ['OS=="linux"', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/lib/libmojo_public_test_support.so',
+        ],
+      },
+    }],
+    ['OS=="mac"', {
+      'variables': {
+        'files': [
+          '<(PRODUCT_DIR)/libmojo_public_test_support.dylib',
+        ],
+      },
+    }],
+  ],
+}
diff --git a/mojo/mojo_common_unittests.isolate b/mojo/mojo_common_unittests.isolate
index 8fe9d31..caeaf44 100644
--- a/mojo/mojo_common_unittests.isolate
+++ b/mojo/mojo_common_unittests.isolate
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 {
   'includes': [
-    '../base/base.isolate',
+    '../mojo/mojo.isolate',
   ],
   'conditions': [
     ['OS=="win" or OS=="mac" or OS=="linux"', {
@@ -19,26 +19,5 @@
         ],
       },
     }],
-    ['OS=="win"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/mojo_public_test_support.dll',
-        ],
-      },
-    }],
-    ['OS=="linux"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/lib/libmojo_public_test_support.so',
-        ],
-      },
-    }],
-    ['OS=="mac"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/libmojo_public_test_support.dylib',
-        ],
-      },
-    }],
   ],
 }
diff --git a/mojo/mojo_edk_tests.gyp b/mojo/mojo_edk_tests.gyp
index d4a65aa..4bed79a 100644
--- a/mojo/mojo_edk_tests.gyp
+++ b/mojo/mojo_edk_tests.gyp
@@ -326,6 +326,45 @@
             'mojo_public_system_unittests.isolate',
           ],
         },
+        {
+          'target_name': 'mojo_js_unittests_run',
+          'type': 'none',
+          'dependencies': [
+            'mojo_js_unittests',
+          ],
+          'includes': [
+            '../build/isolate.gypi',
+          ],
+          'sources': [
+            'mojo_js_unittests.isolate',
+          ],
+        },
+        {
+          'target_name': 'mojo_js_integration_tests_run',
+          'type': 'none',
+          'dependencies': [
+            'mojo_js_integration_tests',
+          ],
+          'includes': [
+            '../build/isolate.gypi',
+          ],
+          'sources': [
+            'mojo_js_integration_tests.isolate',
+          ],
+        },
+        {
+          'target_name': 'mojo_system_unittests_run',
+          'type': 'none',
+          'dependencies': [
+            'mojo_system_unittests',
+          ],
+          'includes': [
+            '../build/isolate.gypi',
+          ],
+          'sources': [
+            'mojo_system_unittests.isolate',
+          ],
+        },
       ],
     }],
   ],
diff --git a/mojo/mojo_js_integration_tests.isolate b/mojo/mojo_js_integration_tests.isolate
new file mode 100644
index 0000000..76d6f9c3
--- /dev/null
+++ b/mojo/mojo_js_integration_tests.isolate
@@ -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.
+{
+  'includes': [
+    '../gin/v8.isolate',
+    '../mojo/mojo.isolate',
+    '../third_party/icu/icu.isolate',
+  ],
+  'conditions': [
+    ['OS=="win" or OS=="mac" or OS=="linux"', {
+      'variables': {
+        'command': [
+          '../testing/test_env.py',
+          '<(PRODUCT_DIR)/mojo_js_integration_tests<(EXECUTABLE_SUFFIX)',
+          '--brave-new-test-launcher',
+          '--test-launcher-bot-mode',
+        ],
+        'files': [
+          '../gin/test/expect.js',
+          '../mojo/edk/js/tests/',
+          '../mojo/public/js/',
+          '../testing/test_env.py',
+          '<(PRODUCT_DIR)/mojo_js_integration_tests<(EXECUTABLE_SUFFIX)',
+          '<(PRODUCT_DIR)/gen/mojo/common/common_custom_types.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/edk/js/tests/js_to_cpp.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/math_calculator.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/no_module.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/ping_service.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/rect.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/regression_tests.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_factory.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_import.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_import2.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_service.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/scoping.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_constants.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_native_types.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_structs.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_unions.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.js',
+        ],
+      },
+    }],
+  ],
+}
diff --git a/mojo/mojo_js_unittests.isolate b/mojo/mojo_js_unittests.isolate
index c628388..7dae01b 100644
--- a/mojo/mojo_js_unittests.isolate
+++ b/mojo/mojo_js_unittests.isolate
@@ -3,6 +3,8 @@
 # found in the LICENSE file.
 {
   'includes': [
+    '../gin/v8.isolate',
+    '../mojo/mojo.isolate',
     '../third_party/icu/icu.isolate',
   ],
   'conditions': [
@@ -17,30 +19,26 @@
         'files': [
           '../gin/test/expect.js',
           '../testing/test_env.py',
-          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/',
-          'bindings/js/',
-          'public/js/bindings/',
-        ],
-      },
-    }],
-    ['OS=="win"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/mojo_public_test_support.dll',
-        ],
-      },
-    }],
-    ['OS=="linux"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/lib/libmojo_public_test_support.so',
-        ],
-      },
-    }],
-    ['OS=="mac"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/libmojo_public_test_support.dylib',
+          'public/interfaces/bindings/tests/data/validation/',
+          'public/js/',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/math_calculator.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/no_module.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/ping_service.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/rect.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/regression_tests.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_factory.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_import.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_import2.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/sample_service.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/scoping.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_constants.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_native_types.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_structs.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_sync_methods.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/test_unions.mojom.js',
+          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.js',
         ],
       },
     }],
diff --git a/mojo/mojo_public_bindings_unittests.isolate b/mojo/mojo_public_bindings_unittests.isolate
index 4c1ffaaa..2b4436f 100644
--- a/mojo/mojo_public_bindings_unittests.isolate
+++ b/mojo/mojo_public_bindings_unittests.isolate
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 {
   'includes': [
-    '../base/base.isolate',
+    '../mojo/mojo.isolate',
   ],
   'conditions': [
     ['OS=="win" or OS=="mac" or OS=="linux"', {
@@ -19,26 +19,5 @@
         ],
       },
     }],
-    ['OS=="win"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/mojo_public_test_support.dll',
-        ],
-      },
-    }],
-    ['OS=="linux"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/lib/libmojo_public_test_support.so',
-        ],
-      },
-    }],
-    ['OS=="mac"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/libmojo_public_test_support.dylib',
-        ],
-      },
-    }],
   ],
 }
diff --git a/mojo/mojo_public_system_unittests.isolate b/mojo/mojo_public_system_unittests.isolate
index 73b8c005..87099f6 100644
--- a/mojo/mojo_public_system_unittests.isolate
+++ b/mojo/mojo_public_system_unittests.isolate
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 {
   'includes': [
-    '../base/base.isolate',
+    '../mojo/mojo.isolate',
   ],
   'conditions': [
     ['OS=="win" or OS=="mac" or OS=="linux"', {
@@ -19,26 +19,5 @@
         ],
       },
     }],
-    ['OS=="win"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/mojo_public_test_support.dll',
-        ],
-      },
-    }],
-    ['OS=="linux"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/lib/libmojo_public_test_support.so',
-        ],
-      },
-    }],
-    ['OS=="mac"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/libmojo_public_test_support.dylib',
-        ],
-      },
-    }],
   ],
 }
diff --git a/mojo/mojo_system_unittests.isolate b/mojo/mojo_system_unittests.isolate
new file mode 100644
index 0000000..cfd6b48
--- /dev/null
+++ b/mojo/mojo_system_unittests.isolate
@@ -0,0 +1,23 @@
+# 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.
+{
+  'includes': [
+    '../mojo/mojo.isolate',
+  ],
+  'conditions': [
+    ['OS=="win" or OS=="mac" or OS=="linux"', {
+      'variables': {
+        'command': [
+          '../testing/test_env.py',
+          '<(PRODUCT_DIR)/mojo_system_unittests<(EXECUTABLE_SUFFIX)',
+          '--brave-new-test-launcher',
+          '--test-launcher-bot-mode',
+        ],
+        'files': [
+          '../testing/test_env.py',
+        ],
+      },
+    }],
+  ],
+}
diff --git a/mojo/public/js/BUILD.gn b/mojo/public/js/BUILD.gn
index 4b86e6eb..eda7e04d 100644
--- a/mojo/public/js/BUILD.gn
+++ b/mojo/public/js/BUILD.gn
@@ -8,3 +8,38 @@
     "constants.h",
   ]
 }
+
+group("bindings") {
+  data = [
+    "bindings.js",
+    "buffer.js",
+    "codec.js",
+    "connection.js",
+    "connector.js",
+    "constants.cc",
+    "constants.h",
+    "core.js",
+    "router.js",
+    "support.js",
+    "threading.js",
+    "unicode.js",
+    "validator.js",
+  ]
+}
+
+group("tests") {
+  testonly = true
+
+  data = [
+    "codec_unittests.js",
+    "core_unittests.js",
+    "struct_unittests.js",
+    "test/validation_test_input_parser.js",
+    "union_unittests.js",
+    "validation_unittests.js",
+    "//mojo/public/interfaces/bindings/tests/data/validation/",
+  ]
+  public_deps = [
+    ":bindings",
+  ]
+}
diff --git a/mojo/public/mojo_application_manifest.gni b/mojo/public/mojo_application_manifest.gni
index b66626b8..61844173 100644
--- a/mojo/public/mojo_application_manifest.gni
+++ b/mojo/public/mojo_application_manifest.gni
@@ -107,11 +107,14 @@
       }
     }
     deps = []
+    data_deps = []
     if (defined(invoker.deps)) {
       deps += invoker.deps
+      data_deps += invoker.deps
     }
     if (defined(invoker.base_deps)) {
       deps += invoker.base_deps
+      data_deps += invoker.base_deps
     }
   }
 
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
index 0d44d6f..3f17c0f6 100644
--- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni
+++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -3,7 +3,7 @@
 # found in the LICENSE file.
 
 _typemap_imports = [
-  "//gpu/command_buffer/common/typemaps.gni",
+  "//gpu/ipc/common/typemaps.gni",
   "//mojo/common/typemaps.gni",
   "//mojo/public/cpp/bindings/tests/chromium_typemaps.gni",
   "//url/mojo/typemaps.gni",
diff --git a/mojo/tools/apptest_runner.py b/mojo/tools/apptest_runner.py
index 6494db73..7fa0aba2 100755
--- a/mojo/tools/apptest_runner.py
+++ b/mojo/tools/apptest_runner.py
@@ -30,6 +30,8 @@
                       help='The number of times to repeat the set of tests.')
   parser.add_argument('--write-full-results-to', metavar='FILENAME',
                       help='The path to write the JSON list of full results.')
+  parser.add_argument('--test-launcher-summary-output', metavar='FILENAME',
+                      help='The path to write the JSON list of full results.')
   parser.add_argument('--test-list-file', metavar='FILENAME', type=file,
                       default=APPTESTS, help='The file listing tests to run.')
   parser.add_argument('--apptest-filter', default='',
@@ -112,6 +114,8 @@
 
   if args.write_full_results_to:
     _WriteJSONResults(tests, failed, args.write_full_results_to)
+  if args.test_launcher_summary_output:
+    _WriteSwarmingJSONResults(tests, failed, args.test_launcher_summary_output)
 
   return 1 if failed else 0
 
@@ -160,5 +164,30 @@
   _AddPathToTrie(trie[directory], rest, value)
 
 
+def _WriteSwarmingJSONResults(tests, failed, write_full_results_to):
+  '''Writes the test results in the JSON test result format used by swarming.'''
+  results = {
+    'all_tests': tests,
+    'disabled_tests': [],
+    'global_tags': [],
+  }
+
+  test_results = []
+  for test in sorted(tests):
+    value = [{
+      'status': 'FAILURE' if test in failed else 'SUCCESS',
+      'output_snippet': '',
+      'output_snippet_base64': '',
+    }]
+    test_results.append({test: value})
+  results['per_iteration_data'] = test_results
+
+  with open(write_full_results_to, 'w') as fp:
+    json.dump(results, fp, indent=2)
+    fp.write('\n')
+
+  return results
+
+
 if __name__ == '__main__':
   sys.exit(main())
diff --git a/net/BUILD.gn b/net/BUILD.gn
index e14caac..c56e7fb 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1689,9 +1689,13 @@
   testonly = true
 
   sources = [
+    "base/fuzzed_data_provider.cc",
+    "base/fuzzed_data_provider.h",
     "base/fuzzer_test_support.cc",
     "socket/fuzzed_socket.cc",
     "socket/fuzzed_socket.h",
+    "socket/fuzzed_socket_factory.cc",
+    "socket/fuzzed_socket_factory.h",
   ]
   deps = [
     "//base",
@@ -1783,6 +1787,17 @@
   ]
 }
 
+fuzzer_test("net_cert_verify_name_match_fuzzer") {
+  sources = [
+    "cert/internal/verify_name_match_fuzzer.cc",
+  ]
+  deps = [
+    ":net_fuzzer_test_support",
+    "//base",
+    "//net",
+  ]
+}
+
 fuzzer_test("net_cert_normalize_name_fuzzer") {
   sources = [
     "cert/internal/verify_name_match_normalizename_fuzzer.cc",
@@ -1793,6 +1808,27 @@
   ]
 }
 
+fuzzer_test("net_cert_verify_name_in_subtree_fuzzer") {
+  sources = [
+    "cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc",
+  ]
+  deps = [
+    ":net_fuzzer_test_support",
+    "//base",
+    "//net",
+  ]
+}
+
+fuzzer_test("net_cert_parse_certificate_fuzzer") {
+  sources = [
+    "cert/internal/parse_certificate_fuzzer.cc",
+  ]
+  deps = [
+    "//base",
+    "//net",
+  ]
+}
+
 fuzzer_test("net_parse_cookie_line_fuzzer") {
   sources = [
     "cookies/parse_cookie_line_fuzzer.cc",
@@ -1814,6 +1850,17 @@
   ]
 }
 
+fuzzer_test("net_dns_hosts_parse_fuzzer") {
+  sources = [
+    "dns/dns_hosts_parse_fuzzer.cc",
+  ]
+  deps = [
+    ":net_fuzzer_test_support",
+    "//base",
+    "//net",
+  ]
+}
+
 fuzzer_test("net_http_stream_parser_fuzzer") {
   sources = [
     "http/http_stream_parser_fuzzer.cc",
@@ -1930,3 +1977,16 @@
     "//net",
   ]
 }
+
+fuzzer_test("net_url_request_fuzzer") {
+  sources = [
+    "url_request/url_request_fuzzer.cc",
+  ]
+  deps = [
+    ":net_fuzzer_test_support",
+    ":test_support",
+    "//base",
+    "//net",
+  ]
+  dict = "data/http/http.dict"
+}
diff --git a/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java b/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
index 09485e3..de211a1 100644
--- a/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
+++ b/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
@@ -98,7 +98,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        ContextUtils.initApplicationContextForTests(Robolectric.application);
+        ContextUtils.initApplicationContextForJUnitTests(Robolectric.application);
     }
 
     @After
diff --git a/net/base/OWNERS b/net/base/OWNERS
index 8532b8c..ddc7882b 100644
--- a/net/base/OWNERS
+++ b/net/base/OWNERS
@@ -3,7 +3,3 @@
 per-file mime_sniffer*=rsleevi@chromium.org
 per-file mime_sniffer*=asanka@chromium.org
 per-file mime_sniffer*=mmenke@chromium.org
-
-# For all files relating to the network quality estimator.
-per-file network_quality*=bengr@chromium.org
-per-file socket_performance_watcher*=bengr@chromium.org
diff --git a/net/base/fuzzed_data_provider.cc b/net/base/fuzzed_data_provider.cc
new file mode 100644
index 0000000..c822a3a
--- /dev/null
+++ b/net/base/fuzzed_data_provider.cc
@@ -0,0 +1,69 @@
+// 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 "net/base/fuzzed_data_provider.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "base/logging.h"
+
+namespace net {
+
+FuzzedDataProvider::FuzzedDataProvider(const uint8_t* data, size_t size)
+    : remaining_data_(reinterpret_cast<const char*>(data), size) {}
+
+FuzzedDataProvider::~FuzzedDataProvider() {}
+
+base::StringPiece FuzzedDataProvider::ConsumeBytes(size_t num_bytes) {
+  num_bytes = std::min(num_bytes, remaining_data_.length());
+  base::StringPiece result(remaining_data_.data(), num_bytes);
+  remaining_data_ = remaining_data_.substr(num_bytes);
+  return result;
+}
+
+base::StringPiece FuzzedDataProvider::ConsumeRemainingBytes() {
+  return ConsumeBytes(remaining_data_.length());
+}
+
+uint32_t FuzzedDataProvider::ConsumeValueInRange(uint32_t min, uint32_t max) {
+  CHECK_LE(min, max);
+
+  uint32_t range = max - min;
+  uint32_t offset = 0;
+  uint32_t result = 0;
+
+  while ((range >> offset) > 0 && !remaining_data_.empty()) {
+    // Pull bytes off the end of the seed data. Experimentally, this seems to
+    // allow the fuzzer to more easily explore the input space. This makes
+    // sense, since it works by modifying inputs that caused new code to run,
+    // and this data is often used to encode length of data read by
+    // ConsumeBytes. Separating out read lengths makes it easier modify the
+    // contents of the data that is actually read.
+    uint8_t next_byte = remaining_data_.back();
+    remaining_data_.remove_suffix(1);
+    result = (result << 8) | next_byte;
+    offset += 8;
+  }
+
+  // Avoid division by 0, in the case |range + 1| results in overflow.
+  if (range == std::numeric_limits<uint32_t>::max())
+    return result;
+
+  return min + result % (range + 1);
+}
+
+bool FuzzedDataProvider::ConsumeBool() {
+  return (ConsumeUint8() & 0x01) == 0x01;
+}
+
+uint8_t FuzzedDataProvider::ConsumeUint8() {
+  return ConsumeValueInRange(0, 0xFF);
+}
+
+uint16_t FuzzedDataProvider::ConsumeUint16() {
+  return ConsumeValueInRange(0, 0xFFFF);
+}
+
+}  // namespace net
diff --git a/net/base/fuzzed_data_provider.h b/net/base/fuzzed_data_provider.h
new file mode 100644
index 0000000..bd8ddbeb
--- /dev/null
+++ b/net/base/fuzzed_data_provider.h
@@ -0,0 +1,62 @@
+// 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 NET_BASE_FUZZED_DATA_PROVIDER_H
+#define NET_BASE_FUZZED_DATA_PROVIDER_H
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "base/strings/string_piece.h"
+
+namespace net {
+
+// Utility class to break up fuzzer input for multiple consumers. Whenever run
+// on the same input, provides the same output, as long as its methods are
+// called in the same order, with the same arguments.
+class FuzzedDataProvider {
+ public:
+  // |data| is an array of length |size| that the FuzzedDataProvider wraps to
+  // provide more granular access. |data| must outlive the FuzzedDataProvider.
+  FuzzedDataProvider(const uint8_t* data, size_t size);
+  ~FuzzedDataProvider();
+
+  // Returns a StringPiece containing |num_bytes| of input data. If fewer than
+  // |num_bytes| of data remain, returns a shorter StringPiece containing all
+  // of the data that's left. The data pointed at by the returned StringPiece
+  // must not be used after the FuzzedDataProvider is destroyed.
+  base::StringPiece ConsumeBytes(size_t num_bytes);
+
+  // Returns a StringPiece containing all remaining bytes of the input data.
+  // The data pointed at by the returned StringPiece must not be used after the
+  // FuzzedDataProvider is destroyed.
+  base::StringPiece ConsumeRemainingBytes();
+
+  // Returns an unsigned number in the range [min, max] by consuming bytes from
+  // the input data. The value might not be uniformly distributed in the given
+  // range. If there's no input data left, always returns |min|. |min| must be
+  // less than or equal to |max|.
+  uint32_t ConsumeValueInRange(uint32_t min, uint32_t max);
+
+  // Returns a bool, or false when no data remains.
+  bool ConsumeBool();
+
+  // Returns a uint8_t from the input or 0 if nothing remains. This is
+  // equivalent to ConsumeValueInRange(0, 0xFF).
+  uint8_t ConsumeUint8();
+
+  // Returns a uint16_t from the input. If fewer than 2 bytes of data remain
+  // will fill the most significant bytes with 0. This is equivalent to
+  // ConsumeValueInRange(0, 0xFFFF).
+  uint16_t ConsumeUint16();
+
+ private:
+  base::StringPiece remaining_data_;
+
+  DISALLOW_COPY_AND_ASSIGN(FuzzedDataProvider);
+};
+
+}  // namespace net
+
+#endif  // NET_BASE_FUZZED_DATA_PROVIDER_H
diff --git a/net/cert/internal/parse_certificate.h b/net/cert/internal/parse_certificate.h
index d48c07c..8ea235c 100644
--- a/net/cert/internal/parse_certificate.h
+++ b/net/cert/internal/parse_certificate.h
@@ -44,7 +44,7 @@
 //     Note: Non-conforming CAs may issue certificates with serial numbers
 //     that are negative or zero.  Certificate users SHOULD be prepared to
 //     gracefully handle such certificates.
-bool VerifySerialNumber(const der::Input& value) WARN_UNUSED_RESULT;
+NET_EXPORT bool VerifySerialNumber(const der::Input& value) WARN_UNUSED_RESULT;
 
 // Parses a DER-encoded "Certificate" as specified by RFC 5280. Returns true on
 // success and sets the results in |out|.
diff --git a/net/cert/internal/parse_certificate_fuzzer.cc b/net/cert/internal/parse_certificate_fuzzer.cc
new file mode 100644
index 0000000..a2fc1c8
--- /dev/null
+++ b/net/cert/internal/parse_certificate_fuzzer.cc
@@ -0,0 +1,70 @@
+// 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 "net/cert/internal/certificate_policies.h"
+#include "net/cert/internal/extended_key_usage.h"
+#include "net/cert/internal/name_constraints.h"
+#include "net/cert/internal/parse_certificate.h"
+#include "net/cert/internal/parse_name.h"
+#include "net/cert/internal/signature_algorithm.h"
+#include "net/cert/internal/signature_policy.h"
+#include "net/cert/internal/verify_signed_data.h"
+
+namespace net {
+namespace {
+
+bool FindExtension(const der::Input& oid,
+                   std::map<der::Input, ParsedExtension>* extensions,
+                   ParsedExtension* extension) {
+  auto it = extensions->find(oid);
+  if (it == extensions->end())
+    return false;
+  *extension = it->second;
+  return true;
+}
+
+void ParseCertificateForFuzzer(const der::Input& in) {
+  ParsedCertificate cert;
+  if (!ParseCertificate(in, &cert))
+    return;
+  std::unique_ptr<SignatureAlgorithm> sig_alg(
+      SignatureAlgorithm::CreateFromDer(cert.signature_algorithm_tlv));
+
+  ParsedTbsCertificate tbs;
+  if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs))
+    return;
+
+  ignore_result(VerifySerialNumber(tbs.serial_number));
+  RDNSequence subject;
+  ignore_result(ParseName(tbs.subject_tlv, &subject));
+
+  std::map<der::Input, ParsedExtension> extensions;
+  if (tbs.has_extensions && ParseExtensions(tbs.extensions_tlv, &extensions)) {
+    ParsedExtension extension;
+    ParsedBasicConstraints basic_constraints;
+    der::BitString key_usage;
+    std::vector<der::Input> policies;
+    std::vector<der::Input> eku_oids;
+    if (FindExtension(BasicConstraintsOid(), &extensions, &extension))
+      ignore_result(ParseBasicConstraints(extension.value, &basic_constraints));
+    if (FindExtension(KeyUsageOid(), &extensions, &extension))
+      ignore_result(ParseKeyUsage(extension.value, &key_usage));
+    if (FindExtension(SubjectAltNameOid(), &extensions, &extension))
+      GeneralNames::CreateFromDer(extension.value);
+    if (FindExtension(CertificatePoliciesOid(), &extensions, &extension))
+      ParseCertificatePoliciesExtension(extension.value, &policies);
+    if (FindExtension(ExtKeyUsageOid(), &extensions, &extension))
+      ParseEKUExtension(extension.value, &eku_oids);
+  }
+}
+
+}  // namespace
+}  // namespace net
+
+extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
+  net::der::Input in(data, size);
+  net::ParseCertificateForFuzzer(in);
+  return 0;
+}
diff --git a/net/cert/internal/verify_name_match_fuzzer.cc b/net/cert/internal/verify_name_match_fuzzer.cc
new file mode 100644
index 0000000..8f51693
--- /dev/null
+++ b/net/cert/internal/verify_name_match_fuzzer.cc
@@ -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.
+
+#include "net/cert/internal/verify_name_match.h"
+
+#include "net/base/fuzzed_data_provider.h"
+#include "net/der/input.h"
+
+// Entry point for LibFuzzer.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  net::FuzzedDataProvider fuzzed_data(data, size);
+  size_t first_part_size = fuzzed_data.ConsumeUint16();
+  base::StringPiece first_part = fuzzed_data.ConsumeBytes(first_part_size);
+  base::StringPiece second_part = fuzzed_data.ConsumeRemainingBytes();
+
+  net::der::Input in1(first_part);
+  net::der::Input in2(second_part);
+  bool match = net::VerifyNameMatch(in1, in2);
+  bool reverse_order_match = net::VerifyNameMatch(in2, in1);
+  // Result should be the same regardless of argument order.
+  CHECK_EQ(match, reverse_order_match);
+  return 0;
+}
diff --git a/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc b/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc
new file mode 100644
index 0000000..f0a8828
--- /dev/null
+++ b/net/cert/internal/verify_name_match_verifynameinsubtree_fuzzer.cc
@@ -0,0 +1,25 @@
+// 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 "net/cert/internal/verify_name_match.h"
+
+#include "net/base/fuzzed_data_provider.h"
+#include "net/der/input.h"
+
+// Entry point for LibFuzzer.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  net::FuzzedDataProvider fuzzed_data(data, size);
+  size_t first_part_size = fuzzed_data.ConsumeUint16();
+  base::StringPiece first_part = fuzzed_data.ConsumeBytes(first_part_size);
+  base::StringPiece second_part = fuzzed_data.ConsumeRemainingBytes();
+
+  net::der::Input in1(first_part);
+  net::der::Input in2(second_part);
+  bool match = net::VerifyNameInSubtree(in1, in2);
+  bool reverse_order_match = net::VerifyNameInSubtree(in2, in1);
+  // If both InSubtree matches are true, then in1 == in2 (modulo normalization).
+  if (match && reverse_order_match)
+    CHECK(net::VerifyNameMatch(in1, in2));
+  return 0;
+}
diff --git a/net/data/http/http.dict b/net/data/http/http.dict
index 20a84968..2e750cb8 100644
--- a/net/data/http/http.dict
+++ b/net/data/http/http.dict
@@ -21,6 +21,7 @@
 "="
 ","
 "\""
+"-"
 
 # Status line components
 "HTTP"
@@ -54,25 +55,109 @@
 
 # Proxy authentication headers. Note that fuzzers don't support NTLM or
 # negotiate.
-"WWW-Authenticate"
-"Proxy-Authenticate"
+"WWW-Authenticate:"
+"Proxy-Authenticate:"
 "Basic"
 "Digest"
 "realm"
 "nonce"
 
-"Connection"
-"Proxy-Connection"
+"Connection:"
+"Proxy-Connection:"
 "Keep-Alive"
 "Close"
+"Upgrade"
 "\x0AConnection: Keep-Alive"
 "\x0AConnection: Close"
 "\x0AProxy-Connection: Keep-Alive"
 "\x0AProxy-Connection: Close"
 
-"Content-Length"
-"Transfer-Encoding"
+"Content-Length:"
+"Transfer-Encoding:"
 "chunked"
 "\x0AContent-Length: 0"
 "\x0AContent-Length: 500"
 "\x0ATransfer-Encoding: chunked\x0A\x0A5\x0A12345\x0A0\x0A\x0A"
+
+"Location:"
+"\x0ALocation: http://foo/"
+"\x0ALocation: http://bar/"
+"\x0ALocation: https://foo/"
+"\x0ALocation: https://bar/"
+
+"Accept-Ranges:"
+"bytes"
+"\x0AAccept-Ranges: bytes"
+
+"Content-Range:"
+
+"Age:"
+"\x0AAge: 0"
+"\x0AAge: 3153600000"
+
+"Cache-Control:"
+"max-age"
+"no-cache"
+"no-store"
+"must-revalidate"
+"\x0ACache-Control: max-age=3153600000"
+"\x0ACache-Control: max-age=0"
+"\x0ACache-Control: no-cache"
+"\x0ACache-Control: no-store"
+"\x0ACache-Control: must-revalidate"
+
+"Content-Disposition:"
+"attachment"
+"filename"
+
+"Content-Encoding:"
+"gzip"
+"deflate"
+"sdch"
+"br"
+"\x0AContent-Encoding: gzip"
+"\x0AContent-Encoding: deflate"
+"\x0AContent-Encoding: sdch"
+"\x0AContent-Encoding: br"
+
+"Date:"
+"Fri, 01 Apr, 2050 14:14:14 GMT"
+"Mon, 28 Mar, 2016 04:04:04 GMT"
+"\x0ADate: Fri, 01 Apr, 2050 14:14:14 GMT"
+"\x0ADate: Mon, 28 Mar, 2016 04:04:04 GMT"
+
+"Last-Modified:"
+"\x0ALast-Modified: Fri, 01 Apr, 2050 14:14:14 GMT"
+"\x0ALast-Modified: Mon, 28 Mar, 2016 04:04:04 GMT"
+
+"Expires:"
+"\x0AExpires: Fri, 01 Apr, 2050 14:14:14 GMT"
+"\x0AExpires: Mon, 28 Mar, 2016 04:04:04 GMT"
+
+"Set-Cookie:"
+"Expires"
+"Max-Age"
+"Domain"
+"Path"
+"Secure"
+"HttpOnly"
+"Priority"
+"Low"
+"Medium"
+"High"
+"SameSite"
+"Strict"
+"Lax"
+"\x0ASet-Cookie: foo=bar"
+"\x0ASet-Cookie: foo2=bar2;HttpOnly;Priority=Low;SameSite=Strict;Path=/"
+"\x0ASet-Cookie: foo=chicken;SameSite=Lax"
+
+"Strict-Transport-Security:"
+"includeSubDomains"
+
+"Vary:"
+"\x0AVary: Cookie"
+"\x0AVary: Age"
+
+"ETag:"
+"\x0AETag: jumboshrimp"
diff --git a/net/dns/address_sorter_posix_unittest.cc b/net/dns/address_sorter_posix_unittest.cc
index 1f3df9ff..997ac48 100644
--- a/net/dns/address_sorter_posix_unittest.cc
+++ b/net/dns/address_sorter_posix_unittest.cc
@@ -9,9 +9,9 @@
 #include "base/macros.h"
 #include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
 #include "net/socket/client_socket_factory.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/socket/stream_socket.h"
 #include "net/udp/datagram_client_socket.h"
diff --git a/net/dns/dns_hosts_parse_fuzzer.cc b/net/dns/dns_hosts_parse_fuzzer.cc
new file mode 100644
index 0000000..194cb2b
--- /dev/null
+++ b/net/dns/dns_hosts_parse_fuzzer.cc
@@ -0,0 +1,22 @@
+// 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 <string>
+
+#include "net/dns/dns_hosts.h"
+
+// Entry point for LibFuzzer.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  std::string input(reinterpret_cast<const char*>(data), size);
+  net::DnsHosts dns_hosts;
+  net::ParseHostsWithCommaModeForTesting(input, &dns_hosts,
+                                         net::PARSE_HOSTS_COMMA_IS_TOKEN);
+  dns_hosts.clear();
+  net::ParseHostsWithCommaModeForTesting(input, &dns_hosts,
+                                         net::PARSE_HOSTS_COMMA_IS_WHITESPACE);
+  return 0;
+}
diff --git a/net/dns/dns_session_unittest.cc b/net/dns/dns_session_unittest.cc
index 6eabefb..88cefbe0 100644
--- a/net/dns/dns_session_unittest.cc
+++ b/net/dns/dns_session_unittest.cc
@@ -12,10 +12,10 @@
 #include "base/rand_util.h"
 #include "base/stl_util.h"
 #include "net/base/ip_address.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/dns/dns_protocol.h"
 #include "net/dns/dns_socket_pool.h"
 #include "net/log/net_log.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socket_test_util.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/socket/stream_socket.h"
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc
index 602349fd..125ee0c8 100644
--- a/net/http/bidirectional_stream.cc
+++ b/net/http/bidirectional_stream.cc
@@ -5,6 +5,7 @@
 #include "net/http/bidirectional_stream.h"
 
 #include <memory>
+#include <string>
 
 #include "base/bind.h"
 #include "base/location.h"
@@ -13,12 +14,16 @@
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "base/values.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
 #include "net/http/bidirectional_stream_request_info.h"
+#include "net/http/http_log_util.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_stream.h"
+#include "net/log/net_log_capture_mode.h"
+#include "net/spdy/spdy_header_block.h"
 #include "net/spdy/spdy_http_utils.h"
 #include "net/ssl/ssl_cert_request_info.h"
 #include "net/ssl/ssl_config.h"
@@ -26,6 +31,32 @@
 
 namespace net {
 
+namespace {
+
+std::unique_ptr<base::Value> NetLogHeadersCallback(
+    const SpdyHeaderBlock* headers,
+    NetLogCaptureMode capture_mode) {
+  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+  dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
+  return std::move(dict);
+}
+
+std::unique_ptr<base::Value> NetLogCallback(const GURL* url,
+                                            const std::string* method,
+                                            const HttpRequestHeaders* headers,
+                                            NetLogCaptureMode capture_mode) {
+  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+  dict->SetString("url", url->possibly_invalid_spec());
+  dict->SetString("method", *method);
+  std::string empty;
+  std::unique_ptr<base::Value> headers_param(
+      headers->NetLogCallback(&empty, capture_mode));
+  dict->Set("headers", std::move(headers_param));
+  return std::move(dict);
+}
+
+}  // namespace
+
 BidirectionalStream::Delegate::Delegate() {}
 
 void BidirectionalStream::Delegate::OnStreamReady() {}
@@ -85,10 +116,19 @@
   // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady
   // synchronously.
   DCHECK(!stream_impl_);
+  if (net_log_.IsCapturing()) {
+    net_log_.BeginEvent(
+        NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE,
+        base::Bind(&NetLogCallback, &request_info_->url, &request_info_->method,
+                   base::Unretained(&request_info_->extra_headers)));
+  }
 }
 
 BidirectionalStream::~BidirectionalStream() {
   Cancel();
+  if (net_log_.IsCapturing()) {
+    net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE);
+  }
 }
 
 int BidirectionalStream::ReadData(IOBuffer* buf, int buf_len) {
@@ -173,7 +213,10 @@
     delegate_->OnFailed(ERR_FAILED);
     return;
   }
-
+  if (net_log_.IsCapturing()) {
+    net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS,
+                      base::Bind(&NetLogHeadersCallback, &response_headers));
+  }
   session_->http_stream_factory()->ProcessAlternativeServices(
       session_, response_info.headers.get(),
       url::SchemeHostPort(request_info_->url));
@@ -183,9 +226,11 @@
 void BidirectionalStream::OnDataRead(int bytes_read) {
   DCHECK(read_buffer_);
 
-  net_log_.AddByteTransferEvent(
-      NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read,
-      read_buffer_->data());
+  if (net_log_.IsCapturing()) {
+    net_log_.AddByteTransferEvent(
+        NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read,
+        read_buffer_->data());
+  }
   read_buffer_ = nullptr;
   delegate_->OnDataRead(bytes_read);
 }
@@ -194,10 +239,12 @@
   DCHECK(!write_buffer_list_.empty());
   DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size());
 
-  for (size_t i = 0; i < write_buffer_list_.size(); ++i) {
-    net_log_.AddByteTransferEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT,
-                                  write_buffer_len_list_[i],
-                                  write_buffer_list_[i]->data());
+  if (net_log_.IsCapturing()) {
+    for (size_t i = 0; i < write_buffer_list_.size(); ++i) {
+      net_log_.AddByteTransferEvent(
+          NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT,
+          write_buffer_len_list_[i], write_buffer_list_[i]->data());
+    }
   }
   write_buffer_list_.clear();
   write_buffer_len_list_.clear();
@@ -205,6 +252,10 @@
 }
 
 void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) {
+  if (net_log_.IsCapturing()) {
+    net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS,
+                      base::Bind(&NetLogHeadersCallback, &trailers));
+  }
   delegate_->OnTrailersReceived(trailers);
 }
 
diff --git a/net/http/bidirectional_stream_unittest.cc b/net/http/bidirectional_stream_unittest.cc
index 8ecb3f22..2b295361 100644
--- a/net/http/bidirectional_stream_unittest.cc
+++ b/net/http/bidirectional_stream_unittest.cc
@@ -480,7 +480,8 @@
             delegate->GetTotalReceivedBytes());
 }
 
-TEST_F(BidirectionalStreamTest, TestContainFullBytes) {
+// Tests that the NetLog contains correct entries.
+TEST_F(BidirectionalStreamTest, TestNetLogContainEntries) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
   std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
@@ -496,7 +497,12 @@
   std::unique_ptr<SpdySerializedFrame> response_body_frame1(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
   std::unique_ptr<SpdySerializedFrame> response_body_frame2(
-      spdy_util_.ConstructSpdyBodyFrame(1, true));
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+
+  SpdyHeaderBlock trailers;
+  trailers["foo"] = "bar";
+  std::unique_ptr<SpdySerializedFrame> response_trailers(
+      spdy_util_.ConstructSpdyResponseHeaders(1, trailers, true));
 
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
@@ -504,7 +510,8 @@
       CreateMockRead(*response_body_frame1, 4),
       MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause.
       CreateMockRead(*response_body_frame2, 6),
-      MockRead(ASYNC, 0, 7),
+      CreateMockRead(*response_trailers, 7),
+      MockRead(ASYNC, 0, 8),
   };
 
   HostPortPair host_port_pair("www.example.org", 443);
@@ -558,16 +565,31 @@
   EXPECT_EQ(1, delegate->on_data_read_count());
   EXPECT_EQ(1, delegate->on_data_sent_count());
   EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
+  EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
   EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
             delegate->GetTotalSentBytes());
   EXPECT_EQ(CountReadBytes(reads, arraysize(reads)),
             delegate->GetTotalReceivedBytes());
 
+  // Destroy the delegate will destroy the stream, so we can get an end event
+  // for BIDIRECTIONAL_STREAM_ALIVE.
+  delegate.reset();
   TestNetLogEntry::List entries;
   net_log_.GetEntries(&entries);
-  // Sent bytes. Sending data is always asynchronous.
   size_t index = ExpectLogContainsSomewhere(
-      entries, 0, NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT,
+      entries, 0, NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE, NetLog::PHASE_BEGIN);
+  // Headers received should happen after BIDIRECTIONAL_STREAM_ALIVE.
+  index = ExpectLogContainsSomewhere(
+      entries, index, NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS,
+      NetLog::PHASE_NONE);
+  // Trailers received should happen after headers received. It might happen
+  // before the reads complete.
+  ExpectLogContainsSomewhere(entries, index,
+                             NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS,
+                             NetLog::PHASE_NONE);
+  // Sent bytes. Sending data is always asynchronous.
+  index = ExpectLogContainsSomewhere(
+      entries, index, NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT,
       NetLog::PHASE_NONE);
   TestNetLogEntry entry = entries[index];
   EXPECT_EQ(NetLog::SOURCE_BIDIRECTIONAL_STREAM, entry.source.type);
@@ -583,6 +605,9 @@
       NetLog::PHASE_NONE);
   entry = entries[index];
   EXPECT_EQ(NetLog::SOURCE_BIDIRECTIONAL_STREAM, entry.source.type);
+  ExpectLogContainsSomewhere(entries, index,
+                             NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE,
+                             NetLog::PHASE_END);
 }
 
 TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) {
@@ -927,16 +952,19 @@
   std::unique_ptr<SpdySerializedFrame> body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
 
-  SpdyHeaderBlock late_headers;
-  late_headers["foo"] = "bar";
-  std::unique_ptr<SpdySerializedFrame> trailers(
-      spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, true));
+  SpdyHeaderBlock trailers;
+  trailers["foo"] = "bar";
+  std::unique_ptr<SpdySerializedFrame> response_trailers(
+      spdy_util_.ConstructSpdyResponseHeaders(1, trailers, true));
 
   MockRead reads[] = {
-      CreateMockRead(*resp, 1),           CreateMockRead(*body_frame, 2),
-      CreateMockRead(*body_frame, 3),     CreateMockRead(*body_frame, 4),
+      CreateMockRead(*resp, 1),
+      CreateMockRead(*body_frame, 2),
+      CreateMockRead(*body_frame, 3),
+      CreateMockRead(*body_frame, 4),
       MockRead(ASYNC, ERR_IO_PENDING, 5),  // Force a pause.
-      CreateMockRead(*trailers, 6),       MockRead(SYNCHRONOUS, 0, 7),
+      CreateMockRead(*response_trailers, 6),
+      MockRead(SYNCHRONOUS, 0, 7),
   };
 
   HostPortPair host_port_pair("www.example.org", 443);
@@ -1308,14 +1336,14 @@
   std::unique_ptr<SpdySerializedFrame> response_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
 
-  SpdyHeaderBlock late_headers;
-  late_headers["foo"] = "bar";
-  std::unique_ptr<SpdySerializedFrame> trailers(
-      spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, true));
+  SpdyHeaderBlock trailers;
+  trailers["foo"] = "bar";
+  std::unique_ptr<SpdySerializedFrame> response_trailers(
+      spdy_util_.ConstructSpdyResponseHeaders(1, trailers, true));
 
   MockRead reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*response_body_frame, 2),
-      CreateMockRead(*trailers, 3), MockRead(ASYNC, 0, 5),
+      CreateMockRead(*response_trailers, 3), MockRead(ASYNC, 0, 5),
   };
 
   HostPortPair host_port_pair("www.example.org", 443);
diff --git a/net/http/http_log_util.cc b/net/http/http_log_util.cc
index 8146f0d..9d86c4de 100644
--- a/net/http/http_log_util.cc
+++ b/net/http/http_log_util.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "base/values.h"
 #include "net/http/http_auth_challenge_tokenizer.h"
 #include "net/http/http_auth_scheme.h"
 #include "net/http/http_util.h"
@@ -87,4 +88,18 @@
          std::string(" bytes were stripped]");
 }
 
+std::unique_ptr<base::ListValue> ElideSpdyHeaderBlockForNetLog(
+    const SpdyHeaderBlock& headers,
+    NetLogCaptureMode capture_mode) {
+  std::unique_ptr<base::ListValue> headers_list(new base::ListValue());
+  for (SpdyHeaderBlock::const_iterator it = headers.begin();
+       it != headers.end(); ++it) {
+    headers_list->AppendString(
+        it->first.as_string() + ": " +
+        ElideHeaderValueForNetLog(capture_mode, it->first.as_string(),
+                                  it->second.as_string()));
+  }
+  return headers_list;
+}
+
 }  // namespace net
diff --git a/net/http/http_log_util.h b/net/http/http_log_util.h
index 5fda79c..ce47139 100644
--- a/net/http/http_log_util.h
+++ b/net/http/http_log_util.h
@@ -10,6 +10,11 @@
 #include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 #include "net/log/net_log.h"
+#include "net/spdy/spdy_header_block.h"
+
+namespace base {
+class ListValue;
+}  // namespace base
 
 namespace net {
 
@@ -26,6 +31,11 @@
     NetLogCaptureMode capture_mode,
     base::StringPiece debug_data);
 
+// Given a SpdyHeaderBlock, return its base::ListValue representation.
+std::unique_ptr<base::ListValue> ElideSpdyHeaderBlockForNetLog(
+    const SpdyHeaderBlock& headers,
+    NetLogCaptureMode capture_mode);
+
 }  // namespace net
 
 #endif  // NET_HTTP_HTTP_LOG_UTIL_
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 7bf2cdb..66b3866d 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -115,7 +115,6 @@
       quic_max_number_of_lossy_connections(0),
       quic_packet_loss_threshold(1.0f),
       quic_socket_receive_buffer_size(kQuicSocketReceiveBufferSize),
-      quic_delay_tcp_race(false),
       quic_max_server_configs_stored_in_properties(0u),
       quic_clock(NULL),
       quic_random(NULL),
@@ -134,7 +133,7 @@
       quic_disable_bidirectional_streams(false),
       proxy_delegate(NULL),
       enable_token_binding(false) {
-  quic_supported_versions.push_back(QUIC_VERSION_30);
+  quic_supported_versions.push_back(QUIC_VERSION_31);
 }
 
 HttpNetworkSession::Params::Params(const Params& other) = default;
@@ -181,7 +180,6 @@
           params.quic_threshold_public_resets_post_handshake,
           params.quic_threshold_timeouts_streams_open,
           params.quic_socket_receive_buffer_size,
-          params.quic_delay_tcp_race,
           params.quic_max_server_configs_stored_in_properties,
           params.quic_close_sessions_on_ip_change,
           params.disable_quic_on_timeout_with_open_streams,
@@ -336,7 +334,7 @@
   dict->SetInteger("max_number_of_lossy_connections",
                    params_.quic_max_number_of_lossy_connections);
   dict->SetDouble("packet_loss_threshold", params_.quic_packet_loss_threshold);
-  dict->SetBoolean("delay_tcp_race", params_.quic_delay_tcp_race);
+  dict->SetBoolean("delay_tcp_race", true);
   dict->SetInteger("max_server_configs_stored_in_properties",
                    params_.quic_max_server_configs_stored_in_properties);
   dict->SetInteger("idle_connection_timeout_seconds",
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 1de42b7..c3cea43b 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -143,9 +143,6 @@
     float quic_packet_loss_threshold;
     // Size in bytes of the QUIC DUP socket receive buffer.
     int quic_socket_receive_buffer_size;
-    // Delay starting a TCP connection when QUIC believes it can speak
-    // 0-RTT to a server.
-    bool quic_delay_tcp_race;
     // Maximum number of server configs that are to be stored in
     // HttpServerProperties, instead of the disk cache.
     size_t quic_max_server_configs_stored_in_properties;
diff --git a/net/http/http_proxy_client_socket_fuzzer.cc b/net/http/http_proxy_client_socket_fuzzer.cc
index 2fab8e0..8c4b80e 100644
--- a/net/http/http_proxy_client_socket_fuzzer.cc
+++ b/net/http/http_proxy_client_socket_fuzzer.cc
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "net/base/address_list.h"
 #include "net/base/auth.h"
+#include "net/base/fuzzed_data_provider.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/test_completion_callback.h"
 #include "net/http/http_auth_cache.h"
@@ -33,19 +34,13 @@
 // class for details.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   // Use a test NetLog, to exercise logging code.
-  net::BoundTestNetLog bound_test_net_log;
+  net::TestNetLog test_net_log;
 
-  // Use last byte to determine if the HttpProxyClientSocket should be told the
-  // underlying socket is HTTPS.
-  bool is_https_proxy = 0;
-  if (size > 0) {
-    is_https_proxy = !(data[size - 1] & 1);
-    size--;
-  }
+  net::FuzzedDataProvider data_provider(data, size);
 
   net::TestCompletionCallback callback;
   std::unique_ptr<net::FuzzedSocket> fuzzed_socket(
-      new net::FuzzedSocket(data, size, bound_test_net_log.bound()));
+      new net::FuzzedSocket(&data_provider, &test_net_log));
   CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback()));
 
   std::unique_ptr<net::ClientSocketHandle> socket_handle(
@@ -65,6 +60,9 @@
       new net::HttpAuthController(net::HttpAuth::AUTH_PROXY,
                                   GURL("http://proxy:42/"), &auth_cache,
                                   &auth_handler_factory));
+  // Determine if the HttpProxyClientSocket should be told the underlying socket
+  // is HTTPS.
+  bool is_https_proxy = data_provider.ConsumeBool();
   net::HttpProxyClientSocket socket(
       socket_handle.release(), "Bond/007", net::HostPortPair("foo", 80),
       net::HostPortPair("proxy", 42), auth_controller.get(), true /* tunnel */,
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index 6c7380d..962527c 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -1628,9 +1628,9 @@
   EXPECT_EQ(OK, stream_impl->ReadData(buffer.get(), 1));
   EXPECT_EQ(kProtoQUIC1SPDY3, stream_impl->GetProtocol());
   EXPECT_EQ("200", delegate.response_headers().find(":status")->second);
-  EXPECT_EQ(1, GetSocketPoolGroupCount(session()->GetTransportSocketPool(
+  EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool(
                    HttpNetworkSession::NORMAL_SOCKET_POOL)));
-  EXPECT_EQ(1, GetSocketPoolGroupCount(session()->GetSSLSocketPool(
+  EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetSSLSocketPool(
                    HttpNetworkSession::NORMAL_SOCKET_POOL)));
   EXPECT_EQ(0, GetSocketPoolGroupCount(session()->GetTransportSocketPool(
                    HttpNetworkSession::WEBSOCKET_SOCKET_POOL)));
diff --git a/net/http/http_stream_parser_fuzzer.cc b/net/http/http_stream_parser_fuzzer.cc
index 78e3955..421aaac 100644
--- a/net/http/http_stream_parser_fuzzer.cc
+++ b/net/http/http_stream_parser_fuzzer.cc
@@ -15,6 +15,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "net/base/fuzzed_data_provider.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
@@ -33,8 +34,9 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   net::TestCompletionCallback callback;
   net::BoundTestNetLog bound_test_net_log;
-  std::unique_ptr<net::FuzzedSocket> fuzzed_socket(
-      new net::FuzzedSocket(data, size, bound_test_net_log.bound()));
+  net::FuzzedDataProvider data_provider(data, size);
+  std::unique_ptr<net::FuzzedSocket> fuzzed_socket(new net::FuzzedSocket(
+      &data_provider, bound_test_net_log.bound().net_log()));
   CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback()));
 
   net::ClientSocketHandle socket_handle;
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index 1f7a4688..e699e0c 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -1170,6 +1170,15 @@
 // BidirectionalStream
 // ------------------------------------------------------------------------
 
+// Marks the creation/destruction of a net::BidirectionalStream.
+// The following parameters are attached:
+//   {
+//      "url": <The URL being used>,
+//      "method": <The HTTP method being used>,
+//      "headers": <The list of header:value pairs>,
+//   }
+EVENT_TYPE(BIDIRECTIONAL_STREAM_ALIVE)
+
 // The specified number of bytes were sent on the stream.  Depending on the
 // source of the event, may be logged either once the data is sent, or when it
 // is queued to be sent.
@@ -1190,6 +1199,20 @@
 //   }
 EVENT_TYPE(BIDIRECTIONAL_STREAM_BYTES_RECEIVED)
 
+// This event is sent for receiving headers on the stream.
+// The following parameters are attached:
+//   {
+//     "headers": <The list of header:value pairs>,
+//   }
+EVENT_TYPE(BIDIRECTIONAL_STREAM_RECV_HEADERS)
+
+// This event is sent for receiving trailers on the stream.
+// The following parameters are attached:
+//   {
+//     "headers": <The list of header:value pairs>,
+//   }
+EVENT_TYPE(BIDIRECTIONAL_STREAM_RECV_TRAILERS)
+
 // ------------------------------------------------------------------------
 // SpdySession
 // ------------------------------------------------------------------------
diff --git a/net/net.gypi b/net/net.gypi
index 78c47c1..657582f7 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -62,8 +62,6 @@
       'base/registry_controlled_domains/registry_controlled_domain.h',
       'base/sockaddr_storage.cc',
       'base/sockaddr_storage.h',
-      'base/socket_performance_watcher.h',
-      'base/socket_performance_watcher_factory.h',
       'base/sys_addrinfo.h',
       'base/url_util.cc',
       'base/url_util.h',
@@ -181,6 +179,8 @@
       'socket/next_proto.cc',
       'socket/next_proto.h',
       'socket/socket.h',
+      'socket/socket_performance_watcher.h',
+      'socket/socket_performance_watcher_factory.h',
       'socket/ssl_client_socket.cc',
       'socket/ssl_client_socket.h',
       'socket/ssl_client_socket_impl.cc',
@@ -458,7 +458,6 @@
       'base/elements_upload_data_stream.cc',
       'base/elements_upload_data_stream.h',
       'base/expiring_cache.h',
-      'base/external_estimate_provider.h',
       'base/file_stream.cc',
       'base/file_stream.h',
       'base/file_stream_context.cc',
@@ -518,8 +517,6 @@
       'base/network_interfaces_linux.cc',
       'base/network_interfaces_mac.cc',
       'base/network_interfaces_win.cc',
-      'base/network_quality_estimator.cc',
-      'base/network_quality_estimator.h',
       'base/platform_mime_util.h',
       'base/platform_mime_util_linux.cc',
       'base/platform_mime_util_mac.mm',
@@ -918,6 +915,9 @@
       'http/url_security_manager.h',
       'http/url_security_manager_posix.cc',
       'http/url_security_manager_win.cc',
+      'nqe/external_estimate_provider.h',
+      'nqe/network_quality_estimator.cc',
+      'nqe/network_quality_estimator.h',
       'proxy/dhcp_proxy_script_adapter_fetcher_win.cc',
       'proxy/dhcp_proxy_script_adapter_fetcher_win.h',
       'proxy/dhcp_proxy_script_fetcher.cc',
@@ -1331,7 +1331,6 @@
       'base/network_change_notifier_unittest.cc',
       'base/network_change_notifier_win_unittest.cc',
       'base/network_interfaces_unittest.cc',
-      'base/network_quality_estimator_unittest.cc',
       'base/parse_number_unittest.cc',
       'base/port_util_unittest.cc',
       'base/prioritized_dispatcher_unittest.cc',
@@ -1507,6 +1506,7 @@
       'log/net_log_util_unittest.cc',
       'log/trace_net_log_observer_unittest.cc',
       'log/write_to_file_net_log_observer_unittest.cc',
+      'nqe/network_quality_estimator_unittest.cc',
       'proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc',
       'proxy/dhcp_proxy_script_fetcher_factory_unittest.cc',
       'proxy/dhcp_proxy_script_fetcher_win_unittest.cc',
diff --git a/net/nqe/OWNERS b/net/nqe/OWNERS
new file mode 100644
index 0000000..d0e5b09f
--- /dev/null
+++ b/net/nqe/OWNERS
@@ -0,0 +1 @@
+bengr@chromium.org
\ No newline at end of file
diff --git a/net/base/external_estimate_provider.h b/net/nqe/external_estimate_provider.h
similarity index 93%
rename from net/base/external_estimate_provider.h
rename to net/nqe/external_estimate_provider.h
index c4480cf1..7fd58f5 100644
--- a/net/base/external_estimate_provider.h
+++ b/net/nqe/external_estimate_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_BASE_EXTERNAL_ESTIMATE_PROVIDER_H_
-#define NET_BASE_EXTERNAL_ESTIMATE_PROVIDER_H_
+#ifndef NET_NQE_EXTERNAL_ESTIMATE_PROVIDER_H_
+#define NET_NQE_EXTERNAL_ESTIMATE_PROVIDER_H_
 
 #include <stdint.h>
 
@@ -69,4 +69,4 @@
 
 }  // namespace net
 
-#endif  // NET_BASE_EXTERNAL_ESTIMATE_PROVIDER_H_
+#endif  // NET_NQE_EXTERNAL_ESTIMATE_PROVIDER_H_
diff --git a/net/base/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
similarity index 99%
rename from net/base/network_quality_estimator.cc
rename to net/nqe/network_quality_estimator.cc
index a9ad1b9..1f720c8 100644
--- a/net/base/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "net/base/network_quality_estimator.h"
+#include "net/nqe/network_quality_estimator.h"
 
 #include <float.h>
 #include <algorithm>
@@ -21,8 +21,8 @@
 #include "net/base/load_flags.h"
 #include "net/base/load_timing_info.h"
 #include "net/base/network_interfaces.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/url_util.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/url_request/url_request.h"
 #include "url/gurl.h"
 
@@ -1117,17 +1117,14 @@
 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality(
     const NetworkQuality& network_quality)
     : last_update_time_(base::TimeTicks::Now()),
-      network_quality_(network_quality) {
-}
+      network_quality_(network_quality) {}
 
 NetworkQualityEstimator::CachedNetworkQuality::CachedNetworkQuality(
     const CachedNetworkQuality& other)
     : last_update_time_(other.last_update_time_),
-      network_quality_(other.network_quality_) {
-}
+      network_quality_(other.network_quality_) {}
 
-NetworkQualityEstimator::CachedNetworkQuality::~CachedNetworkQuality() {
-}
+NetworkQualityEstimator::CachedNetworkQuality::~CachedNetworkQuality() {}
 
 bool NetworkQualityEstimator::CachedNetworkQuality::OlderThan(
     const CachedNetworkQuality& cached_network_quality) const {
@@ -1153,8 +1150,8 @@
 NetworkQualityEstimator::NetworkQuality::~NetworkQuality() {}
 
 NetworkQualityEstimator::NetworkQuality&
-    NetworkQualityEstimator::NetworkQuality::
-    operator=(const NetworkQuality& other) {
+NetworkQualityEstimator::NetworkQuality::operator=(
+    const NetworkQuality& other) {
   rtt_ = other.rtt_;
   downstream_throughput_kbps_ = other.downstream_throughput_kbps_;
   return *this;
diff --git a/net/base/network_quality_estimator.h b/net/nqe/network_quality_estimator.h
similarity index 98%
rename from net/base/network_quality_estimator.h
rename to net/nqe/network_quality_estimator.h
index 0a386e9..dc4e995 100644
--- a/net/base/network_quality_estimator.h
+++ b/net/nqe/network_quality_estimator.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
-#define NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
+#ifndef NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_
+#define NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_
 
 #include <stddef.h>
 #include <stdint.h>
@@ -22,10 +22,10 @@
 #include "base/observer_list.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
-#include "net/base/external_estimate_provider.h"
 #include "net/base/net_export.h"
 #include "net/base/network_change_notifier.h"
-#include "net/base/socket_performance_watcher_factory.h"
+#include "net/nqe/external_estimate_provider.h"
+#include "net/socket/socket_performance_watcher_factory.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -668,4 +668,4 @@
 
 }  // namespace net
 
-#endif  // NET_BASE_NETWORK_QUALITY_ESTIMATOR_H_
+#endif  // NET_NQE_NETWORK_QUALITY_ESTIMATOR_H_
diff --git a/net/base/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc
similarity index 99%
rename from net/base/network_quality_estimator_unittest.cc
rename to net/nqe/network_quality_estimator_unittest.cc
index d45fcf93..c8827de5 100644
--- a/net/base/network_quality_estimator_unittest.cc
+++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "net/base/network_quality_estimator.h"
+#include "net/nqe/network_quality_estimator.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -23,12 +23,12 @@
 #include "base/test/histogram_tester.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "net/base/external_estimate_provider.h"
 #include "net/base/load_flags.h"
 #include "net/base/network_change_notifier.h"
-#include "net/base/socket_performance_watcher.h"
-#include "net/base/socket_performance_watcher_factory.h"
 #include "net/http/http_status_code.h"
+#include "net/nqe/external_estimate_provider.h"
+#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_performance_watcher_factory.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc
index db2c071e..44dc0f0 100644
--- a/net/quic/quic_chromium_client_session.cc
+++ b/net/quic/quic_chromium_client_session.cc
@@ -131,26 +131,13 @@
   return std::move(dict);
 }
 
-std::unique_ptr<base::ListValue> SpdyHeaderBlockToListValue(
-    const SpdyHeaderBlock& headers,
-    NetLogCaptureMode capture_mode) {
-  std::unique_ptr<base::ListValue> headers_list(new base::ListValue());
-  for (const auto& it : headers) {
-    headers_list->AppendString(
-        it.first.as_string() + ": " +
-        ElideHeaderValueForNetLog(capture_mode, it.first.as_string(),
-                                  it.second.as_string()));
-  }
-  return headers_list;
-}
-
 std::unique_ptr<base::Value> NetLogQuicPushPromiseReceivedCallback(
     const SpdyHeaderBlock* headers,
     SpdyStreamId stream_id,
     SpdyStreamId promised_stream_id,
     NetLogCaptureMode capture_mode) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
+  dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   dict->SetInteger("id", stream_id);
   dict->SetInteger("promised_stream_id", promised_stream_id);
   return std::move(dict);
diff --git a/net/quic/quic_chromium_client_session.h b/net/quic/quic_chromium_client_session.h
index f40be75..fff5d972 100644
--- a/net/quic/quic_chromium_client_session.h
+++ b/net/quic/quic_chromium_client_session.h
@@ -20,7 +20,6 @@
 #include "base/time/time.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_error_details.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/cert/ct_verify_result.h"
 #include "net/proxy/proxy_server.h"
 #include "net/quic/quic_chromium_client_stream.h"
@@ -30,6 +29,7 @@
 #include "net/quic/quic_crypto_client_stream.h"
 #include "net/quic/quic_protocol.h"
 #include "net/quic/quic_time.h"
+#include "net/socket/socket_performance_watcher.h"
 
 namespace net {
 
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc
index f8e17f9..15f50be 100644
--- a/net/quic/quic_chromium_client_session_test.cc
+++ b/net/quic/quic_chromium_client_session_test.cc
@@ -11,7 +11,6 @@
 #include "base/memory/ptr_util.h"
 #include "base/rand_util.h"
 #include "base/thread_task_runner_handle.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
 #include "net/base/test_data_directory.h"
 #include "net/cert/cert_verify_result.h"
@@ -39,6 +38,7 @@
 #include "net/quic/test_tools/quic_test_packet_maker.h"
 #include "net/quic/test_tools/quic_test_utils.h"
 #include "net/quic/test_tools/simple_quic_framer.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socket_test_util.h"
 #include "net/spdy/spdy_test_utils.h"
 #include "net/test/cert_test_util.h"
diff --git a/net/quic/quic_connection_logger.h b/net/quic/quic_connection_logger.h
index a8f657db..96cb56e 100644
--- a/net/quic/quic_connection_logger.h
+++ b/net/quic/quic_connection_logger.h
@@ -12,11 +12,11 @@
 #include "base/macros.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/network_change_notifier.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/log/net_log.h"
 #include "net/quic/quic_connection.h"
 #include "net/quic/quic_protocol.h"
 #include "net/quic/quic_spdy_session.h"
+#include "net/socket/socket_performance_watcher.h"
 
 namespace net {
 namespace test {
diff --git a/net/quic/quic_connection_logger_unittest.cc b/net/quic/quic_connection_logger_unittest.cc
index 268e7f7..a92ad7ae 100644
--- a/net/quic/quic_connection_logger_unittest.cc
+++ b/net/quic/quic_connection_logger_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "net/quic/quic_connection_logger.h"
 
-#include "net/base/socket_performance_watcher.h"
 #include "net/quic/quic_protocol.h"
 #include "net/quic/test_tools/quic_test_utils.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 395f8cc..b24dabf 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -15,7 +15,6 @@
 #include "net/base/chunked_upload_data_stream.h"
 #include "net/base/elements_upload_data_stream.h"
 #include "net/base/net_errors.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
 #include "net/base/test_data_directory.h"
 #include "net/base/upload_bytes_element_reader.h"
@@ -47,6 +46,7 @@
 #include "net/quic/test_tools/quic_test_packet_maker.h"
 #include "net/quic/test_tools/quic_test_utils.h"
 #include "net/quic/test_tools/test_task_runner.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socket_test_util.h"
 #include "net/spdy/spdy_frame_builder.h"
 #include "net/spdy/spdy_framer.h"
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index d14e2f8..cf7d65ed 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -13,8 +13,6 @@
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "net/base/chunked_upload_data_stream.h"
-#include "net/base/socket_performance_watcher.h"
-#include "net/base/socket_performance_watcher_factory.h"
 #include "net/base/test_completion_callback.h"
 #include "net/base/test_data_directory.h"
 #include "net/cert/mock_cert_verifier.h"
@@ -47,6 +45,8 @@
 #include "net/quic/test_tools/quic_test_utils.h"
 #include "net/socket/client_socket_factory.h"
 #include "net/socket/mock_client_socket_pool_manager.h"
+#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_performance_watcher_factory.h"
 #include "net/socket/socket_test_util.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/spdy/spdy_frame_builder.h"
@@ -646,10 +646,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   params_.parse_alternative_services = false;
   params_.enable_alternative_service_with_different_host = false;
   CreateSession();
@@ -773,7 +769,6 @@
   crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
 
   request_.url = GURL("http://" + origin_host);
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
   AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
   SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
@@ -815,7 +810,6 @@
   request_.url = GURL("https://" + origin.host());
   AddQuicRemoteAlternativeServiceMapping(
       MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   SendRequestAndExpectQuicResponse("hello!");
@@ -901,7 +895,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   SendRequestAndExpectHttpResponse("hello world");
@@ -936,7 +929,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   SendRequestAndExpectHttpResponse("hello world");
@@ -1037,7 +1029,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   SendRequestAndExpectHttpResponse("hello world");
@@ -1182,7 +1173,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   SendRequestAndExpectHttpResponse("hello world");
@@ -1267,12 +1257,8 @@
   mock_quic_data.AddRead(ASYNC, 0);               // EOF
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
-  AddHangingNonAlternateProtocolSocketData();
-
   mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
 
-  AddHangingNonAlternateProtocolSocketData();
-
   CreateSession();
 
   SendRequestAndExpectHttpResponse("hello world");
@@ -1348,7 +1334,6 @@
   mock_quic_data.AddRead(ASYNC, 0);               // EOF
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
-  AddHangingNonAlternateProtocolSocketData();
 
   CreateSession();
 
@@ -1441,10 +1426,7 @@
   mock_quic_data2.AddRead(ASYNC, 0);               // EOF
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
-  AddHangingNonAlternateProtocolSocketData();
-
   mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
-  AddHangingNonAlternateProtocolSocketData();
 
   CreateSession();
 
@@ -1490,7 +1472,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   SendRequestAndExpectHttpResponse("hello world");
@@ -1523,7 +1504,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   AlternativeService alternative_service(QUIC,
@@ -1600,10 +1580,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   params_.parse_alternative_services = false;
   params_.parse_alternative_services = false;
   CreateSession();
@@ -1639,10 +1615,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   params_.parse_alternative_services = false;
   params_.parse_alternative_services = false;
   CreateSession();
@@ -1678,10 +1650,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   params_.parse_alternative_services = false;
   CreateSession();
 
@@ -1715,10 +1683,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   params_.parse_alternative_services = false;
   CreateSession();
 
@@ -1764,10 +1728,7 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
   AddHangingNonAlternateProtocolSocketData();
-
   CreateSession();
 
   // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
@@ -1924,10 +1885,6 @@
 
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   CreateSession();
   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
   SendRequestAndExpectQuicResponse("hello!");
@@ -2011,10 +1968,6 @@
   mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);  // No more data to read
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   // In order for a new QUIC session to be established via alternate-protocol
   // without racing an HTTP connection, we need the host resolution to happen
   // synchronously.  Of course, even though QUIC *could* perform a 0-RTT
@@ -2028,6 +1981,10 @@
   host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
                          nullptr, net_log_.bound());
 
+  // The non-alternate protocol job needs to hang in order to guarantee that
+  // the alternate-protocol job will "win".
+  AddHangingNonAlternateProtocolSocketData();
+
   CreateSession();
   session_->quic_stream_factory()->set_require_confirmation(true);
   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
@@ -2246,8 +2203,6 @@
                                      0);
   socket_factory_.AddSocketDataProvider(&quic_data);
 
-  AddHangingNonAlternateProtocolSocketData();
-
   // Second Alternate-protocol job which will race with the TCP job.
   StaticSocketDataProvider quic_data2(quic_reads, arraysize(quic_reads),
                                       nullptr, 0);
@@ -2264,6 +2219,7 @@
   socket_factory_.AddSocketDataProvider(&http_data);
   socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
 
+  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
 
   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
@@ -2381,7 +2337,6 @@
   mock_quic_data.AddSocketDataToFactory(&socket_factory_);
 
   request_.url = GURL("https://www.example.org:443");
-  AddHangingNonAlternateProtocolSocketData();
   CreateSession();
   AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
   SendRequestAndExpectQuicResponse("hello!");
@@ -2399,10 +2354,6 @@
                                   arraysize(writes));
   socket_factory_.AddSocketDataProvider(&socket_data);
 
-  // The non-alternate protocol job needs to hang in order to guarantee that
-  // the alternate-protocol job will "win".
-  AddHangingNonAlternateProtocolSocketData();
-
   params_.parse_alternative_services = false;
   params_.enable_alternative_service_with_different_host = false;
   CreateSession();
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index 770b15dc..37c73c2f 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -1164,7 +1164,7 @@
   session_.PostProcessAfterData();
   EXPECT_TRUE(connection_->connected());
   EXPECT_TRUE(QuicSessionPeer::IsStreamClosed(&session_, stream_id));
-  EXPECT_EQ(nullptr, QuicSessionPeer::dynamic_streams(&session_)[stream_id]);
+  EXPECT_FALSE(QuicSessionPeer::IsStreamCreated(&session_, stream_id));
 
   // The stream is not waiting for the arrival of the peer's final offset as it
   // was received with the FIN earlier.
diff --git a/net/quic/quic_spdy_session.cc b/net/quic/quic_spdy_session.cc
index 593e3a02..071d011 100644
--- a/net/quic/quic_spdy_session.cc
+++ b/net/quic/quic_spdy_session.cc
@@ -16,7 +16,16 @@
                                  const QuicConfig& config)
     : QuicSession(connection, config) {}
 
-QuicSpdySession::~QuicSpdySession() {}
+QuicSpdySession::~QuicSpdySession() {
+  // Set the streams' session pointers in closed and dynamic stream lists
+  // to null to avoid subsequent use of this session.
+  for (auto const& stream : *closed_streams()) {
+    static_cast<QuicSpdyStream*>(stream)->ClearSession();
+  }
+  for (auto const& kv : dynamic_streams()) {
+    static_cast<QuicSpdyStream*>(kv.second)->ClearSession();
+  }
+}
 
 void QuicSpdySession::Initialize() {
   QuicSession::Initialize();
diff --git a/net/quic/quic_spdy_stream.cc b/net/quic/quic_spdy_stream.cc
index bf5b734..1eb4521 100644
--- a/net/quic/quic_spdy_stream.cc
+++ b/net/quic/quic_spdy_stream.cc
@@ -38,7 +38,9 @@
 }
 
 QuicSpdyStream::~QuicSpdyStream() {
-  spdy_session_->UnregisterStreamPriority(id());
+  if (spdy_session_ != nullptr) {
+    spdy_session_->UnregisterStreamPriority(id());
+  }
 }
 
 void QuicSpdyStream::CloseWriteSide() {
@@ -380,4 +382,9 @@
 SpdyPriority QuicSpdyStream::priority() const {
   return priority_;
 }
+
+void QuicSpdyStream::ClearSession() {
+  spdy_session_ = nullptr;
+}
+
 }  // namespace net
diff --git a/net/quic/quic_spdy_stream.h b/net/quic/quic_spdy_stream.h
index ca52cd3..252a3e0 100644
--- a/net/quic/quic_spdy_stream.h
+++ b/net/quic/quic_spdy_stream.h
@@ -184,6 +184,10 @@
   // written to the server.
   void SetPriority(SpdyPriority priority);
 
+  // Called when owning session is getting deleted to avoid subsequent
+  // use of the spdy_session_ member.
+  void ClearSession();
+
  protected:
   // Called by OnStreamHeadersComplete depending on which type (initial or
   // trailing) headers are expected next.
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index e70bb68..7911f81 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -26,8 +26,6 @@
 #include "crypto/openssl_util.h"
 #include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
-#include "net/base/socket_performance_watcher.h"
-#include "net/base/socket_performance_watcher_factory.h"
 #include "net/cert/cert_verifier.h"
 #include "net/cert/ct_verifier.h"
 #include "net/dns/host_resolver.h"
@@ -54,6 +52,8 @@
 #include "net/quic/quic_protocol.h"
 #include "net/quic/quic_server_id.h"
 #include "net/socket/client_socket_factory.h"
+#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_performance_watcher_factory.h"
 #include "net/ssl/token_binding.h"
 #include "net/udp/udp_client_socket.h"
 
@@ -594,7 +594,6 @@
     int threshold_public_resets_post_handshake,
     int threshold_timeouts_with_open_streams,
     int socket_receive_buffer_size,
-    bool delay_tcp_race,
     int max_server_configs_stored_in_properties,
     bool close_sessions_on_ip_change,
     bool disable_quic_on_timeout_with_open_streams,
@@ -643,7 +642,6 @@
       threshold_public_resets_post_handshake_(
           threshold_public_resets_post_handshake),
       socket_receive_buffer_size_(socket_receive_buffer_size),
-      delay_tcp_race_(delay_tcp_race),
       yield_after_packets_(kQuicYieldAfterPacketsRead),
       yield_after_duration_(QuicTime::Delta::FromMilliseconds(
           kQuicYieldAfterDurationMilliseconds)),
@@ -740,7 +738,7 @@
 
 base::TimeDelta QuicStreamFactory::GetTimeDelayForWaitingJob(
     const QuicServerId& server_id) {
-  if (!delay_tcp_race_ || require_confirmation_)
+  if (require_confirmation_)
     return base::TimeDelta();
   int64_t srtt =
       1.5 * GetServerNetworkStatsSmoothedRttInMicroseconds(server_id);
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index a03edf3..a56a70e 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -155,7 +155,6 @@
       int threshold_timeouts_with_streams_open,
       int threshold_public_resets_post_handshake,
       int socket_receive_buffer_size,
-      bool delay_tcp_race,
       int max_server_configs_stored_in_properties,
       bool close_sessions_on_ip_change,
       bool disable_quic_on_timeout_with_open_streams,
@@ -322,8 +321,6 @@
 
   int socket_receive_buffer_size() const { return socket_receive_buffer_size_; }
 
-  bool delay_tcp_race() const { return delay_tcp_race_; }
-
  private:
   class Job;
   friend class test::QuicStreamFactoryPeer;
@@ -516,9 +513,6 @@
   // Size of the UDP receive buffer.
   int socket_receive_buffer_size_;
 
-  // Set if we do want to delay TCP connection when it is racing with QUIC.
-  bool delay_tcp_race_;
-
   // If more than |yield_after_packets_| packets have been read or more than
   // |yield_after_duration_| time has passed, then
   // QuicChromiumPacketReader::StartReading() yields by doing a PostTask().
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index fb49977..89007ee5 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -226,7 +226,6 @@
         threshold_timeouts_with_open_streams_(2),
         threshold_public_resets_post_handshake_(2),
         receive_buffer_size_(0),
-        delay_tcp_race_(false),
         close_sessions_on_ip_change_(false),
         disable_quic_on_timeout_with_open_streams_(false),
         idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds),
@@ -250,7 +249,7 @@
         max_number_of_lossy_connections_, packet_loss_threshold_,
         max_disabled_reasons_, threshold_timeouts_with_open_streams_,
         threshold_public_resets_post_handshake_, receive_buffer_size_,
-        delay_tcp_race_, /*max_server_configs_stored_in_properties*/ 0,
+        /*max_server_configs_stored_in_properties*/ 0,
         close_sessions_on_ip_change_,
         disable_quic_on_timeout_with_open_streams_,
         idle_connection_timeout_seconds_, migrate_sessions_on_network_change_,
@@ -437,7 +436,6 @@
   int threshold_timeouts_with_open_streams_;
   int threshold_public_resets_post_handshake_;
   int receive_buffer_size_;
-  bool delay_tcp_race_;
   bool close_sessions_on_ip_change_;
   bool disable_quic_on_timeout_with_open_streams_;
   int idle_connection_timeout_seconds_;
@@ -1103,7 +1101,6 @@
   EXPECT_EQ(true,
             QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
   EXPECT_FALSE(HasActiveSession(host_port_pair_));
-  EXPECT_FALSE(HasActiveSession(host_port_pair_));
 
   // Create a new request for the same destination and verify that a
   // new session is created.
@@ -2805,8 +2802,8 @@
   TestCompletionCallback callback2;
   QuicStreamRequest request2(factory_.get());
   EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
-                                 /*cert_verify_flags=*/0, url_, "GET", net_log_,
-                                 callback2.callback()));
+                                 /*cert_verify_flags=*/0, url2_, "GET",
+                                 net_log_, callback2.callback()));
   QuicChromiumClientSession* session2 = GetActiveSession(server2);
 
   // If there is no packet loss during handshake confirmation, number of lossy
@@ -2858,7 +2855,6 @@
   EXPECT_TRUE(
       QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server3.port()));
   EXPECT_FALSE(HasActiveSession(server3));
-  EXPECT_FALSE(HasActiveSession(server3));
 
   // Set packet_loss_rate to higher value than packet_loss_threshold 3rd time in
   // a row and IsQuicDisabled() should close the session.
@@ -2870,7 +2866,6 @@
   EXPECT_TRUE(
       QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server4.port()));
   EXPECT_FALSE(HasActiveSession(server4));
-  EXPECT_FALSE(HasActiveSession(server4));
 
   std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
   EXPECT_TRUE(stream.get());
@@ -3150,7 +3145,7 @@
   TestCompletionCallback callback3;
   QuicStreamRequest request3(factory_.get());
   EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
-                                 /*cert_verify_flags=*/0, url2_, "GET",
+                                 /*cert_verify_flags=*/0, url3_, "GET",
                                  net_log_, callback3.callback()));
   QuicChromiumClientSession* session3 = GetActiveSession(server3);
 
@@ -3673,8 +3668,6 @@
   Initialize();
   ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
   crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
-  bool delay_tcp_race = QuicStreamFactoryPeer::GetDelayTcpRace(factory_.get());
-  QuicStreamFactoryPeer::SetDelayTcpRace(factory_.get(), false);
   MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
   SequencedSocketData socket_data(reads, arraysize(reads), nullptr, 0);
   socket_factory_.AddSocketDataProvider(&socket_data);
@@ -3697,14 +3690,6 @@
                             /*cert_verify_flags=*/0, url_, "POST", net_log_,
                             callback_.callback()));
 
-  // If we don't delay TCP connection, then time delay should be 0.
-  EXPECT_FALSE(factory_->delay_tcp_race());
-  EXPECT_EQ(base::TimeDelta(), request.GetTimeDelayForWaitingJob());
-
-  // Enable |delay_tcp_race_| param and verify delay is one RTT and that
-  // server supports QUIC.
-  QuicStreamFactoryPeer::SetDelayTcpRace(factory_.get(), true);
-  EXPECT_TRUE(factory_->delay_tcp_race());
   EXPECT_EQ(base::TimeDelta::FromMicroseconds(15),
             request.GetTimeDelayForWaitingJob());
 
@@ -3718,7 +3703,6 @@
   EXPECT_TRUE(stream.get());
   EXPECT_TRUE(socket_data.AllReadDataConsumed());
   EXPECT_TRUE(socket_data.AllWriteDataConsumed());
-  QuicStreamFactoryPeer::SetDelayTcpRace(factory_.get(), delay_tcp_race);
 }
 
 TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
diff --git a/net/quic/reliable_quic_stream_test.cc b/net/quic/reliable_quic_stream_test.cc
index 645573f..2aefc23 100644
--- a/net/quic/reliable_quic_stream_test.cc
+++ b/net/quic/reliable_quic_stream_test.cc
@@ -107,7 +107,7 @@
   void Initialize(bool stream_should_process_data) {
     connection_ = new StrictMock<MockConnection>(
         &helper_, &alarm_factory_, Perspective::IS_SERVER, supported_versions_);
-    session_.reset(new StrictMock<MockQuicSpdySession>(connection_));
+    session_.reset(new StrictMock<MockQuicSession>(connection_));
 
     // New streams rely on having the peer's flow control receive window
     // negotiated in the config.
@@ -152,7 +152,7 @@
   MockConnectionHelper helper_;
   MockAlarmFactory alarm_factory_;
   MockConnection* connection_;
-  std::unique_ptr<MockQuicSpdySession> session_;
+  std::unique_ptr<MockQuicSession> session_;
   TestStream* stream_;
   SpdyHeaderBlock headers_;
   QuicWriteBlockedList* write_blocked_list_;
@@ -648,7 +648,7 @@
   Initialize(kShouldProcessData);
   EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
   EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
-      .WillRepeatedly(Invoke(MockQuicSpdySession::ConsumeAllData));
+      .WillRepeatedly(Invoke(MockQuicSession::ConsumeAllData));
 
   // Receive data for the request.
   QuicStreamFrame frame1(stream_->id(), false, 0, StringPiece("Start"));
diff --git a/net/quic/test_tools/quic_session_peer.cc b/net/quic/test_tools/quic_session_peer.cc
index 04f5912..a2d62477 100644
--- a/net/quic/test_tools/quic_session_peer.cc
+++ b/net/quic/test_tools/quic_session_peer.cc
@@ -66,11 +66,6 @@
 }
 
 // static
-QuicSession::StreamMap& QuicSessionPeer::dynamic_streams(QuicSession* session) {
-  return session->dynamic_streams();
-}
-
-// static
 std::unordered_set<QuicStreamId>* QuicSessionPeer::GetDrainingStreams(
     QuicSession* session) {
   return &session->draining_streams_;
diff --git a/net/quic/test_tools/quic_session_peer.h b/net/quic/test_tools/quic_session_peer.h
index dcc60b9..d621dfe 100644
--- a/net/quic/test_tools/quic_session_peer.h
+++ b/net/quic/test_tools/quic_session_peer.h
@@ -39,7 +39,6 @@
   static std::map<QuicStreamId, QuicStreamOffset>&
   GetLocallyClosedStreamsHighestOffset(QuicSession* session);
   static QuicSession::StreamMap& static_streams(QuicSession* session);
-  static QuicSession::StreamMap& dynamic_streams(QuicSession* session);
   static std::unordered_set<QuicStreamId>* GetDrainingStreams(
       QuicSession* session);
 
diff --git a/net/quic/test_tools/quic_stream_factory_peer.cc b/net/quic/test_tools/quic_stream_factory_peer.cc
index 0d58f20a..63ec75d 100644
--- a/net/quic/test_tools/quic_stream_factory_peer.cc
+++ b/net/quic/test_tools/quic_stream_factory_peer.cc
@@ -73,15 +73,6 @@
   return factory->IsQuicDisabled(port);
 }
 
-bool QuicStreamFactoryPeer::GetDelayTcpRace(QuicStreamFactory* factory) {
-  return factory->delay_tcp_race_;
-}
-
-void QuicStreamFactoryPeer::SetDelayTcpRace(QuicStreamFactory* factory,
-                                            bool delay_tcp_race) {
-  factory->delay_tcp_race_ = delay_tcp_race;
-}
-
 void QuicStreamFactoryPeer::SetYieldAfterPackets(QuicStreamFactory* factory,
                                                  int yield_after_packets) {
   factory->yield_after_packets_ = yield_after_packets;
diff --git a/net/quic/test_tools/quic_stream_factory_peer.h b/net/quic/test_tools/quic_stream_factory_peer.h
index e0d85a3..a8ab16e 100644
--- a/net/quic/test_tools/quic_stream_factory_peer.h
+++ b/net/quic/test_tools/quic_stream_factory_peer.h
@@ -55,10 +55,6 @@
 
   static bool IsQuicDisabled(QuicStreamFactory* factory, uint16_t port);
 
-  static bool GetDelayTcpRace(QuicStreamFactory* factory);
-
-  static void SetDelayTcpRace(QuicStreamFactory* factory, bool delay_tcp_race);
-
   static void SetYieldAfterPackets(QuicStreamFactory* factory,
                                    int yield_after_packets);
 
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index 70e01a1..61d1908 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -326,6 +326,26 @@
                                     HAS_RETRANSMITTABLE_DATA);
 }
 
+MockQuicSession::MockQuicSession(QuicConnection* connection)
+    : QuicSession(connection, DefaultQuicConfig()) {
+  crypto_stream_.reset(new QuicCryptoStream(this));
+  Initialize();
+  ON_CALL(*this, WritevData(_, _, _, _, _))
+      .WillByDefault(testing::Return(QuicConsumedData(0, false)));
+}
+
+MockQuicSession::~MockQuicSession() {}
+
+// static
+QuicConsumedData MockQuicSession::ConsumeAllData(
+    QuicStreamId /*id*/,
+    const QuicIOVector& data,
+    QuicStreamOffset /*offset*/,
+    bool fin,
+    QuicAckListenerInterface* /*ack_notifier_delegate*/) {
+  return QuicConsumedData(data.total_length, fin);
+}
+
 MockQuicSpdySession::MockQuicSpdySession(QuicConnection* connection)
     : QuicSpdySession(connection, DefaultQuicConfig()) {
   crypto_stream_.reset(new QuicCryptoStream(this));
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index 65c5826..07ea1f7 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -471,6 +471,65 @@
   DISALLOW_COPY_AND_ASSIGN(PacketSavingConnection);
 };
 
+class MockQuicSession : public QuicSession {
+ public:
+  explicit MockQuicSession(QuicConnection* connection);
+  ~MockQuicSession() override;
+
+  QuicCryptoStream* GetCryptoStream() override { return crypto_stream_.get(); }
+
+  MOCK_METHOD3(OnConnectionClosed,
+               void(QuicErrorCode error,
+                    const std::string& error_details,
+                    ConnectionCloseSource source));
+  MOCK_METHOD1(CreateIncomingDynamicStream,
+               ReliableQuicStream*(QuicStreamId id));
+  MOCK_METHOD1(CreateOutgoingDynamicStream,
+               ReliableQuicStream*(SpdyPriority priority));
+  MOCK_METHOD1(ShouldCreateIncomingDynamicStream, bool(QuicStreamId id));
+  MOCK_METHOD0(ShouldCreateOutgoingDynamicStream, bool());
+  MOCK_METHOD5(WritevData,
+               QuicConsumedData(QuicStreamId id,
+                                QuicIOVector data,
+                                QuicStreamOffset offset,
+                                bool fin,
+                                QuicAckListenerInterface*));
+
+  MOCK_METHOD3(SendRstStream,
+               void(QuicStreamId stream_id,
+                    QuicRstStreamErrorCode error,
+                    QuicStreamOffset bytes_written));
+
+  MOCK_METHOD2(OnStreamHeaders,
+               void(QuicStreamId stream_id, base::StringPiece headers_data));
+  MOCK_METHOD2(OnStreamHeadersPriority,
+               void(QuicStreamId stream_id, SpdyPriority priority));
+  MOCK_METHOD3(OnStreamHeadersComplete,
+               void(QuicStreamId stream_id, bool fin, size_t frame_len));
+  MOCK_METHOD4(OnStreamHeaderList,
+               void(QuicStreamId stream_id,
+                    bool fin,
+                    size_t frame_len,
+                    const QuicHeaderList& header_list));
+  MOCK_METHOD0(IsCryptoHandshakeConfirmed, bool());
+
+  using QuicSession::ActivateStream;
+
+  // Returns a QuicConsumedData that indicates all of |data| (and |fin| if set)
+  // has been consumed.
+  static QuicConsumedData ConsumeAllData(
+      QuicStreamId id,
+      const QuicIOVector& data,
+      QuicStreamOffset offset,
+      bool fin,
+      QuicAckListenerInterface* ack_notifier_delegate);
+
+ private:
+  std::unique_ptr<QuicCryptoStream> crypto_stream_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockQuicSession);
+};
+
 class MockQuicSpdySession : public QuicSpdySession {
  public:
   explicit MockQuicSpdySession(QuicConnection* connection);
diff --git a/net/socket/client_socket_factory.h b/net/socket/client_socket_factory.h
index ea1aacb..5fdb365 100644
--- a/net/socket/client_socket_factory.h
+++ b/net/socket/client_socket_factory.h
@@ -10,8 +10,8 @@
 
 #include "net/base/net_export.h"
 #include "net/base/rand_callback.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/log/net_log.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/udp/datagram_socket.h"
 
 namespace net {
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index 11e4659..a080afa 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -29,7 +29,6 @@
 #include "net/base/load_timing_info_test_util.h"
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
 #include "net/http/http_response_headers.h"
 #include "net/log/net_log.h"
@@ -38,6 +37,7 @@
 #include "net/log/test_net_log_util.h"
 #include "net/socket/client_socket_factory.h"
 #include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socket_test_util.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/socket/stream_socket.h"
diff --git a/net/socket/fuzzed_socket.cc b/net/socket/fuzzed_socket.cc
index c00faafd..4ff9f28 100644
--- a/net/socket/fuzzed_socket.cc
+++ b/net/socket/fuzzed_socket.cc
@@ -4,17 +4,27 @@
 
 #include "net/socket/fuzzed_socket.h"
 
+#include <algorithm>
+
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/thread_task_runner_handle.h"
+#include "net/base/fuzzed_data_provider.h"
 #include "net/base/io_buffer.h"
 
 namespace net {
 
 namespace {
 
-// Subset of the socket errors that can be returned by normal socket reads /
+// Some of the socket errors that can be returned by normal socket connection
+// attempts.
+const Error kConnectErrors[] = {
+    ERR_CONNECTION_RESET,     ERR_CONNECTION_CLOSED, ERR_FAILED,
+    ERR_CONNECTION_TIMED_OUT, ERR_ACCESS_DENIED,     ERR_CONNECTION_REFUSED,
+    ERR_ADDRESS_UNREACHABLE};
+
+// Some of the socket errors that can be returned by normal socket reads /
 // writes. The first one is returned when no more input data remains, so it's
 // one of the most common ones.
 const Error kReadWriteErrors[] = {ERR_CONNECTION_CLOSED, ERR_FAILED,
@@ -22,11 +32,11 @@
 
 }  // namespace
 
-FuzzedSocket::FuzzedSocket(const uint8_t* data,
-                           size_t data_size,
-                           const BoundNetLog& bound_net_log)
-    : data_(reinterpret_cast<const char*>(data), data_size),
-      bound_net_log_(bound_net_log),
+FuzzedSocket::FuzzedSocket(FuzzedDataProvider* data_provider,
+                           net::NetLog* net_log)
+    : data_provider_(data_provider),
+      bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
+      remote_address_(IPEndPoint(IPAddress::IPv4Localhost(), 80)),
       weak_factory_(this) {}
 
 FuzzedSocket::~FuzzedSocket() {}
@@ -34,6 +44,7 @@
 int FuzzedSocket::Read(IOBuffer* buf,
                        int buf_len,
                        const CompletionCallback& callback) {
+  DCHECK(!connect_pending_);
   DCHECK(!read_pending_);
 
   bool sync;
@@ -44,24 +55,23 @@
     result = net_error_;
     sync = !error_pending_;
   } else {
-    // Otherwise, use |data_|.
-    uint8_t random_val = ConsumeUint8FromData();
-    sync = !!(random_val & 0x01);
-    result = random_val >> 1;
+    // Otherwise, use |data_provider_|.
+    sync = data_provider_->ConsumeBool();
+    result = data_provider_->ConsumeUint8();
     if (result > buf_len)
       result = buf_len;
-    // Can't read more data than is available in |data_|.
-    if (static_cast<size_t>(result) > data_.length())
-      result = data_.length();
+
+    if (result > 0) {
+      base::StringPiece data = data_provider_->ConsumeBytes(result);
+      result = data.length();
+      std::copy(data.data(), data.data() + result, buf->data());
+    }
 
     if (result == 0) {
       net_error_ = ConsumeReadWriteErrorFromData();
       result = net_error_;
       if (!sync)
         error_pending_ = true;
-    } else {
-      memcpy(buf->data(), data_.data(), result);
-      data_ = data_.substr(result);
     }
   }
 
@@ -86,6 +96,7 @@
 int FuzzedSocket::Write(IOBuffer* buf,
                         int buf_len,
                         const CompletionCallback& callback) {
+  DCHECK(!connect_pending_);
   DCHECK(!write_pending_);
 
   bool sync;
@@ -97,9 +108,8 @@
     sync = !error_pending_;
   } else {
     // Otherwise, use |data_|.
-    uint8_t random_val = ConsumeUint8FromData();
-    sync = !!(random_val & 0x01);
-    result = random_val >> 1;
+    sync = data_provider_->ConsumeBool();
+    result = data_provider_->ConsumeUint8();
     if (result > buf_len)
       result = buf_len;
     if (result == 0) {
@@ -134,19 +144,43 @@
 int FuzzedSocket::Connect(const CompletionCallback& callback) {
   // Sockets can normally be reused, but don't support it here.
   DCHECK_NE(net_error_, OK);
+  DCHECK(!connect_pending_);
   DCHECK(!read_pending_);
   DCHECK(!write_pending_);
   DCHECK(!error_pending_);
   DCHECK(!total_bytes_read_);
   DCHECK(!total_bytes_written_);
 
-  net_error_ = OK;
-  return OK;
+  bool sync = true;
+  Error result = OK;
+  if (fuzz_connect_result_) {
+    // Decide if sync or async. Use async, if no data is left.
+    sync = data_provider_->ConsumeBool();
+    // Decide if the connect succeeds or not, and if so, pick an error code.
+    if (data_provider_->ConsumeBool()) {
+      result = kConnectErrors[data_provider_->ConsumeValueInRange(
+          0, arraysize(kConnectErrors) - 1)];
+    }
+  }
+
+  if (sync) {
+    net_error_ = result;
+    return result;
+  }
+
+  connect_pending_ = true;
+  if (result != OK)
+    error_pending_ = true;
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::Bind(&FuzzedSocket::OnConnectComplete,
+                            weak_factory_.GetWeakPtr(), callback, result));
+  return ERR_IO_PENDING;
 }
 
 void FuzzedSocket::Disconnect() {
   net_error_ = ERR_CONNECTION_CLOSED;
   weak_factory_.InvalidateWeakPtrs();
+  connect_pending_ = false;
   read_pending_ = false;
   write_pending_ = false;
   error_pending_ = false;
@@ -212,17 +246,9 @@
   return total_bytes_read_;
 }
 
-uint8_t FuzzedSocket::ConsumeUint8FromData() {
-  size_t length = data_.length();
-  if (!length)
-    return 0;
-  uint8_t out = data_[length - 1];
-  data_ = data_.substr(0, length - 1);
-  return out;
-}
-
 Error FuzzedSocket::ConsumeReadWriteErrorFromData() {
-  return kReadWriteErrors[ConsumeUint8FromData() % arraysize(kReadWriteErrors)];
+  return kReadWriteErrors[data_provider_->ConsumeValueInRange(
+      0, arraysize(kReadWriteErrors) - 1)];
 }
 
 void FuzzedSocket::OnReadComplete(const CompletionCallback& callback,
@@ -249,4 +275,13 @@
   callback.Run(result);
 }
 
+void FuzzedSocket::OnConnectComplete(const CompletionCallback& callback,
+                                     int result) {
+  CHECK(connect_pending_);
+  connect_pending_ = false;
+  if (result < 0)
+    error_pending_ = false;
+  callback.Run(result);
+}
+
 }  // namespace net
diff --git a/net/socket/fuzzed_socket.h b/net/socket/fuzzed_socket.h
index 441300f..dd57f2e 100644
--- a/net/socket/fuzzed_socket.h
+++ b/net/socket/fuzzed_socket.h
@@ -11,20 +11,23 @@
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_piece.h"
 #include "net/base/completion_callback.h"
+#include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/log/net_log.h"
 #include "net/socket/stream_socket.h"
 
 namespace net {
 
+class FuzzedDataProvider;
+class IPEndPoint;
 class IOBuffer;
 
-// A StreamSocket that uses a single block of data to generate responses for use
-// with fuzzers. Writes can succeed synchronously or asynchronously, can write
-// some or all of the provided data, and can fail with several different errors.
-// Reads can do the same, but the read data is also generated from the initial
-// input data. The number of bytes written/read from a single call is currently
-// capped at 127 bytes.
+// A StreamSocket that uses a FuzzedDataProvider to generate responses. Writes
+// can succeed synchronously or asynchronously, can write some or all of the
+// provided data, and can fail with several different errors. Reads can do the
+// same, but the read data is also generated from the FuzzedDataProvider. The
+// number of bytes written/read from a single call is currently capped at 255
+// bytes.
 //
 // Reads and writes are executed independently of one another, so to guarantee
 // the fuzzer behaves the same across repeated runs with the same input, the
@@ -33,14 +36,23 @@
 // data.
 class FuzzedSocket : public StreamSocket {
  public:
-  // |data| must be of length |data_size| and is used as to determine behavior
-  // of the FuzzedSocket. It must remain valid until the FuzzedSocket is
-  // destroyed.
-  FuzzedSocket(const uint8_t* data,
-               size_t data_size,
-               const BoundNetLog& bound_net_log);
+  // |data_provider| is used as to determine behavior of the FuzzedSocket. It
+  // must remain valid until after the FuzzedSocket is destroyed.
+  FuzzedSocket(FuzzedDataProvider* data_provider, net::NetLog* net_log);
   ~FuzzedSocket() override;
 
+  // If set to true, the socket will fuzz the result of the Connect() call.
+  // It can fail or succeed, and return synchronously or asynchronously. If
+  // false, Connect() succeeds synchronously. Defaults to false.
+  void set_fuzz_connect_result(bool fuzz_connect_result) {
+    fuzz_connect_result_ = fuzz_connect_result;
+  }
+
+  // Sets the remote address the socket claims to be using.
+  void set_remote_address(const IPEndPoint& remote_address) {
+    remote_address_ = remote_address;
+  }
+
   // Socket implementation:
   int Read(IOBuffer* buf,
            int buf_len,
@@ -72,22 +84,22 @@
   int64_t GetTotalReceivedBytes() const override;
 
  private:
-  // Returns a uint8_t removed from the back of |data_|. Bytes read from the
-  // socket are taken from the front of the stream, so this will keep read bytes
-  // more consistent between test runs. If no data is left, returns 0.
-  uint8_t ConsumeUint8FromData();
-
   // Returns a net::Error that can be returned by a read or a write. Reads and
   // writes return basically the same set of errors, at the TCP socket layer.
-  // Which error is determined by a call to ConsumeUint8FromData().
   Error ConsumeReadWriteErrorFromData();
 
   void OnReadComplete(const CompletionCallback& callback, int result);
   void OnWriteComplete(const CompletionCallback& callback, int result);
+  void OnConnectComplete(const CompletionCallback& callback, int result);
 
-  // The unconsumed portion of the input data that |this| was created with.
-  base::StringPiece data_;
+  FuzzedDataProvider* data_provider_;
 
+  // If true, the result of the Connect() call is fuzzed - it can succeed or
+  // fail with a variety of connection errors, and it can complete synchronously
+  // or asynchronously.
+  bool fuzz_connect_result_ = false;
+
+  bool connect_pending_ = false;
   bool read_pending_ = false;
   bool write_pending_ = false;
 
@@ -105,6 +117,8 @@
 
   BoundNetLog bound_net_log_;
 
+  IPEndPoint remote_address_;
+
   base::WeakPtrFactory<FuzzedSocket> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(FuzzedSocket);
diff --git a/net/socket/fuzzed_socket_factory.cc b/net/socket/fuzzed_socket_factory.cc
new file mode 100644
index 0000000..5c91990
--- /dev/null
+++ b/net/socket/fuzzed_socket_factory.cc
@@ -0,0 +1,237 @@
+// 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 "net/socket/fuzzed_socket_factory.h"
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "net/base/address_list.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/base/network_change_notifier.h"
+#include "net/log/net_log.h"
+#include "net/socket/client_socket_handle.h"
+#include "net/socket/connection_attempts.h"
+#include "net/socket/fuzzed_socket.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/ssl/ssl_failure_state.h"
+#include "net/udp/datagram_client_socket.h"
+
+namespace net {
+
+namespace {
+
+// Datagram ClientSocket implementation that always failed to connect.
+class FailingUDPClientSocket : public DatagramClientSocket {
+ public:
+  FailingUDPClientSocket() {}
+  ~FailingUDPClientSocket() override {}
+
+  // DatagramClientSocket implementation:
+  int Connect(const IPEndPoint& address) override { return ERR_FAILED; }
+
+  int ConnectUsingNetwork(NetworkChangeNotifier::NetworkHandle network,
+                          const IPEndPoint& address) override {
+    return ERR_FAILED;
+  }
+
+  int ConnectUsingDefaultNetwork(const IPEndPoint& address) override {
+    return ERR_FAILED;
+  }
+
+  NetworkChangeNotifier::NetworkHandle GetBoundNetwork() const override {
+    return -1;
+  }
+
+  // DatagramSocket implementation:
+  void Close() override {}
+
+  int GetPeerAddress(IPEndPoint* address) const override {
+    return ERR_SOCKET_NOT_CONNECTED;
+  }
+
+  int GetLocalAddress(IPEndPoint* address) const override {
+    return ERR_SOCKET_NOT_CONNECTED;
+  }
+
+  const BoundNetLog& NetLog() const override { return net_log_; }
+
+  // Socket implementation:
+  int Read(IOBuffer* buf,
+           int buf_len,
+           const CompletionCallback& callback) override {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  int Write(IOBuffer* buf,
+            int buf_len,
+            const CompletionCallback& callback) override {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  int SetReceiveBufferSize(int32_t size) override {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  int SetSendBufferSize(int32_t size) override {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  BoundNetLog net_log_;
+
+  DISALLOW_COPY_AND_ASSIGN(FailingUDPClientSocket);
+};
+
+// SSLClientSocket implementation that always fails to connect.
+class FailingSSLClientSocket : public SSLClientSocket {
+ public:
+  FailingSSLClientSocket() {}
+  ~FailingSSLClientSocket() override {}
+
+  // Socket implementation:
+  int Read(IOBuffer* buf,
+           int buf_len,
+           const CompletionCallback& callback) override {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  int Write(IOBuffer* buf,
+            int buf_len,
+            const CompletionCallback& callback) override {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  int SetReceiveBufferSize(int32_t size) override { return OK; }
+  int SetSendBufferSize(int32_t size) override { return OK; }
+
+  // StreamSocket implementation:
+  int Connect(const CompletionCallback& callback) override {
+    return ERR_FAILED;
+  }
+
+  void Disconnect() override {}
+  bool IsConnected() const override { return false; }
+  bool IsConnectedAndIdle() const override { return false; }
+
+  int GetPeerAddress(IPEndPoint* address) const override {
+    return ERR_SOCKET_NOT_CONNECTED;
+  }
+  int GetLocalAddress(IPEndPoint* address) const override {
+    return ERR_SOCKET_NOT_CONNECTED;
+  }
+
+  const BoundNetLog& NetLog() const override { return net_log_; }
+
+  void SetSubresourceSpeculation() override {}
+  void SetOmniboxSpeculation() override {}
+
+  bool WasEverUsed() const override { return false; }
+
+  void EnableTCPFastOpenIfSupported() override {}
+
+  bool WasNpnNegotiated() const override { return false; }
+
+  NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
+
+  bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
+
+  void GetConnectionAttempts(ConnectionAttempts* out) const override {
+    out->clear();
+  }
+
+  void ClearConnectionAttempts() override {}
+
+  void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
+
+  int64_t GetTotalReceivedBytes() const override { return 0; }
+
+  // SSLSocket implementation:
+  int ExportKeyingMaterial(const base::StringPiece& label,
+                           bool has_context,
+                           const base::StringPiece& context,
+                           unsigned char* out,
+                           unsigned int outlen) override {
+    NOTREACHED();
+    return 0;
+  }
+
+  // SSLClientSocket implementation:
+  void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
+
+  NextProtoStatus GetNextProto(std::string* proto) const override {
+    return NextProtoStatus::kNextProtoUnsupported;
+  }
+
+  ChannelIDService* GetChannelIDService() const override {
+    NOTREACHED();
+    return nullptr;
+  }
+
+  Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
+                                    std::vector<uint8_t>* out) override {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  crypto::ECPrivateKey* GetChannelIDKey() const override {
+    NOTREACHED();
+    return nullptr;
+  }
+
+  SSLFailureState GetSSLFailureState() const override {
+    return SSL_FAILURE_UNKNOWN;
+  }
+
+ private:
+  BoundNetLog net_log_;
+
+  DISALLOW_COPY_AND_ASSIGN(FailingSSLClientSocket);
+};
+
+}  // namespace
+
+FuzzedSocketFactory::FuzzedSocketFactory(FuzzedDataProvider* data_provider)
+    : data_provider_(data_provider) {}
+
+FuzzedSocketFactory::~FuzzedSocketFactory() {}
+
+std::unique_ptr<DatagramClientSocket>
+FuzzedSocketFactory::CreateDatagramClientSocket(
+    DatagramSocket::BindType bind_type,
+    const RandIntCallback& rand_int_cb,
+    NetLog* net_log,
+    const NetLog::Source& source) {
+  return base::WrapUnique(new FailingUDPClientSocket());
+}
+
+std::unique_ptr<StreamSocket> FuzzedSocketFactory::CreateTransportClientSocket(
+    const AddressList& addresses,
+    std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
+    NetLog* net_log,
+    const NetLog::Source& source) {
+  std::unique_ptr<FuzzedSocket> socket(
+      new FuzzedSocket(data_provider_, net_log));
+  socket->set_fuzz_connect_result(true);
+  // Just use the first address.
+  socket->set_remote_address(*addresses.begin());
+  return std::move(socket);
+}
+
+std::unique_ptr<SSLClientSocket> FuzzedSocketFactory::CreateSSLClientSocket(
+    std::unique_ptr<ClientSocketHandle> transport_socket,
+    const HostPortPair& host_and_port,
+    const SSLConfig& ssl_config,
+    const SSLClientSocketContext& context) {
+  return base::WrapUnique(new FailingSSLClientSocket());
+}
+
+void FuzzedSocketFactory::ClearSSLSessionCache() {}
+
+}  // namespace net
diff --git a/net/socket/fuzzed_socket_factory.h b/net/socket/fuzzed_socket_factory.h
new file mode 100644
index 0000000..6b102ff
--- /dev/null
+++ b/net/socket/fuzzed_socket_factory.h
@@ -0,0 +1,64 @@
+// 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 NET_SOCKET_FUZZED_SOCKET_FACTORY_H
+#define NET_SOCKET_FUZZED_SOCKET_FACTORY_H
+
+#include <memory>
+
+#include "base/macros.h"
+#include "net/socket/client_socket_factory.h"
+
+namespace net {
+
+class FuzzedDataProvider;
+
+// A socket factory that creates FuzzedSockets that share the same
+// FuzzedDataProvider. To behave consistently, the read operations on all
+// sockets must be the same, and in the same order (both on each socket, and
+// between sockets).
+//
+// Currently doesn't support UDP or SSL sockets - just returns sockets that
+// synchronously fail to connect when trying to create either type of socket.
+// TODO(mmenke): Add support for both types of socket.
+// TODO(mmenke): add fuzzing for generation of valid cryptographically signed
+// messages.
+class FuzzedSocketFactory : public ClientSocketFactory {
+ public:
+  // |data_provider| must outlive the FuzzedSocketFactory, and all sockets it
+  // creates. Other objects can also continue to consume |data_provider|, as
+  // long as their calls into it are made on the CLientSocketFactory's thread
+  // and the calls are deterministic.
+  explicit FuzzedSocketFactory(FuzzedDataProvider* data_provider);
+  ~FuzzedSocketFactory() override;
+
+  std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
+      DatagramSocket::BindType bind_type,
+      const RandIntCallback& rand_int_cb,
+      NetLog* net_log,
+      const NetLog::Source& source) override;
+
+  std::unique_ptr<StreamSocket> CreateTransportClientSocket(
+      const AddressList& addresses,
+      std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
+      NetLog* net_log,
+      const NetLog::Source& source) override;
+
+  std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
+      std::unique_ptr<ClientSocketHandle> transport_socket,
+      const HostPortPair& host_and_port,
+      const SSLConfig& ssl_config,
+      const SSLClientSocketContext& context) override;
+
+  void ClearSSLSessionCache() override;
+
+ private:
+  FuzzedDataProvider* data_provider_;
+
+  DISALLOW_COPY_AND_ASSIGN(FuzzedSocketFactory);
+};
+
+}  // namespace net
+
+#endif  // NET_SOCKET_FUZZED_SOCKET_FACTORY_H
diff --git a/net/base/socket_performance_watcher.h b/net/socket/socket_performance_watcher.h
similarity index 90%
rename from net/base/socket_performance_watcher.h
rename to net/socket/socket_performance_watcher.h
index 74413679..8665cbd 100644
--- a/net/base/socket_performance_watcher.h
+++ b/net/socket/socket_performance_watcher.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_BASE_SOCKET_PERFORMANCE_WATCHER_H_
-#define NET_BASE_SOCKET_PERFORMANCE_WATCHER_H_
+#ifndef NET_SOCKET_SOCKET_PERFORMANCE_WATCHER_H_
+#define NET_SOCKET_SOCKET_PERFORMANCE_WATCHER_H_
 
 #include "net/base/net_export.h"
 
@@ -40,4 +40,4 @@
 
 }  // namespace net
 
-#endif  // NET_BASE_SOCKET_PERFORMANCE_WATCHER_H_
+#endif  // NET_SOCKET_SOCKET_PERFORMANCE_WATCHER_H_
diff --git a/net/base/socket_performance_watcher_factory.h b/net/socket/socket_performance_watcher_factory.h
similarity index 87%
rename from net/base/socket_performance_watcher_factory.h
rename to net/socket/socket_performance_watcher_factory.h
index 2c1d3f3..79648204 100644
--- a/net/base/socket_performance_watcher_factory.h
+++ b/net/socket/socket_performance_watcher_factory.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_BASE_SOCKET_PERFORMANCE_WATCHER_FACTORY_H_
-#define NET_BASE_SOCKET_PERFORMANCE_WATCHER_FACTORY_H_
+#ifndef NET_SOCKET_SOCKET_PERFORMANCE_WATCHER_FACTORY_H_
+#define NET_SOCKET_SOCKET_PERFORMANCE_WATCHER_FACTORY_H_
 
 #include <memory>
 
@@ -40,4 +40,4 @@
 
 }  // namespace net
 
-#endif  // NET_BASE_SOCKET_PERFORMANCE_WATCHER_FACTORY_H_
+#endif  // NET_SOCKET_SOCKET_PERFORMANCE_WATCHER_FACTORY_H_
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index c731cc55..3d11867 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -26,7 +26,6 @@
 #include "net/base/address_list.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
 #include "net/http/http_auth_controller.h"
 #include "net/http/http_proxy_client_socket_pool.h"
@@ -34,6 +33,7 @@
 #include "net/socket/client_socket_factory.h"
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/connection_attempts.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socks_client_socket_pool.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/socket/ssl_client_socket_pool.h"
diff --git a/net/socket/socks5_client_socket_fuzzer.cc b/net/socket/socks5_client_socket_fuzzer.cc
index 8bbc7fc..3c0864c7 100644
--- a/net/socket/socks5_client_socket_fuzzer.cc
+++ b/net/socket/socks5_client_socket_fuzzer.cc
@@ -9,6 +9,7 @@
 
 #include "base/logging.h"
 #include "net/base/address_list.h"
+#include "net/base/fuzzed_data_provider.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
 #include "net/log/test_net_log.h"
@@ -23,11 +24,13 @@
 // class for details.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   // Use a test NetLog, to exercise logging code.
-  net::BoundTestNetLog bound_test_net_log;
+  net::TestNetLog test_net_log;
+
+  net::FuzzedDataProvider data_provider(data, size);
 
   net::TestCompletionCallback callback;
   std::unique_ptr<net::FuzzedSocket> fuzzed_socket(
-      new net::FuzzedSocket(data, size, bound_test_net_log.bound()));
+      new net::FuzzedSocket(&data_provider, &test_net_log));
   CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback()));
 
   std::unique_ptr<net::ClientSocketHandle> socket_handle(
diff --git a/net/socket/socks_client_socket_fuzzer.cc b/net/socket/socks_client_socket_fuzzer.cc
index 2bc905b..498af718 100644
--- a/net/socket/socks_client_socket_fuzzer.cc
+++ b/net/socket/socks_client_socket_fuzzer.cc
@@ -9,6 +9,7 @@
 
 #include "base/logging.h"
 #include "net/base/address_list.h"
+#include "net/base/fuzzed_data_provider.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
 #include "net/dns/host_resolver.h"
@@ -24,21 +25,17 @@
 // class for details.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   // Use a test NetLog, to exercise logging code.
-  net::BoundTestNetLog bound_test_net_log;
+  net::TestNetLog test_net_log;
 
-  // Consume the last byte of |data| to determine if the DNS lookup returns
-  // synchronously or asynchronously, and succeeds or fails, and returns an IPv4
-  // or IPv6 address.
+  net::FuzzedDataProvider data_provider(data, size);
+
+  // Determine if the DNS lookup returns synchronously or asynchronously,
+  // succeeds or fails, and returns an IPv4 or IPv6 address.
   net::MockHostResolver mock_host_resolver;
   scoped_refptr<net::RuleBasedHostResolverProc> rules(
       new net::RuleBasedHostResolverProc(nullptr));
-  uint8_t resolver_result = 0;
-  if (size > 0) {
-    resolver_result = data[size - 1];
-    size--;
-  }
-  mock_host_resolver.set_synchronous_mode(!!(resolver_result & 0x1));
-  switch ((resolver_result >> 1) % 3) {
+  mock_host_resolver.set_synchronous_mode(data_provider.ConsumeBool());
+  switch (data_provider.ConsumeValueInRange(0, 2)) {
     case 0:
       rules->AddRule("*", "127.0.0.1");
       break;
@@ -53,7 +50,7 @@
 
   net::TestCompletionCallback callback;
   std::unique_ptr<net::FuzzedSocket> fuzzed_socket(
-      new net::FuzzedSocket(data, size, bound_test_net_log.bound()));
+      new net::FuzzedSocket(&data_provider, &test_net_log));
   CHECK_EQ(net::OK, fuzzed_socket->Connect(callback.callback()));
 
   std::unique_ptr<net::ClientSocketHandle> socket_handle(
diff --git a/net/socket/tcp_client_socket.cc b/net/socket/tcp_client_socket.cc
index c43a82d..1c292bb 100644
--- a/net/socket/tcp_client_socket.cc
+++ b/net/socket/tcp_client_socket.cc
@@ -14,7 +14,7 @@
 #include "net/base/io_buffer.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
-#include "net/base/socket_performance_watcher.h"
+#include "net/socket/socket_performance_watcher.h"
 
 namespace net {
 
diff --git a/net/socket/tcp_client_socket_unittest.cc b/net/socket/tcp_client_socket_unittest.cc
index 856c1087..d8499b44 100644
--- a/net/socket/tcp_client_socket_unittest.cc
+++ b/net/socket/tcp_client_socket_unittest.cc
@@ -13,8 +13,8 @@
 #include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/tcp_server_socket.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/net/socket/tcp_socket_posix.h b/net/socket/tcp_socket_posix.h
index 6cb5771..4d157e7 100644
--- a/net/socket/tcp_socket_posix.h
+++ b/net/socket/tcp_socket_posix.h
@@ -16,8 +16,8 @@
 #include "net/base/address_family.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_export.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/log/net_log.h"
+#include "net/socket/socket_performance_watcher.h"
 
 namespace base {
 class TickClock;
diff --git a/net/socket/tcp_socket_unittest.cc b/net/socket/tcp_socket_unittest.cc
index 0f572c5..b24d104 100644
--- a/net/socket/tcp_socket_unittest.cc
+++ b/net/socket/tcp_socket_unittest.cc
@@ -20,8 +20,8 @@
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/sockaddr_storage.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/base/test_completion_callback.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/tcp_client_socket.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
diff --git a/net/socket/tcp_socket_win.h b/net/socket/tcp_socket_win.h
index 4710287..39eceb93 100644
--- a/net/socket/tcp_socket_win.h
+++ b/net/socket/tcp_socket_win.h
@@ -18,8 +18,8 @@
 #include "net/base/address_family.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_export.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/log/net_log.h"
+#include "net/socket/socket_performance_watcher.h"
 
 namespace net {
 
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index 8b2f180..c94c0a1 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -20,13 +20,13 @@
 #include "base/values.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
-#include "net/base/socket_performance_watcher.h"
-#include "net/base/socket_performance_watcher_factory.h"
 #include "net/log/net_log.h"
 #include "net/socket/client_socket_factory.h"
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/client_socket_pool_base.h"
 #include "net/socket/socket_net_log_params.h"
+#include "net/socket/socket_performance_watcher.h"
+#include "net/socket/socket_performance_watcher_factory.h"
 #include "net/socket/tcp_client_socket.h"
 
 using base::TimeDelta;
diff --git a/net/socket/transport_client_socket_pool_test_util.h b/net/socket/transport_client_socket_pool_test_util.h
index 679fb17..97702a87 100644
--- a/net/socket/transport_client_socket_pool_test_util.h
+++ b/net/socket/transport_client_socket_pool_test_util.h
@@ -17,10 +17,10 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "net/base/address_list.h"
-#include "net/base/socket_performance_watcher.h"
 #include "net/log/net_log.h"
 #include "net/socket/client_socket_factory.h"
 #include "net/socket/client_socket_handle.h"
+#include "net/socket/socket_performance_watcher.h"
 #include "net/socket/stream_socket.h"
 
 namespace net {
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index c1d73e49..e1fdf8ff 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -9,14 +9,11 @@
 #include <algorithm>
 #include <ios>
 #include <iterator>
-#include <list>
 #include <memory>
-#include <new>
 #include <string>
 #include <vector>
 
 #include "base/lazy_instance.h"
-#include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "net/quic/quic_flags.h"
 #include "net/spdy/hpack/hpack_constants.h"
@@ -24,7 +21,6 @@
 #include "net/spdy/spdy_bug_tracker.h"
 #include "net/spdy/spdy_frame_builder.h"
 #include "net/spdy/spdy_frame_reader.h"
-#include "net/spdy/spdy_framer_adapter.h"
 #include "third_party/zlib/zlib.h"
 
 using base::StringPiece;
@@ -169,7 +165,7 @@
   return true;
 }
 
-SpdyFramer::SpdyFramer(SpdyMajorVersion version, bool choose_decoder)
+SpdyFramer::SpdyFramer(SpdyMajorVersion version)
     : current_frame_buffer_(kControlFrameBufferSize),
       expect_continuation_(0),
       visitor_(NULL),
@@ -187,24 +183,8 @@
   static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit,
                 "Our send limit should be at most our receive limit");
   Reset();
-
-  if (choose_decoder && version == HTTP2) {
-#ifdef SPDY_USE_NESTED_DECODER
-    // Another case will be added, hence the nested if blocks...
-    if (VLOG_IS_ON(1)) {
-      VLOG(1) << "Creating NestedSpdyFramerDecoder.";
-    } else {
-      // Logging at INFO level to make it easy to determine if this is
-      // triggering unexpectedly.
-      LOG_FIRST_N(INFO, 100) << "Creating NestedSpdyFramerDecoder.";
-    }
-    decoder_adapter_.reset(CreateNestedSpdyFramerDecoder(this));
-#endif
-  }
 }
 
-SpdyFramer::SpdyFramer(SpdyMajorVersion version) : SpdyFramer(version, true) {}
-
 SpdyFramer::~SpdyFramer() {
   if (header_compressor_.get()) {
     deflateEnd(header_compressor_.get());
@@ -215,9 +195,6 @@
 }
 
 void SpdyFramer::Reset() {
-  if (decoder_adapter_ != nullptr) {
-    decoder_adapter_->Reset();
-  }
   state_ = SPDY_READY_FOR_FRAME;
   previous_state_ = SPDY_READY_FOR_FRAME;
   error_code_ = SPDY_NO_ERROR;
@@ -233,49 +210,6 @@
   remaining_padding_payload_length_ = 0;
 }
 
-void SpdyFramer::set_visitor(SpdyFramerVisitorInterface* visitor) {
-  if (decoder_adapter_ != nullptr) {
-    decoder_adapter_->set_visitor(visitor);
-  }
-  visitor_ = visitor;
-}
-
-void SpdyFramer::set_debug_visitor(
-    SpdyFramerDebugVisitorInterface* debug_visitor) {
-  if (decoder_adapter_ != nullptr) {
-    decoder_adapter_->set_debug_visitor(debug_visitor);
-  }
-  debug_visitor_ = debug_visitor;
-}
-
-void SpdyFramer::set_process_single_input_frame(bool v) {
-  if (decoder_adapter_ != nullptr) {
-    decoder_adapter_->set_process_single_input_frame(v);
-  }
-  process_single_input_frame_ = v;
-}
-
-bool SpdyFramer::probable_http_response() const {
-  if (decoder_adapter_) {
-    return decoder_adapter_->probable_http_response();
-  }
-  return probable_http_response_;
-}
-
-SpdyFramer::SpdyError SpdyFramer::error_code() const {
-  if (decoder_adapter_ != nullptr) {
-    return decoder_adapter_->error_code();
-  }
-  return error_code_;
-}
-
-SpdyFramer::SpdyState SpdyFramer::state() const {
-  if (decoder_adapter_ != nullptr) {
-    return decoder_adapter_->state();
-  }
-  return state_;
-}
-
 size_t SpdyFramer::GetDataFrameMinimumSize() const {
   return SpdyConstants::GetDataFrameMinimumSize(protocol_version_);
 }
@@ -592,9 +526,6 @@
   DCHECK(visitor_);
   DCHECK(data);
 
-  if (decoder_adapter_ != nullptr) {
-    return decoder_adapter_->ProcessInput(data, len);
-  }
   const size_t original_len = len;
   do {
     previous_state_ = state_;
@@ -724,10 +655,8 @@
         goto bottom;
     }
   } while (state_ != previous_state_);
-bottom:
-  DCHECK(len == 0 || state_ == SPDY_ERROR || process_single_input_frame_)
-      << "len: " << len << " state: " << state_
-      << " process single input frame: " << process_single_input_frame_;
+ bottom:
+  DCHECK(len == 0 || state_ == SPDY_ERROR || process_single_input_frame_);
   if (current_frame_buffer_.len() == 0 && remaining_data_length_ == 0 &&
       remaining_control_header_ == 0) {
     DCHECK(state_ == SPDY_READY_FOR_FRAME || state_ == SPDY_ERROR)
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 5b3dced..5e664ee6 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -20,7 +20,6 @@
 #include "net/spdy/hpack/hpack_encoder.h"
 #include "net/spdy/spdy_alt_svc_wire_format.h"
 #include "net/spdy/spdy_header_block.h"
-#include "net/spdy/spdy_headers_handler_interface.h"
 #include "net/spdy/spdy_protocol.h"
 
 typedef struct z_stream_s z_stream;  // Forward declaration for zlib.
@@ -38,7 +37,6 @@
 
 class SpdyFramer;
 class SpdyFrameBuilder;
-class SpdyFramerDecoderAdapter;
 
 namespace test {
 
@@ -368,30 +366,31 @@
 
   // Create a new Framer, provided a SPDY version.
   explicit SpdyFramer(SpdyMajorVersion version);
-
-  // Used recursively from the above constructor in order to support
-  // instantiating a SpdyFramerDecoderAdapter selected via flags.
-  SpdyFramer(SpdyMajorVersion version, bool choose_decoder);
-
   virtual ~SpdyFramer();
 
   // Set callbacks to be called from the framer.  A visitor must be set, or
   // else the framer will likely crash.  It is acceptable for the visitor
   // to do nothing.  If this is called multiple times, only the last visitor
   // will be used.
-  void set_visitor(SpdyFramerVisitorInterface* visitor);
+  void set_visitor(SpdyFramerVisitorInterface* visitor) {
+    visitor_ = visitor;
+  }
 
   // Set debug callbacks to be called from the framer. The debug visitor is
   // completely optional and need not be set in order for normal operation.
   // If this is called multiple times, only the last visitor will be used.
-  void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor);
+  void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor) {
+    debug_visitor_ = debug_visitor;
+  }
 
   // Sets whether or not ProcessInput returns after finishing a frame, or
   // continues processing additional frames. Normally ProcessInput processes
   // all input, but this method enables the caller (and visitor) to work with
   // a single frame at a time (or that portion of the frame which is provided
   // as input). Reset() does not change the value of this flag.
-  void set_process_single_input_frame(bool v);
+  void set_process_single_input_frame(bool v) {
+    process_single_input_frame_ = v;
+  }
 
   // Pass data into the framer for parsing.
   // Returns the number of bytes consumed. It is safe to pass more bytes in
@@ -403,9 +402,9 @@
   void Reset();
 
   // Check the state of the framer.
-  SpdyError error_code() const;
-  SpdyState state() const;
-  bool HasError() const { return state() == SPDY_ERROR; }
+  SpdyError error_code() const { return error_code_; }
+  SpdyState state() const { return state_; }
+  bool HasError() const { return state_ == SPDY_ERROR; }
 
   // Given a buffer containing a decompressed header block in SPDY
   // serialized format, parse out a SpdyHeaderBlock, putting the results
@@ -544,9 +543,7 @@
 
   SpdyMajorVersion protocol_version() const { return protocol_version_; }
 
-  // Did the most recent frame header appear to be an HTTP/1.x (or earlier)
-  // response (i.e. start with "HTTP/")?
-  bool probable_http_response() const;
+  bool probable_http_response() const { return probable_http_response_; }
 
   SpdyPriority GetLowestPriority() const { return 7; }
 
@@ -773,9 +770,6 @@
 
   std::string display_protocol_;
 
-  // Optional decoder to use instead of this instance.
-  std::unique_ptr<SpdyFramerDecoderAdapter> decoder_adapter_;
-
   // The protocol version to be spoken/understood by this framer.
   const SpdyMajorVersion protocol_version_;
 
diff --git a/net/spdy/spdy_framer_adapter.cc b/net/spdy/spdy_framer_adapter.cc
deleted file mode 100644
index d3211e6..0000000
--- a/net/spdy/spdy_framer_adapter.cc
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright (c) 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 "net/spdy/spdy_framer_adapter.h"
-
-#include <memory>
-#include <string>
-
-#include "base/format_macros.h"
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-
-#define PRETTY_THIS                                    \
-  StringPrintf("%s@%" PRIu64 " ", __PRETTY_FUNCTION__, \
-               reinterpret_cast<uint64>(this))
-
-namespace net {
-
-SpdyFramerDecoderAdapter::SpdyFramerDecoderAdapter() {
-  DVLOG(1) << PRETTY_THIS;
-}
-
-SpdyFramerDecoderAdapter::~SpdyFramerDecoderAdapter() {
-  DVLOG(1) << PRETTY_THIS;
-}
-
-void SpdyFramerDecoderAdapter::set_visitor(
-    SpdyFramerVisitorInterface* visitor) {
-  visitor_ = visitor;
-}
-
-void SpdyFramerDecoderAdapter::set_debug_visitor(
-    SpdyFramerDebugVisitorInterface* debug_visitor) {
-  debug_visitor_ = debug_visitor;
-}
-
-void SpdyFramerDecoderAdapter::set_process_single_input_frame(bool v) {
-  process_single_input_frame_ = v;
-}
-
-void SpdyFramerVisitorAdapter::OnError(SpdyFramer* framer) {
-  visitor_->OnError(framer_);
-}
-
-void SpdyFramerVisitorAdapter::OnDataFrameHeader(SpdyStreamId stream_id,
-                                                 size_t length,
-                                                 bool fin) {
-  visitor_->OnDataFrameHeader(stream_id, length, fin);
-}
-
-void SpdyFramerVisitorAdapter::OnStreamFrameData(SpdyStreamId stream_id,
-                                                 const char* data,
-                                                 size_t len,
-                                                 bool fin) {
-  visitor_->OnStreamFrameData(stream_id, data, len, fin);
-}
-
-void SpdyFramerVisitorAdapter::OnStreamEnd(SpdyStreamId stream_id) {
-  visitor_->OnStreamEnd(stream_id);
-}
-
-void SpdyFramerVisitorAdapter::OnStreamPadding(SpdyStreamId stream_id,
-                                               size_t len) {
-  visitor_->OnStreamPadding(stream_id, len);
-}
-
-SpdyHeadersHandlerInterface* SpdyFramerVisitorAdapter::OnHeaderFrameStart(
-    SpdyStreamId stream_id) {
-  return visitor_->OnHeaderFrameStart(stream_id);
-}
-
-void SpdyFramerVisitorAdapter::OnHeaderFrameEnd(SpdyStreamId stream_id,
-                                                bool end_headers) {
-  visitor_->OnHeaderFrameEnd(stream_id, end_headers);
-}
-
-bool SpdyFramerVisitorAdapter::OnControlFrameHeaderData(
-    SpdyStreamId stream_id,
-    const char* header_data,
-    size_t header_data_len) {
-  return visitor_->OnControlFrameHeaderData(stream_id, header_data,
-                                            header_data_len);
-}
-
-void SpdyFramerVisitorAdapter::OnSynStream(SpdyStreamId stream_id,
-                                           SpdyStreamId associated_stream_id,
-                                           SpdyPriority priority,
-                                           bool fin,
-                                           bool unidirectional) {
-  visitor_->OnSynStream(stream_id, associated_stream_id, priority, fin,
-                        unidirectional);
-}
-
-void SpdyFramerVisitorAdapter::OnSynReply(SpdyStreamId stream_id, bool fin) {
-  visitor_->OnSynReply(stream_id, fin);
-}
-
-void SpdyFramerVisitorAdapter::OnRstStream(SpdyStreamId stream_id,
-                                           SpdyRstStreamStatus status) {
-  visitor_->OnRstStream(stream_id, status);
-}
-
-void SpdyFramerVisitorAdapter::OnSetting(SpdySettingsIds id,
-                                         uint8_t flags,
-                                         uint32_t value) {
-  visitor_->OnSetting(id, flags, value);
-}
-
-void SpdyFramerVisitorAdapter::OnPing(SpdyPingId unique_id, bool is_ack) {
-  visitor_->OnPing(unique_id, is_ack);
-}
-
-void SpdyFramerVisitorAdapter::OnSettings(bool clear_persisted) {
-  visitor_->OnSettings(clear_persisted);
-}
-
-void SpdyFramerVisitorAdapter::OnSettingsAck() {
-  visitor_->OnSettingsAck();
-}
-
-void SpdyFramerVisitorAdapter::OnSettingsEnd() {
-  visitor_->OnSettingsEnd();
-}
-
-void SpdyFramerVisitorAdapter::OnGoAway(SpdyStreamId last_accepted_stream_id,
-                                        SpdyGoAwayStatus status) {
-  visitor_->OnGoAway(last_accepted_stream_id, status);
-}
-
-void SpdyFramerVisitorAdapter::OnHeaders(SpdyStreamId stream_id,
-                                         bool has_priority,
-                                         SpdyPriority priority,
-                                         SpdyStreamId parent_stream_id,
-                                         bool exclusive,
-                                         bool fin,
-                                         bool end) {
-  visitor_->OnHeaders(stream_id, has_priority, priority, parent_stream_id,
-                      exclusive, fin, end);
-}
-
-void SpdyFramerVisitorAdapter::OnWindowUpdate(SpdyStreamId stream_id,
-                                              int delta_window_size) {
-  visitor_->OnWindowUpdate(stream_id, delta_window_size);
-}
-
-bool SpdyFramerVisitorAdapter::OnGoAwayFrameData(const char* goaway_data,
-                                                 size_t len) {
-  return visitor_->OnGoAwayFrameData(goaway_data, len);
-}
-
-bool SpdyFramerVisitorAdapter::OnRstStreamFrameData(const char* rst_stream_data,
-                                                    size_t len) {
-  return visitor_->OnRstStreamFrameData(rst_stream_data, len);
-}
-
-void SpdyFramerVisitorAdapter::OnBlocked(SpdyStreamId stream_id) {
-  visitor_->OnBlocked(stream_id);
-}
-
-void SpdyFramerVisitorAdapter::OnPushPromise(SpdyStreamId stream_id,
-                                             SpdyStreamId promised_stream_id,
-                                             bool end) {
-  visitor_->OnPushPromise(stream_id, promised_stream_id, end);
-}
-
-void SpdyFramerVisitorAdapter::OnContinuation(SpdyStreamId stream_id,
-                                              bool end) {
-  visitor_->OnContinuation(stream_id, end);
-}
-
-void SpdyFramerVisitorAdapter::OnPriority(SpdyStreamId stream_id,
-                                          SpdyStreamId parent_id,
-                                          SpdyPriority priority,
-                                          bool exclusive) {
-  visitor_->OnPriority(stream_id, parent_id, priority, exclusive);
-}
-
-void SpdyFramerVisitorAdapter::OnAltSvc(
-    SpdyStreamId stream_id,
-    base::StringPiece origin,
-    const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
-  visitor_->OnAltSvc(stream_id, origin, altsvc_vector);
-}
-
-bool SpdyFramerVisitorAdapter::OnUnknownFrame(SpdyStreamId stream_id,
-                                              int frame_type) {
-  return visitor_->OnUnknownFrame(stream_id, frame_type);
-}
-
-class NestedSpdyFramerDecoder : public SpdyFramerDecoderAdapter {
-  typedef SpdyFramer::SpdyState SpdyState;
-  typedef SpdyFramer::SpdyError SpdyError;
-
- public:
-  explicit NestedSpdyFramerDecoder(SpdyFramer* outer)
-      : framer_(HTTP2, false), outer_(outer) {
-    DVLOG(1) << PRETTY_THIS;
-  }
-  ~NestedSpdyFramerDecoder() override { DVLOG(1) << PRETTY_THIS; }
-
-  // Wrap the visitor in a SpdyFramerVisitorAdapter so that the correct
-  // SpdyFramer instance is passed to OnError. Passes the call on to the
-  // base adapter class and wrapped SpdyFramer.
-  void set_visitor(SpdyFramerVisitorInterface* visitor) override {
-    visitor_adapter_.reset(new SpdyFramerVisitorAdapter(visitor, outer_));
-    SpdyFramerDecoderAdapter::set_visitor(visitor_adapter_.get());
-    framer_.set_visitor(visitor_adapter_.get());
-  }
-
-  // Passes the call on to the base adapter class and wrapped SpdyFramer.
-  void set_debug_visitor(
-      SpdyFramerDebugVisitorInterface* debug_visitor) override {
-    SpdyFramerDecoderAdapter::set_debug_visitor(debug_visitor);
-    framer_.set_debug_visitor(debug_visitor);
-  }
-
-  // Passes the call on to the base adapter class and wrapped SpdyFramer.
-  void set_process_single_input_frame(bool v) override {
-    SpdyFramerDecoderAdapter::set_process_single_input_frame(v);
-    framer_.set_process_single_input_frame(v);
-  }
-
-  size_t ProcessInput(const char* data, size_t len) override {
-    DVLOG(2) << "ProcessInput(data, " << len << ")";
-    size_t result = framer_.ProcessInput(data, len);
-    DVLOG(2) << "ProcessInput(data, " << len << ")  returning " << result;
-    return result;
-  }
-
-  void Reset() override { framer_.Reset(); }
-
-  SpdyFramer::SpdyError error_code() const override {
-    return framer_.error_code();
-  }
-  SpdyFramer::SpdyState state() const override { return framer_.state(); }
-  bool probable_http_response() const override {
-    return framer_.probable_http_response();
-  }
-
- private:
-  SpdyFramer framer_;
-  SpdyFramer* const outer_;
-  std::unique_ptr<SpdyFramerVisitorAdapter> visitor_adapter_;
-};
-
-SpdyFramerDecoderAdapter* CreateNestedSpdyFramerDecoder(SpdyFramer* outer) {
-  return new NestedSpdyFramerDecoder(outer);
-}
-
-}  // namespace net
diff --git a/net/spdy/spdy_framer_adapter.h b/net/spdy/spdy_framer_adapter.h
deleted file mode 100644
index 8d9d1f6..0000000
--- a/net/spdy/spdy_framer_adapter.h
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 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 GFE_SPDY_SPDY_FRAMER_ADAPTER_H_
-#define GFE_SPDY_SPDY_FRAMER_ADAPTER_H_
-
-#include <stddef.h>
-
-#include "base/strings/string_piece.h"
-#include "net/spdy/spdy_alt_svc_wire_format.h"
-#include "net/spdy/spdy_framer.h"
-#include "net/spdy/spdy_headers_handler_interface.h"
-#include "net/spdy/spdy_protocol.h"
-
-namespace net {
-
-// Abstract base class for an HTTP/2 decoder to be called from SpdyFramer.
-class SpdyFramerDecoderAdapter {
- public:
-  SpdyFramerDecoderAdapter();
-  virtual ~SpdyFramerDecoderAdapter();
-
-  // Set callbacks to be called from the framer.  A visitor must be set, or
-  // else the framer will likely crash.  It is acceptable for the visitor
-  // to do nothing.  If this is called multiple times, only the last visitor
-  // will be used.
-  virtual void set_visitor(SpdyFramerVisitorInterface* visitor);
-  SpdyFramerVisitorInterface* visitor() const { return visitor_; }
-
-  // Set debug callbacks to be called from the framer. The debug visitor is
-  // completely optional and need not be set in order for normal operation.
-  // If this is called multiple times, only the last visitor will be used.
-  virtual void set_debug_visitor(
-      SpdyFramerDebugVisitorInterface* debug_visitor);
-  SpdyFramerDebugVisitorInterface* debug_visitor() const {
-    return debug_visitor_;
-  }
-
-  // Sets whether or not ProcessInput returns after finishing a frame, or
-  // continues processing additional frames. Normally ProcessInput processes
-  // all input, but this method enables the caller (and visitor) to work with
-  // a single frame at a time (or that portion of the frame which is provided
-  // as input). Reset() does not change the value of this flag.
-  virtual void set_process_single_input_frame(bool v);
-  bool process_single_input_frame() const {
-    return process_single_input_frame_;
-  }
-
-  // Decode the |len| bytes of encoded HTTP/2 starting at |*data|. Returns the
-  // number of bytes consumed. It is safe to pass more bytes in than may be
-  // consumed.
-  virtual size_t ProcessInput(const char* data, size_t len) = 0;
-
-  // Reset the decoder (used just for tests at this time).
-  virtual void Reset() = 0;
-
-  // Current state of the decoder.
-  virtual SpdyFramer::SpdyState state() const = 0;
-
-  // Current error code (NO_ERROR if state != ERROR).
-  virtual SpdyFramer::SpdyError error_code() const = 0;
-
-  // Did the most recently decoded frame header appear to be the start of an
-  // HTTP/1.1 (or earlier) response? Used to detect if a backend/server that
-  // we sent a request to, responded with an HTTP/1.1 response?
-  virtual bool probable_http_response() const = 0;
-
- private:
-  SpdyFramerVisitorInterface* visitor_ = nullptr;
-  SpdyFramerDebugVisitorInterface* debug_visitor_ = nullptr;
-  bool process_single_input_frame_ = false;
-};
-
-// Create an instance of NestedSpdyFramerDecoder, which implements
-// SpdyFramerDecoderAdapter, delegating to a SpdyFramer instance that will
-// actually perform the decoding (when requested via ProcessInput).
-SpdyFramerDecoderAdapter* CreateNestedSpdyFramerDecoder(SpdyFramer* outer);
-
-// SpdyFramerVisitorInterface::OnError needs the original SpdyFramer* to
-// pass to the visitor (really a listener). This implementation takes care of
-// that while passing along all other calls unmodified.
-class SpdyFramerVisitorAdapter : public SpdyFramerVisitorInterface {
- public:
-  SpdyFramerVisitorAdapter(SpdyFramerVisitorInterface* visitor,
-                           SpdyFramer* framer)
-      : visitor_(visitor), framer_(framer) {}
-  ~SpdyFramerVisitorAdapter() override {}
-  // The visitor needs the original SpdyFramer, not the SpdyFramerDecoderAdapter
-  // instance.
-  void OnError(SpdyFramer* framer) override;
-  void OnDataFrameHeader(SpdyStreamId stream_id,
-                         size_t length,
-                         bool fin) override;
-  void OnStreamFrameData(SpdyStreamId stream_id,
-                         const char* data,
-                         size_t len,
-                         bool fin) override;
-  void OnStreamEnd(SpdyStreamId stream_id) override;
-  void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
-  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
-      SpdyStreamId stream_id) override;
-  void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override;
-  bool OnControlFrameHeaderData(SpdyStreamId stream_id,
-                                const char* header_data,
-                                size_t header_data_len) override;
-  void OnSynStream(SpdyStreamId stream_id,
-                   SpdyStreamId associated_stream_id,
-                   SpdyPriority priority,
-                   bool fin,
-                   bool unidirectional) override;
-  void OnSynReply(SpdyStreamId stream_id, bool fin) override;
-  void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override;
-  void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override;
-  void OnPing(SpdyPingId unique_id, bool is_ack) override;
-  void OnSettings(bool clear_persisted) override;
-  void OnSettingsAck() override;
-  void OnSettingsEnd() override;
-  void OnGoAway(SpdyStreamId last_accepted_stream_id,
-                SpdyGoAwayStatus status) override;
-  void OnHeaders(SpdyStreamId stream_id,
-                 bool has_priority,
-                 SpdyPriority priority,
-                 SpdyStreamId parent_stream_id,
-                 bool exclusive,
-                 bool fin,
-                 bool end) override;
-  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
-  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
-  bool OnRstStreamFrameData(const char* rst_stream_data, size_t len) override;
-  void OnBlocked(SpdyStreamId stream_id) override;
-  void OnPushPromise(SpdyStreamId stream_id,
-                     SpdyStreamId promised_stream_id,
-                     bool end) override;
-  void OnContinuation(SpdyStreamId stream_id, bool end) override;
-  void OnPriority(SpdyStreamId stream_id,
-                  SpdyStreamId parent_id,
-                  SpdyPriority priority,
-                  bool exclusive) override;
-  void OnAltSvc(SpdyStreamId stream_id,
-                base::StringPiece origin,
-                const SpdyAltSvcWireFormat::AlternativeServiceVector&
-                    altsvc_vector) override;
-  bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override;
-
- protected:
-  SpdyFramerVisitorInterface* visitor() const { return visitor_; }
-  SpdyFramer* framer() const { return framer_; }
-
- private:
-  SpdyFramerVisitorInterface* const visitor_;
-  SpdyFramer* const framer_;
-};
-
-}  // namespace net
-
-#endif  // GFE_SPDY_SPDY_FRAMER_ADAPTER_H_
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 26bd4b7..67b55002 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -61,20 +61,6 @@
 // Minimum seconds that unclaimed pushed streams will be kept in memory.
 const int kMinPushedStreamLifetimeSeconds = 300;
 
-std::unique_ptr<base::ListValue> SpdyHeaderBlockToListValue(
-    const SpdyHeaderBlock& headers,
-    NetLogCaptureMode capture_mode) {
-  std::unique_ptr<base::ListValue> headers_list(new base::ListValue());
-  for (SpdyHeaderBlock::const_iterator it = headers.begin();
-       it != headers.end(); ++it) {
-    headers_list->AppendString(
-        it->first.as_string() + ": " +
-        ElideHeaderValueForNetLog(capture_mode, it->first.as_string(),
-                                  it->second.as_string()));
-  }
-  return headers_list;
-}
-
 std::unique_ptr<base::Value> NetLogSpdySynStreamSentCallback(
     const SpdyHeaderBlock* headers,
     bool fin,
@@ -83,7 +69,7 @@
     SpdyStreamId stream_id,
     NetLogCaptureMode capture_mode) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
+  dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   dict->SetBoolean("fin", fin);
   dict->SetBoolean("unidirectional", unidirectional);
   dict->SetInteger("priority", static_cast<int>(spdy_priority));
@@ -101,7 +87,7 @@
     bool exclusive,
     NetLogCaptureMode capture_mode) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
+  dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   dict->SetBoolean("fin", fin);
   dict->SetInteger("stream_id", stream_id);
   dict->SetBoolean("has_priority", has_priority);
@@ -122,7 +108,7 @@
     SpdyStreamId associated_stream,
     NetLogCaptureMode capture_mode) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
+  dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   dict->SetBoolean("fin", fin);
   dict->SetBoolean("unidirectional", unidirectional);
   dict->SetInteger("priority", static_cast<int>(spdy_priority));
@@ -137,7 +123,7 @@
     SpdyStreamId stream_id,
     NetLogCaptureMode capture_mode) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
+  dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   dict->SetBoolean("fin", fin);
   dict->SetInteger("stream_id", stream_id);
   return std::move(dict);
@@ -300,7 +286,7 @@
     SpdyStreamId promised_stream_id,
     NetLogCaptureMode capture_mode) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode));
+  dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode));
   dict->SetInteger("id", stream_id);
   dict->SetInteger("promised_stream_id", promised_stream_id);
   return std::move(dict);
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index a2f4770..6f3740f 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -186,7 +186,6 @@
       enable_alternative_service_with_different_host(false),
       enable_quic(false),
       quic_max_server_configs_stored_in_properties(0),
-      quic_delay_tcp_race(false),
       quic_max_number_of_lossy_connections(0),
       quic_prefer_aes(false),
       quic_packet_loss_threshold(1.0f),
@@ -420,8 +419,6 @@
   network_session_params.enable_quic = http_network_session_params_.enable_quic;
   network_session_params.quic_max_server_configs_stored_in_properties =
       http_network_session_params_.quic_max_server_configs_stored_in_properties;
-  network_session_params.quic_delay_tcp_race =
-      http_network_session_params_.quic_delay_tcp_race;
   network_session_params.quic_max_number_of_lossy_connections =
       http_network_session_params_.quic_max_number_of_lossy_connections;
   network_session_params.quic_packet_loss_threshold =
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h
index 2aa534f..20ff0f33 100644
--- a/net/url_request/url_request_context_builder.h
+++ b/net/url_request/url_request_context_builder.h
@@ -96,7 +96,6 @@
     bool enable_quic;
     std::string quic_user_agent_id;
     int quic_max_server_configs_stored_in_properties;
-    bool quic_delay_tcp_race;
     int quic_max_number_of_lossy_connections;
     std::unordered_set<std::string> quic_host_whitelist;
     bool quic_prefer_aes;
@@ -232,10 +231,6 @@
         quic_max_server_configs_stored_in_properties;
   }
 
-  void set_quic_delay_tcp_race(bool quic_delay_tcp_race) {
-    http_network_session_params_.quic_delay_tcp_race = quic_delay_tcp_race;
-  }
-
   void set_quic_max_number_of_lossy_connections(
       int quic_max_number_of_lossy_connections) {
     http_network_session_params_.quic_max_number_of_lossy_connections =
diff --git a/net/url_request/url_request_fuzzer.cc b/net/url_request/url_request_fuzzer.cc
new file mode 100644
index 0000000..db9cdfa
--- /dev/null
+++ b/net/url_request/url_request_fuzzer.cc
@@ -0,0 +1,44 @@
+// 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 "net/url_request/url_request.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+
+#include "base/run_loop.h"
+#include "net/base/fuzzed_data_provider.h"
+#include "net/base/request_priority.h"
+#include "net/socket/fuzzed_socket_factory.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_test_util.h"
+#include "url/gurl.h"
+
+// Integration fuzzer for URLRequest's handling of HTTP requests. Can follow
+// redirects, both on the same server (using a new socket or the old one) and
+// across servers.
+// TODO(mmenke): Add support for testing HTTPS, FTP, auth, proxies, uploading,
+// cancelation, deferring reads / redirects, using preconnected sockets, SPDY,
+// QUIC, DNS failures (they all currently resolve to localhost), IPv6 DNS
+// results, URLs with IPs instead of hostnames (v4 and v6), etc.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  net::FuzzedDataProvider data_provider(data, size);
+  net::TestURLRequestContext url_request_context(true);
+  net::FuzzedSocketFactory fuzzed_socket_factory(&data_provider);
+  url_request_context.set_client_socket_factory(&fuzzed_socket_factory);
+  url_request_context.Init();
+
+  net::TestDelegate delegate;
+
+  std::unique_ptr<net::URLRequest> url_request(
+      url_request_context.CreateRequest(GURL("http://foo/"),
+                                        net::DEFAULT_PRIORITY, &delegate));
+  url_request->Start();
+  // TestDelegate quits the message loop on completion.
+  base::RunLoop().Run();
+  return 0;
+}
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index e1b0ffb0..c38baaf 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -26,7 +26,6 @@
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_delegate.h"
-#include "net/base/network_quality_estimator.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "net/base/sdch_manager.h"
 #include "net/base/sdch_net_log_params.h"
@@ -42,6 +41,7 @@
 #include "net/http/http_transaction.h"
 #include "net/http/http_transaction_factory.h"
 #include "net/http/http_util.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_info.h"
 #include "net/ssl/channel_id_service.h"
 #include "net/ssl/ssl_cert_request_info.h"
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index 71f203a..4928864 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -24,9 +24,9 @@
 #include "net/base/load_states.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_delegate.h"
-#include "net/base/network_quality_estimator.h"
 #include "net/filter/filter.h"
 #include "net/http/http_response_headers.h"
+#include "net/nqe/network_quality_estimator.h"
 #include "net/url_request/url_request_context.h"
 
 namespace net {
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 200349b..512e5cf 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -47,7 +47,6 @@
 #include "net/base/chunked_upload_data_stream.h"
 #include "net/base/directory_listing.h"
 #include "net/base/elements_upload_data_stream.h"
-#include "net/base/external_estimate_provider.h"
 #include "net/base/load_flags.h"
 #include "net/base/load_timing_info.h"
 #include "net/base/load_timing_info_test_util.h"
@@ -81,6 +80,7 @@
 #include "net/log/test_net_log.h"
 #include "net/log/test_net_log_entry.h"
 #include "net/log/test_net_log_util.h"
+#include "net/nqe/external_estimate_provider.h"
 #include "net/proxy/proxy_service.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/ssl/channel_id_service.h"
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc
index a9019b7..a75dbb7 100644
--- a/ppapi/proxy/ppapi_command_buffer_proxy.cc
+++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc
@@ -179,11 +179,6 @@
   NOTIMPLEMENTED();
 }
 
-bool PpapiCommandBufferProxy::IsGpuChannelLost() {
-  NOTIMPLEMENTED();
-  return false;
-}
-
 void PpapiCommandBufferProxy::EnsureWorkVisible() {
   DCHECK_GE(flushed_fence_sync_release_, validated_fence_sync_release_);
   Send(new PpapiHostMsg_PPBGraphics3D_EnsureWorkVisible(
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h
index d827a457..2d812b874 100644
--- a/ppapi/proxy/ppapi_command_buffer_proxy.h
+++ b/ppapi/proxy/ppapi_command_buffer_proxy.h
@@ -67,7 +67,6 @@
                                      unsigned usage) override;
   void SignalQuery(uint32_t query, const base::Closure& callback) override;
   void SetLock(base::Lock*) override;
-  bool IsGpuChannelLost() override;
   void EnsureWorkVisible() override;
   gpu::CommandBufferNamespace GetNamespaceID() const override;
   gpu::CommandBufferId GetCommandBufferID() const override;
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 33d182f..c0b3e75 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -1043,6 +1043,13 @@
 IPC_SYNC_MESSAGE_ROUTED2_0(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
                            ppapi::HostResource /* context */,
                            int32_t /* id */)
+// The receiver of this message takes ownership of the front buffer of the GL
+// context. Each call to PpapiHostMsg_PPBGraphics3D_SwapBuffers must be preceded
+// by exactly one call to PpapiHostMsg_PPBGraphics3D_TakeFrontBuffer. The
+// SyncToken passed to PpapiHostMsg_PPBGraphics3D_SwapBuffers must be generated
+// after this message is sent.
+IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBGraphics3D_TakeFrontBuffer,
+                    ppapi::HostResource /* graphics_3d */)
 IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
                     ppapi::HostResource /* graphics_3d */,
                     gpu::SyncToken /* sync_token */)
diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.cc b/ppapi/proxy/ppb_graphics_3d_proxy.cc
index ccb784b..0c21e37 100644
--- a/ppapi/proxy/ppb_graphics_3d_proxy.cc
+++ b/ppapi/proxy/ppb_graphics_3d_proxy.cc
@@ -105,6 +105,10 @@
   NOTREACHED();
 }
 
+void Graphics3D::TakeFrontBuffer() {
+  NOTREACHED();
+}
+
 gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
   return command_buffer_.get();
 }
@@ -119,6 +123,11 @@
 
   gpu::gles2::GLES2Implementation* gl = gles2_impl();
   gl->SwapBuffers();
+
+  PluginDispatcher::GetForResource(this)->Send(
+      new PpapiHostMsg_PPBGraphics3D_TakeFrontBuffer(API_ID_PPB_GRAPHICS_3D,
+                                                     host_resource()));
+
   const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
   gl->ShallowFlushCHROMIUM();
 
@@ -212,6 +221,8 @@
                         OnMsgDestroyTransferBuffer)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
                         OnMsgSwapBuffers)
+    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_TakeFrontBuffer,
+                        OnMsgTakeFrontBuffer)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_EnsureWorkVisible,
                         OnMsgEnsureWorkVisible)
 #endif  // !defined(OS_NACL)
@@ -345,6 +356,12 @@
         enter.object()->SwapBuffersWithSyncToken(enter.callback(), sync_token));
 }
 
+void PPB_Graphics3D_Proxy::OnMsgTakeFrontBuffer(const HostResource& context) {
+  EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
+  if (enter.succeeded())
+    enter.object()->TakeFrontBuffer();
+}
+
 void PPB_Graphics3D_Proxy::OnMsgEnsureWorkVisible(const HostResource& context) {
   EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
   if (enter.succeeded())
diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.h b/ppapi/proxy/ppb_graphics_3d_proxy.h
index fab0122..2a28fce 100644
--- a/ppapi/proxy/ppb_graphics_3d_proxy.h
+++ b/ppapi/proxy/ppb_graphics_3d_proxy.h
@@ -55,6 +55,7 @@
   gpu::CommandBuffer::State WaitForGetOffsetInRange(int32_t start,
                                                     int32_t end) override;
   void EnsureWorkVisible() override;
+  void TakeFrontBuffer() override;
 
  private:
   // PPB_Graphics3D_Shared overrides.
@@ -110,6 +111,7 @@
   void OnMsgDestroyTransferBuffer(const HostResource& context, int32_t id);
   void OnMsgSwapBuffers(const HostResource& context,
                         const gpu::SyncToken& sync_token);
+  void OnMsgTakeFrontBuffer(const HostResource& context);
   void OnMsgEnsureWorkVisible(const HostResource& context);
   // Renderer->plugin message handlers.
   void OnMsgSwapBuffersACK(const HostResource& context,
diff --git a/ppapi/thunk/ppb_graphics_3d_api.h b/ppapi/thunk/ppb_graphics_3d_api.h
index 05a28c9..845b35f5f 100644
--- a/ppapi/thunk/ppb_graphics_3d_api.h
+++ b/ppapi/thunk/ppb_graphics_3d_api.h
@@ -62,6 +62,7 @@
   virtual void UnmapTexSubImage2DCHROMIUM(const void* mem) = 0;
 
   virtual void EnsureWorkVisible() = 0;
+  virtual void TakeFrontBuffer() = 0;
 };
 
 }  // namespace thunk
diff --git a/printing/pdf_metafile_skia.cc b/printing/pdf_metafile_skia.cc
index d3679c46..27aa930 100644
--- a/printing/pdf_metafile_skia.cc
+++ b/printing/pdf_metafile_skia.cc
@@ -14,7 +14,6 @@
 #include "base/posix/eintr_wrapper.h"
 #include "base/time/time.h"
 #include "printing/print_settings.h"
-#include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkData.h"
 #include "third_party/skia/include/core/SkDocument.h"
@@ -157,17 +156,19 @@
     FinishPage();
 
   SkDynamicMemoryWStream pdf_stream;
-  skia::RefPtr<SkDocument> pdf_doc =
-      skia::AdoptRef(SkDocument::CreatePDF(&pdf_stream));
-  const std::string& user_agent = GetAgent();
-  SkDocument::Attribute info[] = {
-      SkDocument::Attribute(SkString("Creator"),
-                            user_agent.empty()
-                            ? SkString("Chromium")
-                            : SkString(user_agent.c_str(), user_agent.size())),
-  };
+
+  SkDocument::PDFMetadata metadata;
   SkTime::DateTime now = TimeToSkTime(base::Time::Now());
-  pdf_doc->setMetadata(info, SK_ARRAY_COUNT(info), &now, &now);
+  metadata.fCreation.fEnabled = true;
+  metadata.fCreation.fDateTime = now;
+  metadata.fModified.fEnabled = true;
+  metadata.fModified.fDateTime = now;
+  const std::string& agent = GetAgent();
+  metadata.fCreator = agent.empty() ? SkString("Chromium")
+                                    : SkString(agent.c_str(), agent.size());
+  sk_sp<SkDocument> pdf_doc = SkDocument::MakePDF(
+      &pdf_stream, SK_ScalarDefaultRasterDPI, metadata, nullptr, false);
+
   for (const auto& page : data_->pages_) {
     SkCanvas* canvas = pdf_doc->beginPage(
         page.page_size_.width(), page.page_size_.height(), &page.content_area_);
diff --git a/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java b/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java
index 04c3857e9..e5aff2375 100644
--- a/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java
+++ b/remoting/android/host/src/org/chromium/chromoting/host/jni/Host.java
@@ -30,9 +30,8 @@
      * @param context The Application context.
      */
     public static void loadLibrary(Context context) {
-        ContextUtils.initApplicationContext(context.getApplicationContext());
         System.loadLibrary("remoting_host_jni");
-        ContextUtils.initApplicationContextForNative();
+        ContextUtils.initApplicationContext(context);
     }
 
     public Host() {
diff --git a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java
index 47a8d2b..95b1671 100644
--- a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java
+++ b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java
@@ -25,9 +25,9 @@
      * @param context The Application context.
      */
     public static void loadLibrary(Context context) {
-        ContextUtils.initApplicationContext(context.getApplicationContext());
         System.loadLibrary("remoting_client_jni");
-        ContextUtils.initApplicationContextForNative();
+
+        ContextUtils.initApplicationContext(context);
         nativeLoadNative();
     }
 
diff --git a/remoting/host/desktop_process.cc b/remoting/host/desktop_process.cc
index 525e1f66..5cec219b 100644
--- a/remoting/host/desktop_process.cc
+++ b/remoting/host/desktop_process.cc
@@ -25,6 +25,10 @@
 #include "remoting/host/desktop_environment.h"
 #include "remoting/host/desktop_session_agent.h"
 
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif  // defined(OS_WIN)
+
 namespace remoting {
 
 DesktopProcess::DesktopProcess(
@@ -61,6 +65,22 @@
   daemon_channel_->Send(new ChromotingDesktopDaemonMsg_InjectSas());
 }
 
+void DesktopProcess::LockWorkStation() {
+  DCHECK(caller_task_runner_->BelongsToCurrentThread());
+#if defined(OS_WIN)
+  if (base::win::OSInfo::GetInstance()->version_type() ==
+      base::win::VersionType::SUITE_HOME) {
+    return;
+  }
+
+  if (!::LockWorkStation()) {
+    LOG(ERROR) << "LockWorkStation() failed: " << ::GetLastError();
+  }
+#else
+  NOTREACHED();
+#endif  // defined(OS_WIN)
+}
+
 bool DesktopProcess::OnMessageReceived(const IPC::Message& message) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
@@ -102,6 +122,8 @@
   DCHECK(!desktop_environment_factory_);
   DCHECK(desktop_environment_factory);
 
+  IPC::AttachmentBrokerUnprivileged::CreateBrokerIfNeeded();
+
   desktop_environment_factory_ = std::move(desktop_environment_factory);
 
   // Launch the audio capturing thread.
@@ -141,11 +163,12 @@
 
   // Connect to the daemon.
   daemon_channel_.reset(new IPC::ChannelProxy(this, io_task_runner.get()));
-  IPC::AttachmentBrokerUnprivileged::CreateBrokerIfNeeded();
   IPC::AttachmentBroker* broker = IPC::AttachmentBroker::GetGlobal();
-  if (broker && !broker->IsPrivilegedBroker())
+  if (broker && !broker->IsPrivilegedBroker()) {
     broker->RegisterBrokerCommunicationChannel(daemon_channel_.get());
-  daemon_channel_->Init(daemon_channel_name_, IPC::Channel::MODE_CLIENT, true);
+  }
+  daemon_channel_->Init(daemon_channel_name_, IPC::Channel::MODE_CLIENT,
+                        /*create_pipe_now=*/true);
 
   // Pass |desktop_pipe| to the daemon.
   daemon_channel_->Send(
diff --git a/remoting/host/desktop_process.h b/remoting/host/desktop_process.h
index c74133ead..ec3f87ee 100644
--- a/remoting/host/desktop_process.h
+++ b/remoting/host/desktop_process.h
@@ -51,6 +51,9 @@
   // Injects Secure Attention Sequence.
   void InjectSas();
 
+  // Locks the workstation for the current session.
+  void LockWorkStation();
+
   // Creates the desktop agent and required threads and IPC channels. Returns
   // true on success.
   bool Start(
diff --git a/remoting/host/desktop_process_main.cc b/remoting/host/desktop_process_main.cc
index 825a5f5..2fb0767 100644
--- a/remoting/host/desktop_process_main.cc
+++ b/remoting/host/desktop_process_main.cc
@@ -59,7 +59,9 @@
   desktop_environment_factory.reset(new SessionDesktopEnvironmentFactory(
       ui_task_runner, video_capture_task_runner, input_task_runner,
       ui_task_runner,
-      base::Bind(&DesktopProcess::InjectSas, desktop_process.AsWeakPtr())));
+      base::Bind(&DesktopProcess::InjectSas, desktop_process.AsWeakPtr()),
+      base::Bind(&DesktopProcess::LockWorkStation,
+                 desktop_process.AsWeakPtr())));
 #else  // !defined(OS_WIN)
   desktop_environment_factory.reset(new Me2MeDesktopEnvironmentFactory(
       ui_task_runner, video_capture_task_runner, input_task_runner,
diff --git a/remoting/host/ipc_util_win.cc b/remoting/host/ipc_util_win.cc
index 5da5f82..f7f57a6cb 100644
--- a/remoting/host/ipc_util_win.cc
+++ b/remoting/host/ipc_util_win.cc
@@ -59,10 +59,13 @@
   // Wrap the pipe into an IPC channel.
   std::unique_ptr<IPC::ChannelProxy> server(
       new IPC::ChannelProxy(listener, io_task_runner));
-  IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel(
-      server.get(), io_task_runner);
+  IPC::AttachmentBroker* broker = IPC::AttachmentBroker::GetGlobal();
+  DCHECK(broker) << "No AttachmentBroker registered.";
+  if (broker->IsPrivilegedBroker()) {
+    broker->RegisterCommunicationChannel(server.get(), io_task_runner);
+  }
   server->Init(IPC::ChannelHandle(pipe.Get()), IPC::Channel::MODE_SERVER,
-                true);
+               /*create_pipe_now=*/true);
 
   // Convert the channel name to the pipe name.
   std::string pipe_name(kChromePipeNamePrefix);
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index 2715dfe..2dae6c0 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -479,7 +479,8 @@
   IPC::AttachmentBroker* broker = IPC::AttachmentBroker::GetGlobal();
   if (broker && !broker->IsPrivilegedBroker())
     broker->RegisterBrokerCommunicationChannel(daemon_channel_.get());
-  daemon_channel_->Init(channel_handle, IPC::Channel::MODE_CLIENT, true);
+  daemon_channel_->Init(channel_handle, IPC::Channel::MODE_CLIENT,
+                        /*create_pipe_now=*/true);
 
 #else  // !defined(REMOTING_MULTI_PROCESS)
   if (cmd_line->HasSwitch(kHostConfigSwitchName)) {
@@ -860,8 +861,9 @@
 
 #if defined(REMOTING_MULTI_PROCESS)
   IPC::AttachmentBroker* broker = IPC::AttachmentBroker::GetGlobal();
-  if (broker && !broker->IsPrivilegedBroker())
+  if (broker && !broker->IsPrivilegedBroker()) {
     broker->DeregisterBrokerCommunicationChannel(daemon_channel_.get());
+  }
   daemon_channel_.reset();
 #endif  // defined(REMOTING_MULTI_PROCESS)
 
diff --git a/remoting/host/win/session_desktop_environment.cc b/remoting/host/win/session_desktop_environment.cc
index dc19f1d..ef3aacb 100644
--- a/remoting/host/win/session_desktop_environment.cc
+++ b/remoting/host/win/session_desktop_environment.cc
@@ -26,7 +26,7 @@
   return base::WrapUnique(new SessionInputInjectorWin(
       input_task_runner(),
       InputInjector::Create(input_task_runner(), ui_task_runner()),
-      ui_task_runner(), inject_sas_));
+      ui_task_runner(), inject_sas_, lock_workstation_));
 }
 
 SessionDesktopEnvironment::SessionDesktopEnvironment(
@@ -35,25 +35,29 @@
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
     const base::Closure& inject_sas,
+    const base::Closure& lock_workstation,
     bool supports_touch_events)
     : Me2MeDesktopEnvironment(caller_task_runner,
                               video_capture_task_runner,
                               input_task_runner,
                               ui_task_runner,
                               supports_touch_events),
-      inject_sas_(inject_sas) {}
+      inject_sas_(inject_sas),
+      lock_workstation_(lock_workstation) {}
 
 SessionDesktopEnvironmentFactory::SessionDesktopEnvironmentFactory(
     scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
-    const base::Closure& inject_sas)
+    const base::Closure& inject_sas,
+    const base::Closure& lock_workstation)
     : Me2MeDesktopEnvironmentFactory(caller_task_runner,
                                      video_capture_task_runner,
                                      input_task_runner,
                                      ui_task_runner),
-      inject_sas_(inject_sas) {
+      inject_sas_(inject_sas),
+      lock_workstation_(lock_workstation) {
   DCHECK(caller_task_runner->BelongsToCurrentThread());
 }
 
@@ -64,10 +68,10 @@
   DCHECK(caller_task_runner()->BelongsToCurrentThread());
 
   std::unique_ptr<SessionDesktopEnvironment> desktop_environment(
-      new SessionDesktopEnvironment(caller_task_runner(),
-                                    video_capture_task_runner(),
-                                    input_task_runner(), ui_task_runner(),
-                                    inject_sas_, supports_touch_events()));
+      new SessionDesktopEnvironment(
+          caller_task_runner(), video_capture_task_runner(),
+          input_task_runner(), ui_task_runner(), inject_sas_, lock_workstation_,
+          supports_touch_events()));
   if (!desktop_environment->InitializeSecurity(client_session_control,
                                                curtain_enabled())) {
     return nullptr;
diff --git a/remoting/host/win/session_desktop_environment.h b/remoting/host/win/session_desktop_environment.h
index a74f6fc..53248f66 100644
--- a/remoting/host/win/session_desktop_environment.h
+++ b/remoting/host/win/session_desktop_environment.h
@@ -30,11 +30,15 @@
       scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
       const base::Closure& inject_sas,
+      const base::Closure& lock_workstation,
       bool supports_touch_events);
 
   // Used to ask the daemon to inject Secure Attention Sequence.
   base::Closure inject_sas_;
 
+  // Used to lock the workstation for the current session.
+  base::Closure lock_workstation_;
+
   DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironment);
 };
 
@@ -46,7 +50,8 @@
       scoped_refptr<base::SingleThreadTaskRunner> video_capture_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
-      const base::Closure& inject_sas);
+      const base::Closure& inject_sas,
+      const base::Closure& lock_workstation);
   ~SessionDesktopEnvironmentFactory() override;
 
   // DesktopEnvironmentFactory implementation.
@@ -57,6 +62,9 @@
   // Used to ask the daemon to inject Secure Attention Sequence.
   base::Closure inject_sas_;
 
+  // Used to lock the workstation for the current session.
+  base::Closure lock_workstation_;
+
   DISALLOW_COPY_AND_ASSIGN(SessionDesktopEnvironmentFactory);
 };
 
diff --git a/remoting/host/win/session_input_injector.cc b/remoting/host/win/session_input_injector.cc
index 9b68518..0acccbe49 100644
--- a/remoting/host/win/session_input_injector.cc
+++ b/remoting/host/win/session_input_injector.cc
@@ -34,6 +34,12 @@
     (ctrl_keys + alt_keys == pressed_keys.size());
 }
 
+bool IsWinKeyPressed(const std::set<ui::DomCode>& pressed_keys) {
+  size_t win_keys = pressed_keys.count(ui::DomCode::META_LEFT) +
+                    pressed_keys.count(ui::DomCode::META_RIGHT);
+  return win_keys != 0 && win_keys == pressed_keys.size();
+}
+
 } // namespace
 
 namespace remoting {
@@ -51,7 +57,8 @@
   Core(scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
        std::unique_ptr<InputInjector> nested_executor,
        scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner,
-       const base::Closure& inject_sas);
+       const base::Closure& inject_sas,
+       const base::Closure& lock_workstation);
 
   // InputInjector implementation.
   void Start(std::unique_ptr<ClipboardStub> client_clipboard) override;
@@ -78,17 +85,20 @@
   // Pointer to the next event executor.
   std::unique_ptr<InputInjector> nested_executor_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner_;
 
   webrtc::ScopedThreadDesktop desktop_;
 
   // Used to inject Secure Attention Sequence on Vista+.
   base::Closure inject_sas_;
 
+  // Used to lock the current session on non-home SKUs of Windows.
+  base::Closure lock_workstation_;
+
   // Used to inject Secure Attention Sequence on XP.
   std::unique_ptr<SasInjector> sas_injector_;
 
-  // Keys currently pressed by the client, used to detect Ctrl-Alt-Del.
+  // Keys currently pressed by the client, used to detect key sequences.
   std::set<ui::DomCode> pressed_keys_;
 
   DISALLOW_COPY_AND_ASSIGN(Core);
@@ -97,12 +107,14 @@
 SessionInputInjectorWin::Core::Core(
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
     std::unique_ptr<InputInjector> nested_executor,
-    scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner,
-    const base::Closure& inject_sas)
+    scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner,
+    const base::Closure& inject_sas,
+    const base::Closure& lock_workstation)
     : input_task_runner_(input_task_runner),
       nested_executor_(std::move(nested_executor)),
-      inject_sas_task_runner_(inject_sas_task_runner),
-      inject_sas_(inject_sas) {}
+      execute_action_task_runner_(execute_action_task_runner),
+      inject_sas_(inject_sas),
+      lock_workstation_(lock_workstation) {}
 
 void SessionInputInjectorWin::Core::Start(
     std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
@@ -151,8 +163,11 @@
           if (!sas_injector_->InjectSas())
             LOG(ERROR) << "Failed to inject Secure Attention Sequence.";
         } else {
-          inject_sas_task_runner_->PostTask(FROM_HERE, inject_sas_);
+          execute_action_task_runner_->PostTask(FROM_HERE, inject_sas_);
         }
+      } else if (dom_code == ui::DomCode::US_L &&
+                 IsWinKeyPressed(pressed_keys_)) {
+        execute_action_task_runner_->PostTask(FROM_HERE, lock_workstation_);
       }
 
       pressed_keys_.insert(dom_code);
@@ -217,9 +232,10 @@
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
     std::unique_ptr<InputInjector> nested_executor,
     scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner,
-    const base::Closure& inject_sas) {
+    const base::Closure& inject_sas,
+    const base::Closure& lock_workstation) {
   core_ = new Core(input_task_runner, std::move(nested_executor),
-                   inject_sas_task_runner, inject_sas);
+                   inject_sas_task_runner, inject_sas, lock_workstation);
 }
 
 SessionInputInjectorWin::~SessionInputInjectorWin() {
diff --git a/remoting/host/win/session_input_injector.h b/remoting/host/win/session_input_injector.h
index ed818c98..5579f182 100644
--- a/remoting/host/win/session_input_injector.h
+++ b/remoting/host/win/session_input_injector.h
@@ -18,18 +18,18 @@
 
 namespace remoting {
 
-// Monitors and passes key/mouse events to a nested event executor. Injects
-// Secure Attention Sequence (SAS) when Ctrl+Alt+Del key combination has been
-// detected.
+// Monitors and passes key/mouse events to a nested event executor. Also handles
+// Ctrl+Alt+Del and Win+L key combinations by invoking the given callbacks.
 class SessionInputInjectorWin : public InputInjector {
  public:
-  // |inject_sas| is invoked on |inject_sas_task_runner| to generate SAS on
-  // Vista+.
+  // |inject_sas| and |lock_workstation| are invoked on
+  // |execute_action_task_runner|.
   SessionInputInjectorWin(
       scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
       std::unique_ptr<InputInjector> nested_executor,
-      scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner,
-      const base::Closure& inject_sas);
+      scoped_refptr<base::SingleThreadTaskRunner> execute_action_task_runner,
+      const base::Closure& inject_sas,
+      const base::Closure& lock_workstation);
   ~SessionInputInjectorWin() override;
 
   // InputInjector implementation.
diff --git a/remoting/host/win/wts_session_process_delegate.cc b/remoting/host/win/wts_session_process_delegate.cc
index 779cc62..7342b2e 100644
--- a/remoting/host/win/wts_session_process_delegate.cc
+++ b/remoting/host/win/wts_session_process_delegate.cc
@@ -387,7 +387,7 @@
   IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel(
       channel.get(), io_task_runner_);
   channel->Init(IPC::ChannelHandle(pipe.Get()), IPC::Channel::MODE_SERVER,
-                true);
+                /*create_pipe_now=*/true);
 
   // Pass the name of the IPC channel to use.
   command_line.AppendSwitchNative(kDaemonPipeSwitchName,
diff --git a/services/catalog/BUILD.gn b/services/catalog/BUILD.gn
index 46f166d..f19696b 100644
--- a/services/catalog/BUILD.gn
+++ b/services/catalog/BUILD.gn
@@ -52,6 +52,9 @@
   sources = [
     "entry_unittest.cc",
   ]
+  data = [
+    "//services/catalog/data/",
+  ]
   deps = [
     ":lib",
     "//base",
diff --git a/services/shell/mojo_shell_unittests.isolate b/services/shell/mojo_shell_unittests.isolate
new file mode 100644
index 0000000..bc4dc772
--- /dev/null
+++ b/services/shell/mojo_shell_unittests.isolate
@@ -0,0 +1,23 @@
+# 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.
+{
+  'includes': [
+    '../../mojo/mojo.isolate',
+  ],
+  'conditions': [
+    ['OS=="win" or OS=="mac" or OS=="linux"', {
+      'variables': {
+        'command': [
+          '../../testing/test_env.py',
+          '<(PRODUCT_DIR)/mojo_shell_unittests<(EXECUTABLE_SUFFIX)',
+          '--brave-new-test-launcher',
+          '--test-launcher-bot-mode',
+        ],
+        'files': [
+          '../../testing/test_env.py',
+        ],
+      },
+    }],
+  ],
+}
diff --git a/services/shell/shell.gyp b/services/shell/shell.gyp
index 2ec9da5..f4c2a51e 100644
--- a/services/shell/shell.gyp
+++ b/services/shell/shell.gyp
@@ -248,4 +248,23 @@
       'public/cpp/tests/interface_registry_unittest.cc',
     ],
   }],
+  'conditions': [
+    ['test_isolation_mode != "noop"', {
+      'targets': [
+        {
+          'target_name': 'mojo_shell_unittests_run',
+          'type': 'none',
+          'dependencies': [
+            'mojo_shell_unittests',
+          ],
+          'includes': [
+            '../../build/isolate.gypi',
+          ],
+          'sources': [
+            'mojo_shell_unittests.isolate',
+          ],
+        },
+      ],
+    }],
+  ],
 }
diff --git a/services/shell/tests/connect/BUILD.gn b/services/shell/tests/connect/BUILD.gn
index 50c0d07..00bf944 100644
--- a/services/shell/tests/connect/BUILD.gn
+++ b/services/shell/tests/connect/BUILD.gn
@@ -62,13 +62,15 @@
     "connect_test_package.cc",
   ]
   deps = [
-    ":connect_test_package_manifest",
     ":interfaces",
     "//base",
     "//mojo/common:common_base",
     "//services/shell/public/cpp:sources",
     "//services/shell/public/interfaces",
   ]
+  data_deps = [
+    ":connect_test_package_manifest",
+  ]
 }
 
 mojo_application_manifest("connect_test_package_manifest") {
@@ -90,13 +92,15 @@
     "connect_test_app.cc",
   ]
   deps = [
-    ":connect_test_app_manifest",
     ":interfaces",
     "//base",
     "//mojo/common:common_base",
     "//services/shell/public/cpp:sources",
     "//services/shell/public/interfaces",
   ]
+  data_deps = [
+    ":connect_test_app_manifest",
+  ]
 }
 
 mojo_application_manifest("connect_test_app_manifest") {
@@ -110,13 +114,15 @@
     "connect_test_class_app.cc",
   ]
   deps = [
-    ":connect_test_class_app_manifest",
     ":interfaces",
     "//base",
     "//mojo/common:common_base",
     "//services/shell/public/cpp:sources",
     "//services/shell/public/interfaces",
   ]
+  data_deps = [
+    ":connect_test_class_app_manifest",
+  ]
 }
 
 mojo_application_manifest("connect_test_class_app_manifest") {
@@ -130,11 +136,13 @@
     "connect_test_singleton_app.cc",
   ]
   deps = [
-    ":connect_test_singleton_app_manifest",
     "//base",
     "//mojo/common:common_base",
     "//services/shell/public/cpp:sources",
   ]
+  data_deps = [
+    ":connect_test_singleton_app_manifest",
+  ]
 }
 
 mojo_application_manifest("connect_test_singleton_app_manifest") {
diff --git a/services/shell/tests/lifecycle/BUILD.gn b/services/shell/tests/lifecycle/BUILD.gn
index e44b714..3e002e7 100644
--- a/services/shell/tests/lifecycle/BUILD.gn
+++ b/services/shell/tests/lifecycle/BUILD.gn
@@ -74,11 +74,13 @@
   deps = [
     ":app_client",
     ":interfaces",
-    ":lifecycle_unittest_package_manifest",
     "//base",
     "//services/shell/public/cpp:sources",
     "//services/shell/public/interfaces",
   ]
+  data_deps = [
+    ":lifecycle_unittest_package_manifest",
+  ]
 }
 
 mojo_application_manifest("lifecycle_unittest_package_manifest") {
diff --git a/styleguide/c++/c++11.html b/styleguide/c++/c++11.html
index 12644ef..7bacf868 100644
--- a/styleguide/c++/c++11.html
+++ b/styleguide/c++/c++11.html
@@ -189,7 +189,12 @@
 
 <tr>
 <td>Local Types as Template Arguments</td>
-<td></td>
+<td><code>void func() {<br />
+&nbsp;&nbsp;class Pred {<br />
+&nbsp;&nbsp;&nbsp;public:<br />
+&nbsp;&nbsp;&nbsp;&nbsp;bool operator()(const T&) { ... }<br />
+&nbsp;&nbsp;};<br />
+&nbsp;&nbsp;std::remove_if(vec.begin(), vec.end(), Pred());</code></td>
 <td>Allows local and unnamed types as template arguments</td>
 <td><a href="http://stackoverflow.com/questions/742607/using-local-classes-with-stl-algorithms">Local types, types without linkage and unnamed types as template arguments</a></td>
 <td>Usage should be rare. Approved without discussion.</td>
@@ -255,6 +260,14 @@
 </tr>
 
 <tr>
+<td>Uniform Initialization Syntax</td>
+<td><code><i>type</i> <i>name</i> {[<i>value</i> ..., <i>value</i>]};</code></td>
+<td>Allows any object of primitive, aggregate or class type to be initialized using brace syntax</td>
+<td><a href="http://www.stroustrup.com/C++11FAQ.html#uniform-init">Uniform initialization syntax and semantics</a></td>
+<td>See the <a href="https://www.chromium.org/developers/coding-style/cpp-dos-and-donts?pli=1#TOC-Variable-initialization">Chromium C++ Dos And Don'ts guidance</a> on when to use this. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/GF96FshwHLw">Discussion thread</a></td>
+</tr>
+
+<tr>
 <td>Variadic Macros</td>
 <td><code>#define <i>MACRO</i>(...) <i>Impl</i>(<i>args</i>, __VA_ARGS__)</code></td>
 <td>Allows macros that accept a variable number of arguments</td>
@@ -310,7 +323,7 @@
 <code>minmax</code>, <code>minmax_element</code><br/>
 <code>is_permutation<br/></td>
 <td>Safe and performant implementations of common algorithms</td>
-<td><a href="http://en.cppreference.com/w/cpp/header/algorithm"><code>&lt;algorithm&gt;</code></a></td>
+<td><a href="http://en.cppreference.com/w/cpp/header/algorithm">&lt;algorithm&gt;</a></td>
 <td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/UJQk8S1IuHk">Discussion thread</a><br/> Note that &lt;algorithm&gt; contains a range-based <code>move</code> method. This is allowed, but because people may confuse it with the single-arg <code>std::move</code>, there is often a way to write code without it that is more readable. <a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/8WzmtYrZvQ8'>Discussion thread</a></td>
 </tr>
 
@@ -366,12 +379,20 @@
 <td>Forwarding references</td>
 <td><code>std::forward()</code></td>
 <td>Perfectly forwards arguments (including rvalues)</td>
-<td><a href="http://en.cppreference.com/w/cpp/utility/forward"><code>std::forward</code></a></td>
+<td><a href="http://en.cppreference.com/w/cpp/utility/forward">std::forward</a></td>
 <td>Allowed, though usage should be rare (primarily for forwarding constructor arguments, or in carefully reviewed library code). <a href="https://groups.google.com/a/chromium.org/d/topic/cxx/-O7euklhSxs/discussion">Discussion thread</a>
 </td>
 </tr>
 
 <tr>
+<td>Initializer Lists</td>
+<td><code>std::initializer_list&lt;T&gt;</code></td>
+<td>Allows containers to be initialized with aggregate elements</td>
+<td><a href="http://en.cppreference.com/w/cpp/utility/initializer_list">std::initializer_list</a></td>
+<td>Be cautious adding new constructors which take these, as they can hide non-initializer_list constructors in undesirable ways; see Effective Modern C++ Item 7 for more.</td>
+</tr>
+
+<tr>
 <td>Lexicographical struct comparison</td>
 <td><code>tie(a, b, c) &lt;<br>&nbsp; tie(rhs.a, rhs.b, rhs.c)</code></td>
 <td>Idiom for <code>operator&lt;</code> implementation</td>
@@ -387,7 +408,7 @@
 <code>fmax</code>, <code>fmin</code>, <code>trunc</code>, <code>round</code><br/>
 <code>isinf</code>, <code>isnan</code><br/></td>
 <td>Useful for math-related code</td>
-<td><a href="http://en.cppreference.com/w/cpp/header/cmath"><code>&lt;cmath&gt;</code></a></td>
+<td><a href="http://en.cppreference.com/w/cpp/header/cmath">&lt;cmath&gt;</a></td>
 <td><a href="https://groups.google.com/a/chromium.org/forum/#!topic/cxx/P-1bFBXMeUk">Discussion thread</a></td>
 </tr>
 
@@ -403,7 +424,7 @@
 <td>Move Semantics</td>
 <td><code>std::move()</code></td>
 <td>Facilitates efficient move operations</td>
-<td><a href="http://en.cppreference.com/w/cpp/utility/move"><code>std::move</code> reference</a></td>
+<td><a href="http://en.cppreference.com/w/cpp/utility/move">std::move</a></td>
 <td><a href='https://groups.google.com/a/chromium.org/forum/#!topic/cxx/x_dWFxJFdbM'>Discussion thread</a></td>
 </tr>
 
@@ -519,14 +540,6 @@
 </tr>
 
 <tr>
-<td>(Uniform) Initialization Syntax</td>
-<td><code><i>type</i> <i>name</i> {[<i>value</i> ..., <i>value</i>]};</code></td>
-<td>Allows any object of primitive, aggregate or class type to be initialized using brace syntax</td>
-<td>TODO: documentation link</td>
-<td>Reevaulate now that MSVS2015 is available. <a href="https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/GF96FshwHLw">Discussion thread</a></td>
-</tr>
-
-<tr>
 <td>UTF-16 and UTF-32 Support (16-Bit and 32-Bit Character Types)</td>
 <td><code>char16_t</code> and <code>char32_t</code></td>
 <td>Provides character types for handling 16-bit and 32-bit code units (useful for encoding UTF-16 and UTF-32 string data)</td>
@@ -615,14 +628,6 @@
 <td>Needs a lot more evaluation for Chromium, and there isn't enough of a push for this feature. <a href="https://google.github.io/styleguide/cppguide.html#Ownership_and_Smart_Pointers">Google Style Guide</a>. <a href="https://groups.google.com/a/chromium.org/d/topic/cxx/aT2wsBLKvzI/discussion">Discussion Thread</a>.</td>
 </tr>
 
-<tr>
-<td>Initializer Lists</td>
-<td><code>std::initializer_list&lt;T&gt;</code></td>
-<td>Allows containers to be initialized with aggregate elements</td>
-<td><a href="http://en.cppreference.com/w/cpp/utility/initializer_list"><code>std::initializer_list</code></a></td>
-<td>Reevaluate now that MSVS2015 is available. <a href="https://groups.google.com/a/chromium.org/d/topic/cxx/TQQ-L51_naM/discussion">Discussion Thread</a></td>
-</tr>
-
 </tbody>
 </table>
 
diff --git a/sync/BUILD.gn b/sync/BUILD.gn
index 4e0ffeb..a859663 100644
--- a/sync/BUILD.gn
+++ b/sync/BUILD.gn
@@ -660,6 +660,7 @@
     "internal_api/public/data_batch_impl_unittest.cc",
     "internal_api/public/engine/model_safe_worker_unittest.cc",
     "internal_api/public/sessions/sync_session_snapshot_unittest.cc",
+    "internal_api/public/simple_metadata_change_list_unittest.cc",
     "internal_api/public/util/immutable_unittest.cc",
     "internal_api/public/util/proto_value_ptr_unittest.cc",
     "internal_api/public/util/weak_handle_unittest.cc",
diff --git a/sync/api/mock_model_type_store.cc b/sync/api/mock_model_type_store.cc
index 41bc977..46a19abf 100644
--- a/sync/api/mock_model_type_store.cc
+++ b/sync/api/mock_model_type_store.cc
@@ -141,6 +141,11 @@
   write_metadata_handler_ = handler;
 }
 
+void MockModelTypeStore::RegisterWriteGlobalMetadataHandler(
+    const WriteGlobalMetadataSignature& handler) {
+  write_global_metadata_handler_ = handler;
+}
+
 void MockModelTypeStore::RegisterDeleteDataHandler(
     const DeleteRecordSignature& handler) {
   delete_data_handler_ = handler;
@@ -151,4 +156,9 @@
   delete_metadata_handler_ = handler;
 }
 
+void MockModelTypeStore::RegisterDeleteGlobalMetadataHandler(
+    const DeleteGlobalMetadataSignature& handler) {
+  delete_global_metadata_handler_ = handler;
+}
+
 }  // namespace syncer_v2
diff --git a/sync/internal_api/public/simple_metadata_change_list.cc b/sync/internal_api/public/simple_metadata_change_list.cc
index e358dda..591f75e73 100644
--- a/sync/internal_api/public/simple_metadata_change_list.cc
+++ b/sync/internal_api/public/simple_metadata_change_list.cc
@@ -46,7 +46,34 @@
 void SimpleMetadataChangeList::TransferChanges(
     ModelTypeStore* store,
     ModelTypeStore::WriteBatch* write_batch) {
-  // TODO(skym): Implementation.
+  DCHECK(write_batch);
+  DCHECK(store);
+  for (const auto& pair : metadata_changes_) {
+    const std::string& key = pair.first;
+    const MetadataChange& change = pair.second;
+    switch (change.type) {
+      case UPDATE:
+        store->WriteMetadata(write_batch, key,
+                             change.metadata.SerializeAsString());
+        break;
+      case CLEAR:
+        store->DeleteMetadata(write_batch, key);
+        break;
+    }
+  }
+  metadata_changes_.clear();
+  if (HasDataTypeStateChange()) {
+    switch (state_change_->type) {
+      case UPDATE:
+        store->WriteGlobalMetadata(write_batch,
+                                   state_change_->state.SerializeAsString());
+        break;
+      case CLEAR:
+        store->DeleteGlobalMetadata(write_batch);
+        break;
+    }
+    state_change_.reset();
+  }
 }
 
 }  // namespace syncer_v2
diff --git a/sync/internal_api/public/simple_metadata_change_list_unittest.cc b/sync/internal_api/public/simple_metadata_change_list_unittest.cc
new file mode 100644
index 0000000..ff2fea6
--- /dev/null
+++ b/sync/internal_api/public/simple_metadata_change_list_unittest.cc
@@ -0,0 +1,188 @@
+// 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 "sync/internal_api/public/simple_metadata_change_list.h"
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "sync/api/mock_model_type_store.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace syncer_v2 {
+namespace {
+
+using WriteBatch = ModelTypeStore::WriteBatch;
+
+void RecordMetadataWrite(std::map<std::string, std::string>* map,
+                         WriteBatch* batch,
+                         const std::string& key,
+                         const std::string& value) {
+  (*map)[key] = value;
+}
+
+void RecordGlobalMetadataWrite(std::string* str,
+                               WriteBatch* batch,
+                               const std::string& value) {
+  *str = value;
+}
+
+void RecordMetadataDelete(std::set<std::string>* set,
+                          WriteBatch* batch,
+                          const std::string& id) {
+  set->insert(id);
+}
+
+void RecordGlobalMetadataDelete(bool* was_delete_called, WriteBatch* batch) {
+  *was_delete_called = true;
+}
+
+class SimpleMetadataChangeListTest : public testing::Test {
+ protected:
+  SimpleMetadataChangeListTest() {}
+
+  MockModelTypeStore* store() { return &store_; }
+
+ private:
+  // MockModelTypeStore needs MessageLoop
+  base::MessageLoop message_loop_;
+
+  MockModelTypeStore store_;
+};
+
+TEST_F(SimpleMetadataChangeListTest, TransferChangesEmptyChangeList) {
+  SimpleMetadataChangeList cl;
+  std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch();
+
+  std::map<std::string, std::string> change_map;
+  std::set<std::string> delete_set;
+  std::string global_metadata;
+  store()->RegisterWriteMetadataHandler(
+      base::Bind(&RecordMetadataWrite, &change_map));
+  store()->RegisterWriteGlobalMetadataHandler(
+      base::Bind(&RecordGlobalMetadataWrite, &global_metadata));
+  store()->RegisterDeleteMetadataHandler(
+      base::Bind(&RecordMetadataDelete, &delete_set));
+
+  cl.TransferChanges(store(), batch.get());
+
+  EXPECT_EQ(change_map.size(), 0ul);
+  EXPECT_EQ(delete_set.size(), 0ul);
+  EXPECT_EQ(global_metadata.size(), 0ul);
+}
+
+TEST_F(SimpleMetadataChangeListTest, TransferChangesClearsLocalState) {
+  SimpleMetadataChangeList cl;
+  sync_pb::EntityMetadata metadata;
+  metadata.set_client_tag_hash("some_hash");
+  cl.UpdateMetadata("client_tag", metadata);
+
+  sync_pb::DataTypeState state;
+  state.set_encryption_key_name("ekn");
+  cl.UpdateDataTypeState(state);
+
+  EXPECT_NE(cl.GetMetadataChanges().size(), 0ul);
+  EXPECT_TRUE(cl.HasDataTypeStateChange());
+
+  std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch();
+  cl.TransferChanges(store(), batch.get());
+
+  EXPECT_EQ(cl.GetMetadataChanges().size(), 0ul);
+  EXPECT_FALSE(cl.HasDataTypeStateChange());
+}
+
+TEST_F(SimpleMetadataChangeListTest, TransferChangesMultipleInvocationsSafe) {
+  SimpleMetadataChangeList cl;
+  sync_pb::EntityMetadata metadata;
+  metadata.set_client_tag_hash("some_hash");
+  cl.UpdateMetadata("client_tag", metadata);
+
+  sync_pb::DataTypeState state;
+  state.set_encryption_key_name("ekn");
+  cl.UpdateDataTypeState(state);
+
+  std::string global_metadata;
+  std::map<std::string, std::string> change_map;
+  store()->RegisterWriteMetadataHandler(
+      base::Bind(&RecordMetadataWrite, &change_map));
+  store()->RegisterWriteGlobalMetadataHandler(
+      base::Bind(&RecordGlobalMetadataWrite, &global_metadata));
+
+  std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch();
+  cl.TransferChanges(store(), batch.get());
+  cl.TransferChanges(store(), batch.get());
+  cl.TransferChanges(store(), batch.get());
+
+  EXPECT_EQ(state.SerializeAsString(), global_metadata);
+  EXPECT_EQ(metadata.SerializeAsString(), change_map["client_tag"]);
+}
+
+TEST_F(SimpleMetadataChangeListTest, TransferChangesMultipleChanges) {
+  SimpleMetadataChangeList cl;
+
+  sync_pb::EntityMetadata metadata;
+  metadata.set_client_tag_hash("some_hash");
+  cl.UpdateMetadata("client_tag", metadata);
+  metadata.set_specifics_hash("specifics_hash");
+  cl.UpdateMetadata("client_tag", metadata);
+
+  sync_pb::EntityMetadata metadata2;
+  metadata2.set_client_tag_hash("some_other_hash");
+  cl.UpdateMetadata("client_tag2", metadata2);
+
+  sync_pb::DataTypeState state;
+  state.set_encryption_key_name("ekn");
+  cl.UpdateDataTypeState(state);
+  state.set_encryption_key_name("ekn2");
+  cl.UpdateDataTypeState(state);
+
+  std::string global_metadata;
+  std::map<std::string, std::string> change_map;
+  store()->RegisterWriteGlobalMetadataHandler(
+      base::Bind(&RecordGlobalMetadataWrite, &global_metadata));
+  store()->RegisterWriteMetadataHandler(
+      base::Bind(&RecordMetadataWrite, &change_map));
+
+  std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch();
+  cl.TransferChanges(store(), batch.get());
+
+  EXPECT_EQ(metadata.SerializeAsString(), change_map["client_tag"]);
+  EXPECT_EQ(metadata2.SerializeAsString(), change_map["client_tag2"]);
+  EXPECT_EQ(state.SerializeAsString(), global_metadata);
+}
+
+TEST_F(SimpleMetadataChangeListTest, TransferChangesDeletesClearedItems) {
+  SimpleMetadataChangeList cl;
+  sync_pb::EntityMetadata metadata;
+  metadata.set_client_tag_hash("some_hash");
+  cl.UpdateMetadata("client_tag", metadata);
+  cl.ClearMetadata("client_tag");
+
+  sync_pb::DataTypeState state;
+  state.set_encryption_key_name("ekn");
+  cl.UpdateDataTypeState(state);
+  cl.ClearDataTypeState();
+
+  std::map<std::string, std::string> change_map;
+  std::set<std::string> delete_set;
+  std::string global_metadata;
+  bool delete_called = false;
+  store()->RegisterWriteMetadataHandler(
+      base::Bind(&RecordMetadataWrite, &change_map));
+  store()->RegisterWriteGlobalMetadataHandler(
+      base::Bind(&RecordGlobalMetadataWrite, &global_metadata));
+  store()->RegisterDeleteMetadataHandler(
+      base::Bind(&RecordMetadataDelete, &delete_set));
+  store()->RegisterDeleteGlobalMetadataHandler(
+      base::Bind(&RecordGlobalMetadataDelete, &delete_called));
+
+  std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch();
+  cl.TransferChanges(store(), batch.get());
+
+  EXPECT_TRUE(delete_set.find("client_tag") != delete_set.end());
+  EXPECT_TRUE(change_map.find("client_tag") == change_map.end());
+  EXPECT_TRUE(delete_called);
+  EXPECT_TRUE(global_metadata.empty());
+}
+
+}  // namespace
+}  // namespace syncer_v2
diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi
index f98f1684..89bbd7e4 100644
--- a/sync/sync_tests.gypi
+++ b/sync/sync_tests.gypi
@@ -324,6 +324,7 @@
         'internal_api/public/data_batch_impl_unittest.cc',
         'internal_api/public/engine/model_safe_worker_unittest.cc',
         'internal_api/public/sessions/sync_session_snapshot_unittest.cc',
+        'internal_api/public/simple_metadata_change_list_unittest.cc',
         'internal_api/public/util/immutable_unittest.cc',
         'internal_api/public/util/proto_value_ptr_unittest.cc',
         'internal_api/public/util/weak_handle_unittest.cc',
diff --git a/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java b/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java
index 8411583..c708549 100644
--- a/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java
+++ b/testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java
@@ -6,7 +6,6 @@
 
 import android.os.Bundle;
 
-import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.PathUtils;
 import org.chromium.base.PowerMonitor;
@@ -30,7 +29,6 @@
         // Needed by system_monitor_unittest.cc
         PowerMonitor.createForTests(this);
 
-        ContextUtils.initApplicationContext(getApplicationContext());
         loadLibraries();
     }
 
@@ -40,6 +38,5 @@
             System.loadLibrary(library);
             Log.i(TAG, "loaded: %s", library);
         }
-        ContextUtils.initApplicationContextForNative();
     }
 }
diff --git a/testing/android/native_test/native_test_launcher.cc b/testing/android/native_test/native_test_launcher.cc
index 0f880a74..eb652d99 100644
--- a/testing/android/native_test/native_test_launcher.cc
+++ b/testing/android/native_test/native_test_launcher.cc
@@ -75,6 +75,10 @@
   static const char* const kInitialArgv[] = { "ChromeTestActivity" };
   base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
 
+  // Set the application context in base.
+  base::android::RegisterJni(env);
+  base::android::InitApplicationContext(env, app_context);
+
   std::vector<std::string> args;
 
   const std::string command_line_file_path(
@@ -129,9 +133,6 @@
 }
 
 bool RegisterNativeTestJNI(JNIEnv* env) {
-  if (!base::android::RegisterJni(env)) {
-    return false;
-  }
   return RegisterNativesImpl(env);
 }
 
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 3b4b3b6..a72ee23 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -12,6 +12,10 @@
   "Android Swarm Builder": {
     "gtest_tests": [
       {
+        "override_compile_targets": [
+          "android_webview_test_apk"
+        ],
+        "override_isolate_target": "android_webview_test_apk",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -22,9 +26,10 @@
           ],
           "hard_timeout": 960
         },
-        "test": "android_webview_test"
+        "test": "android_webview_test_apk"
       },
       {
+        "override_isolate_target": "android_webview_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -37,6 +42,7 @@
         "test": "android_webview_unittests"
       },
       {
+        "override_isolate_target": "base_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -49,6 +55,10 @@
         "test": "base_unittests"
       },
       {
+        "override_compile_targets": [
+          "blimp_test_apk"
+        ],
+        "override_isolate_target": "blimp_test_apk",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -59,9 +69,10 @@
           ],
           "hard_timeout": 960
         },
-        "test": "blimp_test"
+        "test": "blimp_test_apk"
       },
       {
+        "override_isolate_target": "blimp_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -74,6 +85,7 @@
         "test": "blimp_unittests"
       },
       {
+        "override_isolate_target": "breakpad_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -86,6 +98,7 @@
         "test": "breakpad_unittests"
       },
       {
+        "override_isolate_target": "cc_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -98,6 +111,10 @@
         "test": "cc_unittests"
       },
       {
+        "override_compile_targets": [
+          "chrome_public_test_apk"
+        ],
+        "override_isolate_target": "chrome_public_test_apk",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -108,9 +125,13 @@
           ],
           "hard_timeout": 1200
         },
-        "test": "chrome_public_test"
+        "test": "chrome_public_test_apk"
       },
       {
+        "override_compile_targets": [
+          "chrome_sync_shell_test_apk"
+        ],
+        "override_isolate_target": "chrome_sync_shell_test_apk",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -121,9 +142,10 @@
           ],
           "hard_timeout": 960
         },
-        "test": "chrome_sync_shell_test"
+        "test": "chrome_sync_shell_test_apk"
       },
       {
+        "override_isolate_target": "components_browsertests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -136,6 +158,7 @@
         "test": "components_browsertests"
       },
       {
+        "override_isolate_target": "components_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -148,6 +171,7 @@
         "test": "components_unittests"
       },
       {
+        "override_isolate_target": "content_browsertests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -161,6 +185,10 @@
         "test": "content_browsertests"
       },
       {
+        "override_compile_targets": [
+          "content_shell_test_apk"
+        ],
+        "override_isolate_target": "content_shell_test_apk",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -171,9 +199,10 @@
           ],
           "hard_timeout": 960
         },
-        "test": "content_shell_test"
+        "test": "content_shell_test_apk"
       },
       {
+        "override_isolate_target": "content_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -186,6 +215,7 @@
         "test": "content_unittests"
       },
       {
+        "override_isolate_target": "device_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -198,6 +228,7 @@
         "test": "device_unittests"
       },
       {
+        "override_isolate_target": "events_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -210,6 +241,7 @@
         "test": "events_unittests"
       },
       {
+        "override_isolate_target": "gl_tests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -222,6 +254,7 @@
         "test": "gl_tests"
       },
       {
+        "override_isolate_target": "gpu_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -234,6 +267,7 @@
         "test": "gpu_unittests"
       },
       {
+        "override_isolate_target": "ipc_tests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -246,6 +280,7 @@
         "test": "ipc_tests"
       },
       {
+        "override_isolate_target": "media_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -258,6 +293,7 @@
         "test": "media_unittests"
       },
       {
+        "override_isolate_target": "net_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -270,6 +306,7 @@
         "test": "net_unittests"
       },
       {
+        "override_isolate_target": "sandbox_linux_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -282,6 +319,7 @@
         "test": "sandbox_linux_unittests"
       },
       {
+        "override_isolate_target": "sql_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -294,6 +332,7 @@
         "test": "sql_unittests"
       },
       {
+        "override_isolate_target": "sync_unit_tests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -306,6 +345,7 @@
         "test": "sync_unit_tests"
       },
       {
+        "override_isolate_target": "ui_android_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -318,6 +358,7 @@
         "test": "ui_android_unittests"
       },
       {
+        "override_isolate_target": "ui_base_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -330,6 +371,7 @@
         "test": "ui_base_unittests"
       },
       {
+        "override_isolate_target": "ui_touch_selection_unittests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
@@ -342,6 +384,7 @@
         "test": "ui_touch_selection_unittests"
       },
       {
+        "override_isolate_target": "unit_tests",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index a89e2de..25c73992 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -590,6 +590,9 @@
         "test": "interactive_ui_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
@@ -635,9 +638,15 @@
         "test": "mojo_public_bindings_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -949,6 +958,9 @@
         "test": "interactive_ui_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
@@ -994,9 +1006,15 @@
         "test": "mojo_public_bindings_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1178,9 +1196,15 @@
         "test": "midi_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_bindings_unittests"
       },
       {
@@ -1190,6 +1214,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1314,9 +1341,15 @@
         "test": "midi_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_bindings_unittests"
       },
       {
@@ -1326,6 +1359,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1479,9 +1515,15 @@
         "test": "midi_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_bindings_unittests"
       },
       {
@@ -1491,6 +1533,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1734,6 +1779,9 @@
         "test": "midi_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
@@ -1749,6 +1797,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -2436,6 +2487,9 @@
         "test": "midi_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
@@ -2451,6 +2505,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -2734,6 +2791,9 @@
         "test": "midi_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
@@ -2743,9 +2803,15 @@
         "test": "mojo_public_bindings_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -7011,6 +7077,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -7542,9 +7611,15 @@
         "test": "mojo_public_bindings_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -8507,6 +8582,9 @@
         "test": "interactive_ui_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
@@ -8552,9 +8630,15 @@
         "test": "mojo_public_bindings_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 6bc6ac8..b7d65bd6 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -56,6 +56,9 @@
         "test": "mojo_common_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_application_unittests"
       },
       {
@@ -71,12 +74,21 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_runner_host_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_surfaces_lib_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -772,6 +784,9 @@
         "test": "interactive_ui_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
@@ -793,6 +808,9 @@
         "test": "leveldb_service_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mash_unittests"
       },
       {
@@ -817,15 +835,30 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "mojo_apptests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_js_integration_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_js_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_public_application_unittests"
       },
       {
@@ -841,21 +874,39 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_runner_host_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_shell_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_surfaces_lib_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_view_manager_lib_unittests"
       },
       {
+        "test": "mus_gpu_unittests"
+      },
+      {
         "swarming": {
           "can_use_on_swarming_builders": true
         },
@@ -1015,10 +1066,6 @@
       {
         "name": "nacl_integration",
         "script": "nacl_integration.py"
-      },
-      {
-        "name": "mojo_apptests",
-        "script": "mojo_apptests.py"
       }
     ]
   },
@@ -1213,6 +1260,9 @@
         "test": "interactive_ui_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
@@ -1255,6 +1305,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "mojo_apptests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_common_unittests"
       },
       {
@@ -1270,9 +1326,15 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
+        "test": "mus_gpu_unittests"
+      },
+      {
         "swarming": {
           "can_use_on_swarming_builders": true
         },
@@ -1414,10 +1476,6 @@
       {
         "name": "nacl_integration",
         "script": "nacl_integration.py"
-      },
-      {
-        "name": "mojo_apptests",
-        "script": "mojo_apptests.py"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index fa4afa6..2dbd81a 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -276,6 +276,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -598,6 +601,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -920,6 +926,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1243,6 +1252,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json
index 91bd827..2dfbd4a 100644
--- a/testing/buildbot/chromium.memory.fyi.json
+++ b/testing/buildbot/chromium.memory.fyi.json
@@ -496,6 +496,9 @@
         "test": "interactive_ui_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
@@ -547,6 +550,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -792,6 +798,9 @@
         "test": "interactive_ui_tests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
@@ -843,6 +852,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1069,6 +1081,9 @@
         "test": "gpu_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "ipc_mojo_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index d974baa..32783f41 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -265,6 +265,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -421,448 +424,14 @@
       }
     ]
   },
-  "Win x64 GN": {
+  "Win x64 Builder": {
     "additional_compile_targets": [
       "gn_all"
-    ],
-    "gtest_tests": [
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "accessibility_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "app_list_presenter_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "app_list_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "app_shell_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "ash_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "aura_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "base_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "battor_agent_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "shards": 10
-        },
-        "test": "browser_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "cacheinvalidation_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "cast_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "cc_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "chrome_app_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "chrome_elf_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "chromedriver_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "components_browsertests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "components_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "compositor_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "content_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "courgette_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "crypto_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "device_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "display_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "events_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "extensions_browsertests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "extensions_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "gcm_unit_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "gfx_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "gn_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "google_apis_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "gpu_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "installer_util_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "shards": 2
-        },
-        "test": "interactive_ui_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "ipc_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "jingle_unittests"
-      },
-      {
-        "test": "keyboard_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "media_blink_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "media_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "message_center_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "midi_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_common_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_bindings_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_system_unittests"
-      },
-      {
-        "test": "mojo_system_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "nacl_loader_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "net_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "ppapi_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "printing_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "remoting_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "sbox_integration_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "sbox_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "sbox_validation_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "setup_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "skia_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "sql_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "sync_integration_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "sync_unit_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "ui_base_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "ui_touch_selection_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "unit_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "url_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "views_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "wm_unittests"
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "isolate_name": "telemetry_gpu_unittests",
-        "name": "telemetry_gpu_unittests",
-        "override_compile_targets": [
-          "telemetry_gpu_unittests_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        }
-      },
-      {
-        "isolate_name": "telemetry_perf_unittests",
-        "name": "telemetry_perf_unittests",
-        "override_compile_targets": [
-          "telemetry_perf_unittests_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        }
-      },
-      {
-        "isolate_name": "telemetry_unittests",
-        "name": "telemetry_unittests",
-        "override_compile_targets": [
-          "telemetry_unittests_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        }
-      }
-    ],
-    "scripts": [
-      {
-        "name": "nacl_integration",
-        "script": "nacl_integration.py"
-      }
     ]
   },
-  "Win x64 GN (dbg)": {
+  "Win x64 Builder (dbg)": {
     "additional_compile_targets": [
       "gn_all"
-    ],
-    "gtest_tests": [
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "events_unittests"
-      }
     ]
   },
   "Win10 Tests x64": {
@@ -1124,6 +693,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1561,6 +1133,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -1933,6 +1508,9 @@
         "test": "mojo_public_system_unittests"
       },
       {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mojo_system_unittests"
       },
       {
@@ -2188,9 +1766,18 @@
         "test": "mojo_view_manager_lib_unittests"
       },
       {
+        "args": [
+          "--override-use-gl-with-osmesa-for-tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "mash_unittests"
       },
       {
+        "test": "mus_gpu_unittests"
+      },
+      {
         "test": "mus_ws_unittests"
       },
       {
diff --git a/testing/buildbot/filters/site-per-process.content_browsertests.filter b/testing/buildbot/filters/site-per-process.content_browsertests.filter
index 94c2321..2f701bb 100644
--- a/testing/buildbot/filters/site-per-process.content_browsertests.filter
+++ b/testing/buildbot/filters/site-per-process.content_browsertests.filter
@@ -1,4 +1,3 @@
 # crbug.com/417518: Get tests working with --site-per-process
 -NavigationControllerBrowserTest.ReloadOriginalRequest
 -*.RestoreSubframeFileAccessForHistoryNavigation
--FrameTreeBrowserTest.NavigateGrandchildToBlob
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 1bd6518..c6d0c9e 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -66,7 +66,7 @@
     "type": "raw",
     "args": [],
   },
-  "android_webview_test": {
+  "android_webview_test_apk": {
     "label": "//android_webview/test:android_webview_test_apk",
     "type": "console_test_launcher",
   },
@@ -132,7 +132,7 @@
     "label": "//tools/battor_agent:battor_agent_unittests",
     "type": "console_test_launcher",
   },
-  "blimp_test": {
+  "blimp_test_apk": {
     "label": "//blimp/client:blimp_test_apk",
     "type": "console_test_launcher",
   },
@@ -191,11 +191,11 @@
     "label": "//chrome_elf:chrome_elf_unittests",
     "type": "raw",
   },
-  "chrome_public_test": {
+  "chrome_public_test_apk": {
     "label": "//chrome/android:chrome_public_test_apk",
     "type": "console_test_launcher",
   },
-  "chrome_sync_shell_test": {
+  "chrome_sync_shell_test_apk": {
     "label": "//chrome/android:chrome_sync_shell_test_apk",
     "type": "console_test_launcher",
   },
@@ -230,7 +230,7 @@
     "executable": "content_browsertests",
     "args": ["--site-per-process", "--test-launcher-filter-file=../../testing/buildbot/filters/site-per-process.content_browsertests.filter"],
   },
-  "content_shell_test": {
+  "content_shell_test_apk": {
     "label": "//content/shell/android:content_shell_test_apk",
     "type": "console_test_launcher",
   },
@@ -332,7 +332,7 @@
   },
   "ipc_mojo_unittests": {
     "label": "//ipc/mojo:ipc_mojo_unittests",
-    "type": "unknown",
+    "type": "console_test_launcher",
   },
   "ipc_tests": {
     "label": "//ipc:ipc_tests",
@@ -372,6 +372,14 @@
     "label": "//media/midi:midi_unittests",
     "type": "windowed_test_launcher",
   },
+  "mojo_apptests": {
+    "label": ":mojo_apptests",
+    "type": "script",
+    "script": "//mojo/tools/apptest_runner.py",
+    "args": [
+      '.',
+    ],
+  },
   "mojo_common_unittests": {
     "label": "//mojo/common:mojo_common_unittests",
     "type": "console_test_launcher",
@@ -385,8 +393,8 @@
     "type": "console_test_launcher",
   },
   "mojo_public_application_unittests": {
-    "label": "//mojo/edk/test:mojo_public_applicaiton_unittests",
-    "type": "unknown",
+    "label": "//services/shell/public/cpp/tests:mojo_public_application_unittests",
+    "type": "windowed_test_launcher",
   },
   "mojo_public_bindings_unittests": {
     "label": "//mojo/edk/test:mojo_public_bindings_unittests",
@@ -397,24 +405,24 @@
     "type": "console_test_launcher",
   },
   "mojo_runner_host_unittests": {
-    "label": "//mojo/runner/host:unittests",
-    "type": "unknown",
+    "label": "//services/shell/runner/host:mojo_runner_host_unittests",
+    "type": "console_test_launcher",
   },
   "mojo_shell_unittests": {
-    "label": "//services/shell:mojo_shell_unittests",
-    "type": "unknown",
+    "label": "//services/shell/tests:mojo_shell_unittests",
+    "type": "console_test_launcher",
   },
   "mojo_surfaces_lib_unittests": {
     "label": "//mojo/converters/surfaces/tests:mojo_surfaces_lib_unittests",
-    "type": "unknown",
+    "type": "windowed_test_launcher",
   },
   "mojo_system_unittests": {
     "label": "//mojo/edk/system:mojo_system_unittests",
-    "type": "unknown",
+    "type": "console_test_launcher",
   },
   "mojo_view_manager_lib_unittests": {
-    "label": "//components/view_manager/public/cpp/tests:mojo_view_manager_lib_unittests",
-    "type": "unknown",
+    "label": "//components/mus/public/cpp/tests:mojo_view_manager_lib_unittests",
+    "type": "windowed_test_launcher",
   },
   "message_center_unittests": {
     "label": "//ui/message_center:message_center_unittests",
@@ -422,7 +430,11 @@
   },
   "mash_unittests": {
     "label": "//mash:mash_unittests",
-    "type": "unknown",
+    "type": "windowed_test_launcher",
+  },
+  "mus_gpu_unittests": {
+    "label": "//components/mus/gpu:mus_gpu_unittests",
+    "type": "console_test_launcher",
   },
   "mus_ws_unittests": {
     "label": "//components/mus/ws:mus_ws_unittests",
diff --git a/testing/test.gni b/testing/test.gni
index 0a6b986..650940e 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -338,5 +338,14 @@
         ":${invoker.target_name}",
       ]
     }
+
+    if (defined(invoker.output_name) && target_name != invoker.output_name) {
+      group("${invoker.output_name}_run") {
+        testonly = true
+        deps = [
+          ":${invoker.target_name}",
+        ]
+      }
+    }
   }
 }
diff --git a/third_party/WebKit/API_OWNERS b/third_party/WebKit/API_OWNERS
index 7a380c8..d64cb73 100644
--- a/third_party/WebKit/API_OWNERS
+++ b/third_party/WebKit/API_OWNERS
@@ -7,5 +7,4 @@
 jochen@chromium.org
 tkent@chromium.org
 chrishtr@chromium.org
-philipj@opera.com
 rbyers@chromium.org
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
index d80335b..0c5ec38 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -33,17 +33,11 @@
   inspector/elements/edit/edit-dom-actions.html
 
 # Regressions: Unexpected crashes (53)
-  dom/xhtml/level2/html/HTMLIFrameElement11.xhtml [ Crash Timeout ]
   editing/execCommand/apply-style-command-crash.html [ Crash ]
   editing/pasteboard/file-drag-to-editable.html [ Crash Failure ]
   editing/style/apply-style-crash.html [ Crash ]
-  fast/css/acid2-pixel.html [ Crash Timeout ]
-  fast/css/acid2.html [ Crash Timeout ]
-  fast/dom/HTMLObjectElement/children-changed.html [ Crash Timeout ]
-  fast/dom/HTMLScriptElement/script-element-moved-to-detached-document-crash.html [ Crash Timeout ]
-  fast/dom/Range/acid3-surround-contents.html [ Crash Timeout ]
-  fast/dom/Window/window-resize-and-move-sub-frame.html [ Crash Timeout ]
-  fast/dom/exception-no-frame-timeout-crash.html [ Crash Timeout ]
+  fast/css/acid2-pixel.html [ Crash Timeout Failure ]
+  fast/css/acid2.html [ Crash Timeout Failure ]
   fast/dom/location-new-window-no-crash.html [ Crash ]
   http/tests/appcache/main-resource-hash.html [ Crash Timeout ]
   http/tests/appcache/main-resource-redirect.html [ Crash Timeout ]
@@ -53,22 +47,10 @@
   http/tests/history/cross-origin-redirect-on-back.html [ Crash ]
   http/tests/history/post-replace-state-reload.html [ Crash Failure ]
   http/tests/navigation/location-reload-after-post.php [ Crash Failure ]
-  virtual/pointerevent/fast/events/before-unload-return-bad-value.html [ Crash Failure ]
   virtual/pointerevent/fast/events/before-unload-return-value-from-listener.html [ Crash Failure ]
-  virtual/pointerevent/fast/events/before-unload-returnValue.html [ Crash Failure ]
   virtual/pointerevent/fast/events/drop-handler-should-not-stop-navigate.html [ Crash Failure ]
-  virtual/pointerevent/fast/events/focusingUnloadedFrame.html [ Crash Timeout ]
-  virtual/pointerevent/fast/events/onload-webkit-before-webcore.html [ Crash Timeout ]
-  virtual/pointerevent/fast/events/onloadFrameCrash.html [ Crash Timeout ]
-  virtual/pointerevent/fast/events/only-valid-drop-targets-receive-file-drop.html [ Crash Failure ]
-  virtual/trustedeventsdefaultaction/fast/events/before-unload-return-bad-value.html [ Crash Failure ]
   virtual/trustedeventsdefaultaction/fast/events/before-unload-return-value-from-listener.html [ Crash Failure ]
-  virtual/trustedeventsdefaultaction/fast/events/before-unload-returnValue.html [ Crash Failure ]
   virtual/trustedeventsdefaultaction/fast/events/drop-handler-should-not-stop-navigate.html [ Crash Failure ]
-  virtual/trustedeventsdefaultaction/fast/events/focusingUnloadedFrame.html [ Crash Timeout ]
-  virtual/trustedeventsdefaultaction/fast/events/onload-webkit-before-webcore.html [ Crash Timeout ]
-  virtual/trustedeventsdefaultaction/fast/events/onloadFrameCrash.html [ Crash Timeout ]
-  virtual/trustedeventsdefaultaction/fast/events/only-valid-drop-targets-receive-file-drop.html [ Crash Failure ]
 
 # Regressions: Unexpected missing results (1)
   http/tests/security/upgrade-insecure-requests/https-header-top-level.html [ Missing ]
@@ -76,7 +58,6 @@
 # Regressions: Unexpected text-only failures (69)
   fast/dom/frame-loading-via-document-write.html [ Failure ]
   http/tests/appcache/remove-cache.html [ Failure Timeout ]
-  http/tests/history/push-state-in-grandchild-after-reload.html [ Failure ]
   http/tests/inspector/console-resource-errors.html [ Failure ]
   http/tests/inspector/extensions-ignore-cache.html [ Failure ]
   http/tests/inspector/network/network-document-initiator.html [ Failure ]
@@ -97,7 +78,6 @@
   http/tests/navigation/post-goback1.html [ Crash Failure ]
   http/tests/navigation/redirect-on-reload-updates-history-item.html [ Failure ]
   http/tests/navigation/same-origin-fragment-navigation-is-sync.html [ Failure ]
-  http/tests/navigation/success200-frames-loadsame.html [ Failure ]
   http/tests/security/XFrameOptions/x-frame-options-allowall.html [ Failure ]
   http/tests/security/XFrameOptions/x-frame-options-deny-meta-tag-in-body.html [ Failure ]
   http/tests/security/XFrameOptions/x-frame-options-deny-meta-tag-parent-same-origin-allow.html [ Failure ]
@@ -123,7 +103,6 @@
   http/tests/security/xssAuditor/script-tag-post-control-char.html [ Failure ]
   http/tests/security/xssAuditor/script-tag-post-null-char.html [ Failure ]
   http/tests/security/xssAuditor/script-tag-post.html [ Failure ]
-  http/tests/security/xssAuditor/script-tag-with-callbacks.html [ Failure ]
   http/tests/security/xssAuditor/xss-filter-bypass-long-string.html [ Failure ]
   http/tests/security/xssAuditor/xss-protection-parsing-01.html [ Failure ]
   http/tests/serviceworker/appcache-ordering-main.html [ Failure ]
@@ -143,7 +122,6 @@
   http/tests/misc/window-open-then-write.html [ Timeout ]
   http/tests/navigation/forward-to-fragment-fires-onload.html [ Timeout ]
   http/tests/navigation/history-back-across-form-submission-to-fragment.html [ Timeout ]
-  http/tests/navigation/redirect-on-back-updates-history-item.html [ Timeout ]
   http/tests/navigation/response204.html [ Timeout ]
   http/tests/navigation/scrollstate-after-http-equiv-refresh-fragment-identifier-2.html [ Timeout ]
   http/tests/navigation/scrollstate-after-http-equiv-refresh-fragment-identifier.html [ Timeout ]
@@ -158,7 +136,6 @@
 
 # Regressions: Unexpected text-only failures (25)
   fast/events/drag-file-crash.html [ Failure ]
-  fast/events/frame-tab-focus.html [ Failure ]
   fast/forms/submit-to-url-fragment.html [ Failure ]
   fast/history/history-length-append-subframe-with-hash.html [ Failure ]
   fast/history/same-document-iframes-changing-fragment.html [ Failure ]
@@ -187,52 +164,24 @@
   svg/custom/anchor-on-use.svg [ Failure ]
 
 # Regressions: Unexpected crashes (55)
-  fast/events/before-unload-return-bad-value.html [ Crash Failure ]
   fast/events/before-unload-return-value-from-listener.html [ Crash Failure ]
-  fast/events/before-unload-returnValue.html [ Crash Failure ]
   fast/events/drop-handler-should-not-stop-navigate.html [ Crash Failure ]
-  fast/events/focusingUnloadedFrame.html [ Crash Timeout ]
-  fast/events/onload-webkit-before-webcore.html [ Crash Timeout ]
-  fast/events/onloadFrameCrash.html [ Crash Timeout ]
-  fast/events/only-valid-drop-targets-receive-file-drop.html [ Crash Failure ]
-  fast/frames/empty-frame-document.html [ Crash Timeout ]
   fast/frames/iframe-plugin-load-remove-document-crash.html [ Crash ]
-  fast/innerHTML/innerHTML-iframe.html [ Crash Timeout ]
-  fast/loader/iframe-crash-on-missing-image.xhtml [ Crash Timeout ]
   fast/loader/recursive-before-unload-crash.html [ Crash Failure ]
   fast/loader/reload-zero-byte-plugin.html [ Crash ]
   fast/loader/stateobjects/pushstate-with-fragment-urls-and-hashchange.html [ Crash Timeout ]
-  fast/overflow/overflow-height-float-not-removed-crash.html [ Crash Timeout ]
-  fast/overflow/overflow-height-float-not-removed-crash2.html [ Crash Timeout ]
-  fast/overflow/overflow-height-float-not-removed-crash3.html [ Crash Timeout ]
-  fast/parser/empty-text-resource.html [ Crash Timeout ]
-  fast/table/crash-splitColumn-2.html [ Crash Timeout ]
-  fast/table/giantCellspacing.html [ Crash Timeout ]
+  fast/overflow/overflow-height-float-not-removed-crash.html [ Crash Timeout Failure ]
+  fast/overflow/overflow-height-float-not-removed-crash3.html [ Crash Timeout Failure ]
+  fast/table/giantCellspacing.html [ Crash Timeout Failure ]
   fast/xmlhttprequest/null-document-xmlhttprequest-open.html [ Crash Timeout ]
-  http/tests/loading/bad-server-subframe.html [ Crash Timeout ]
+  http/tests/loading/bad-server-subframe.html [ Crash Timeout Failure ]
   http/tests/loading/pdf-commit-load-callbacks.html [ Crash ]
   http/tests/loading/redirect-methods.html [ Crash Failure ]
   imported/web-platform-tests/html/browsers/browsing-the-web/history-traversal/popstate_event.html [ Crash Failure Timeout ]
-  imported/web-platform-tests/html/browsers/windows/browsing-context-names/browsing-context-default-name.html [ Crash Timeout ]
-  imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/004.html [ Crash Timeout ]
-  imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/005.html [ Crash Timeout ]
-  imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/006.html [ Crash Timeout ]
-  imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/007.html [ Crash Timeout ]
-  imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/008.html [ Crash Timeout ]
-  imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010.html [ Crash Timeout ]
-  imported/web-platform-tests/html/editing/focus/document-level-focus-apis/document-level-apis.html [ Crash Timeout ]
-  imported/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-document.html [ Crash Timeout ]
-  imported/web-platform-tests/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html [ Crash Timeout ]
-  imported/web-platform-tests/html/semantics/embedded-content/the-object-element/object-attributes.html [ Crash Timeout ]
-  imported/web-platform-tests/html/semantics/selectors/pseudo-classes/focus.html [ Crash Timeout ]
-  inspector-protocol/page/javascriptDialogEvents.html [ Crash Timeout ]
-  inspector/elements/styles-4/styles-source-lines-inline.html [ Crash Timeout ]
-  tables/mozilla/bugs/bug137388-1.html [ Crash Timeout ]
-  tables/mozilla/bugs/bug137388-2.html [ Crash Timeout ]
+  imported/web-platform-tests/html/semantics/embedded-content/the-object-element/object-attributes.html [ Crash Timeout Failure ]
 
 # Regressions: Unexpected timeouts (21)
   fast/forms/xss-auditor-doesnt-crash-on-post-submit.html [ Timeout ]
-  fast/history/history-replace-updates-current-item.html [ Timeout ]
   http/tests/loading/bad-scheme-subframe.html [ Timeout ]
   http/tests/loading/text-content-type-with-binary-extension.html [ Timeout Failure ]
   http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_cross_origin_redirect.html [ Timeout ]
@@ -265,15 +214,12 @@
 # Regressions: Unexpected timeouts (5)
   http/tests/serviceworker/chromium/register-link-header.html [ Timeout ]
   inspector-protocol/runtime/runtime-execution-contexts-events.html [ Timeout ]
-  virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash.html [ Timeout ]
+  virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash.html [ Timeout Failure ]
   virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash2.html [ Timeout ]
-  virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash3.html [ Timeout ]
+  virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash3.html [ Timeout Failure ]
 
 # Update on 16-3-17
 
-# Regressions: Unexpected text-only failures (1)
-  css3/fonts/font-style-matching-8.html [ Failure ]
-
 # Regressions: Unexpected timeouts (1)
   imported/web-platform-tests/html/browsers/browsing-the-web/history-traversal/popstate_event.html [ Timeout ]
 
@@ -294,7 +240,6 @@
 # Update on 16-4-14
 
 # Regressions: Unexpected text-only failures (2)
-  http/tests/security/mixedContent/insecure-prefetch-in-main-frame.html [ Failure ]
   imported/web-platform-tests/web-animations/animation-timeline/document-timeline.html [ Failure ]
 
 # Update on 16-4-26
@@ -302,10 +247,19 @@
 # Regressions: Unexpected text-only failures (1)
   http/tests/loading/doc-write-sync-third-party-script-reload.html [ Failure ]
 
-# Regressions: Unexpected crashes ()
+# Regressions: Unexpected crashes (6)
   fast/events/before-unload-forbidden-navigation.html [ Crash ]
   fast/forms/state-restore-skip-stateless.html [ Crash ]
   fast/loader/document-destruction-within-unload.html [ Crash ]
   http/tests/history/back-during-beforeunload.html [ Crash ]
   http/tests/misc/timer-vs-loading.html [ Crash ]
   virtual/trustedeventsdefaultaction/fast/events/before-unload-forbidden-navigation.html [ Crash ]
+
+# Update on 16-4-29
+
+# Regressions: Unexpected text-only failures (2)
+  fast/layout/scroll-anchoring/history-restore-anchors.html [ Failure ]
+  imported/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html [ Failure ]
+
+# Regressions: Unexpected crashes (1)
+  virtual/pointerevent/fast/events/before-unload-forbidden-navigation.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
index 8e9ad9906..2f30dd6 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -21,18 +21,6 @@
 # Uninvestigated timeouts (possibly variants of https://crbug.com/584984)
 http/tests/history/cross-origin-redirect-on-back.html [ Timeout Crash ]
 
-# https://crbug.com/582201 - missing console message about blocked XSS.
-http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-getAttribute-value.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-htmldom.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-setAttribute.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-setAttributeNode.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-setAttributeNS.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-getAttribute-value.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-htmldom.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-setAttribute.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-setAttributeNode.html [ Failure ]
-http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-setAttributeNS.html [ Failure ]
-
 # https://crbug.com/582245 - no exception, b/c BindingSecurity::shouldAllowAccessTo exits early when |!target|.
 http/tests/security/xss-DENIED-getSVGDocument-iframe.html [ Failure ]
 http/tests/security/xss-DENIED-getSVGDocument-object.html [ Failure ]
@@ -100,7 +88,6 @@
 http/tests/security/xssAuditor/script-tag-post-control-char.html [ Failure ]
 http/tests/security/xssAuditor/script-tag-post.html [ Failure ]
 http/tests/security/xssAuditor/script-tag-post-null-char.html [ Failure ]
-http/tests/security/xssAuditor/script-tag-with-callbacks.html [ Failure ]
 http/tests/security/xssAuditor/xss-filter-bypass-long-string.html [ Failure ]
 
 # Uninvestigated failures under http/tests (but outside of http/tests/security):
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 32893c0..96113c4 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -344,8 +344,6 @@
 crbug.com/552433 [ Linux Mac Win10 Win7 ] svg/hixie/perf/006.xml [ Failure Pass ]
 crbug.com/605024 [ Mac ] svg/transforms/animated-path-inside-transformed-html.xhtml [ Failure ]
 
-crbug.com/530044 transforms/2d/transform-borderbox.html [ NeedsManualRebaseline ]
-
 # This directly has manual tests that don't have to run with run-webkit-tests
 crbug.com/359838 http/tests/ManualTests/ [ Skip ]
 
@@ -1266,15 +1264,6 @@
 crbug.com/587779 [ Linux Mac10.10 Mac10.11 Retina ] fast/dynamic/window-resize-scrollbars-test.html [ Timeout Failure Pass ]
 crbug.com/588103 fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer.html [ Pass Failure ]
 
-crbug.com/475128 fast/images/imagemap-focus-ring-in-positioned-container.html [ NeedsManualRebaseline ]
-crbug.com/475128 fast/images/imagemap-focus-ring-with-paint-root-offset.html [ NeedsManualRebaseline ]
-crbug.com/475128 fast/images/imagemap-focus-ring-with-scale-transform.html [ NeedsManualRebaseline ]
-crbug.com/475128 fast/images/imagemap-focus-ring-zoom.html [ NeedsManualRebaseline ]
-crbug.com/475128 virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container.html [ NeedsManualRebaseline ]
-crbug.com/475128 virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset.html [ NeedsManualRebaseline ]
-crbug.com/475128 virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform.html [ NeedsManualRebaseline ]
-crbug.com/475128 virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom.html [ NeedsManualRebaseline ]
-
 crbug.com/594672 fast/events/iframe-object-onload.html [ Failure Pass ]
 crbug.com/594672 fast/events/scale-and-scroll-iframe-body.html [ Failure Pass ]
 crbug.com/594672 fast/events/updateLayoutForHitTest.html [ Failure Pass ]
@@ -1542,6 +1531,9 @@
 
 crbug.com/600248 imported/web-platform-tests/web-animations/animation-effect-timing/endDelay.html [ Failure ]
 crbug.com/600248 imported/web-platform-tests/web-animations/animation/constructor.html [ Failure Timeout ]
+crbug.com/600248 imported/web-platform-tests/web-animations/animation/finished.html [ Pass Failure ]
+crbug.com/600248 imported/web-platform-tests/web-animations/animation/oncancel.html [ Pass Failure ]
+crbug.com/600248 imported/web-platform-tests/web-animations/animation/onfinish.html [ Pass Failure ]
 
 crbug.com/604642 [ Mac ]  fast/text/midword-break-after-breakable-char.html [ Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations
index b79c53a..0cc0dcde 100644
--- a/third_party/WebKit/LayoutTests/W3CImportExpectations
+++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -211,7 +211,7 @@
 # imported/web-platform-tests/custom-elements [ Pass ]
 imported/web-platform-tests/custom-elements/registering-custom-elements/unresolved-element-pseudoclass [ Skip ]
 imported/web-platform-tests/docs [ Skip ]
-## Owners: philipj@opera.com
+## Owners: tkent@chromium.org
 imported/web-platform-tests/dom [ Pass ]
 imported/web-platform-tests/domparsing [ Skip ]
 imported/web-platform-tests/domxpath [ Skip ]
@@ -767,16 +767,3 @@
 
 # crbug.com/574461: update-w3c-deps imports .py file with x-bit cleared
 imported/web-platform-tests/dom/nodes/Document-createElement-namespace-tests/generate.py [ Skip ]
-
-# crbug.com/606875: New web animation web platform tests are failing.
-imported/web-platform-tests/web-animations/animation-effect-timing/easing.html [ Skip ]
-imported/web-platform-tests/web-animations/animation-effect-timing/fill.html [ Skip ]
-imported/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html [ Skip ]
-imported/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html [ Skip ]
-imported/web-platform-tests/web-animations/animation/finished.html [ Skip ]
-imported/web-platform-tests/web-animations/animation/oncancel.html [ Skip ]
-imported/web-platform-tests/web-animations/animation/onfinish.html [ Skip ]
-
-# crbug.com/606900; Dispatching errors across iframes.
-imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html [ Skip ]
-imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/remove-line-above-float-above-line-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/remove-line-above-float-above-line-crash-expected.txt
new file mode 100644
index 0000000..e773dd2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/remove-line-above-float-above-line-crash-expected.txt
@@ -0,0 +1,3 @@
+PASS if no crash.
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/remove-line-above-float-above-line-crash.html b/third_party/WebKit/LayoutTests/fast/block/float/remove-line-above-float-above-line-crash.html
new file mode 100644
index 0000000..967751e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/remove-line-above-float-above-line-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<p>PASS if no crash.</p>
+<div style="width:5em;">
+    <span id="killme" style="border-top:solid;">LINE_WIDER_THAN_CONTAINER</span>
+    <div style="float:left; width:100%; height:1px;"></div>
+    PASS
+</div>
+<script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+    document.body.offsetTop;
+    document.getElementById("killme").style.display = "none";
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/variables/multiple-writes-to-inline-style.html b/third_party/WebKit/LayoutTests/fast/css/variables/multiple-writes-to-inline-style.html
index a2d1938b..499ec1c8 100644
--- a/third_party/WebKit/LayoutTests/fast/css/variables/multiple-writes-to-inline-style.html
+++ b/third_party/WebKit/LayoutTests/fast/css/variables/multiple-writes-to-inline-style.html
@@ -15,4 +15,17 @@
   assert_equals(testElem.getAttribute('style'), '--foo:second;');
 }, "subsequent writes to inline style overwrite older values.")
 
+test(function() {
+  var value = '10 20% 30px bla("x")';
+  testElem.style.setProperty('--foo', value);
+  assert_equals(testElem.style.getPropertyValue('--foo'), value);
+  testElem.offsetTop;
+  testElem.style.setProperty('--foo', value);
+  assert_equals(testElem.style.getPropertyValue('--foo'), value);
+  testElem.offsetTop;
+  value = '-5 1.5px [ ]'
+  testElem.style.setProperty('--foo', value);
+  assert_equals(testElem.style.getPropertyValue('--foo'), value);
+}, "various token types can be compared")
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-assign-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-assign-crash-expected.txt
deleted file mode 100644
index de9e1e0f..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-assign-crash-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This test checks for a NULL document crash that can happen when calling location.assign. If the test passes, you'll see a PASS message below.
-
-PASS: You didn't crash.
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-assign-crash.html b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-assign-crash.html
deleted file mode 100644
index e5ee2994..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-assign-crash.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<p>This test checks for a NULL document crash that can happen when calling
-location.assign. If the test passes, you'll see a PASS message below.</p>
-<hr>
-<pre id="pre"></pre>
-<iframe style="visibility:hidden" src="does-not-exist.bogus"></iframe> <!-- forces asynchronous load -->
-<script>
-<!--
-function log(s)
-{
-    document.getElementById("pre").appendChild(document.createTextNode(s));
-}
-
-function test()
-{
-    frames[0].location.assign("javascript:'<script>parent.pass()</script>'");
-}
-
-function pass()
-{
-    log("PASS: You didn't crash.");
-
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-function main()
-{
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }    
-    
-    // setTimeout forces execution in the context of the frame
-    frames[0].setTimeout(test, 0);
-}
-
-main();
--->
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-href-put-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-href-put-crash-expected.txt
deleted file mode 100644
index 8c8ea1c6..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-href-put-crash-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This test checks for a NULL document crash that can happen when setting location.href. If the test passes, you'll see a PASS message below.
-
-PASS: You didn't crash.
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-href-put-crash.html b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-href-put-crash.html
deleted file mode 100644
index 58581683..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-href-put-crash.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<p>This test checks for a NULL document crash that can happen when setting
-location.href. If the test passes, you'll see a PASS message below.</p>
-<hr>
-<pre id="pre"></pre>
-<iframe style="visibility:hidden" src="does-not-exist.bogus"></iframe> <!-- forces asynchronous load -->
-<script>
-<!--
-function log(s)
-{
-    document.getElementById("pre").appendChild(document.createTextNode(s));
-}
-
-function test()
-{
-    frames[0].location.href = "javascript:'<script>parent.pass()</script>'";
-}
-
-function pass()
-{
-    log("PASS: You didn't crash.");
-
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-function main()
-{
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }    
-    
-    // setTimeout forces execution in the context of the frame
-    frames[0].setTimeout(test, 0);
-}
-
-main();
--->
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-put-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-put-crash-expected.txt
deleted file mode 100644
index 35371c7..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-put-crash-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This test checks for a NULL document crash that can happen when setting location. If the test passes, you'll see a PASS message below.
-
-PASS: You didn't crash.
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-put-crash.html b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-put-crash.html
deleted file mode 100644
index c2fb3c4f..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-put-crash.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<p>This test checks for a NULL document crash that can happen when setting
-location. If the test passes, you'll see a PASS message below.</p>
-<hr>
-<pre id="pre"></pre>
-<iframe style="visibility:hidden" src="does-not-exist.bogus"></iframe> <!-- forces asynchronous load -->
-<script>
-<!--
-function log(s)
-{
-    document.getElementById("pre").appendChild(document.createTextNode(s));
-}
-
-function test()
-{
-    frames[0].location = "javascript:'<script>parent.pass()</script>'";
-}
-
-function pass()
-{
-    log("PASS: You didn't crash.");
-
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-function main()
-{
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }    
-    
-    // setTimeout forces execution in the context of the frame
-    frames[0].setTimeout(test, 0);
-}
-
-main();
--->
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-replace-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-replace-crash-expected.txt
deleted file mode 100644
index 606f183..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-replace-crash-expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This test checks for a NULL document crash that can happen when calling location.replace. If the test passes, you'll see a PASS message below.
-
-PASS: You didn't crash.
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-replace-crash.html b/third_party/WebKit/LayoutTests/fast/dom/null-document-location-replace-crash.html
deleted file mode 100644
index 175bb364..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-location-replace-crash.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<p>This test checks for a NULL document crash that can happen when calling
-location.replace. If the test passes, you'll see a PASS message below.</p>
-<hr>
-<pre id="pre"></pre>
-<iframe style="display:none" src="does-not-exist.bogus"></iframe> <!-- forces asynchronous load -->
-<script>
-<!--
-function log(s)
-{
-    document.getElementById("pre").appendChild(document.createTextNode(s));
-}
-
-function test()
-{
-    frames[0].location.replace("javascript:'<script>parent.pass()</script>'");
-}
-
-function pass()
-{
-    log("PASS: You didn't crash.");
-
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-function main()
-{
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }    
-    
-    // setTimeout forces execution in the context of the frame
-    frames[0].setTimeout(test, 0);
-}
-
-main();
--->
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-window-open-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/null-document-window-open-crash-expected.txt
deleted file mode 100644
index 434815b..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-window-open-crash-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This test checks for a NULL document crash that can happen when calling window.open. If the test passes, you'll see a PASS message below.
-
-PASS: You didn't crash.
-
diff --git a/third_party/WebKit/LayoutTests/fast/dom/null-document-window-open-crash.html b/third_party/WebKit/LayoutTests/fast/dom/null-document-window-open-crash.html
deleted file mode 100644
index 542ee12..0000000
--- a/third_party/WebKit/LayoutTests/fast/dom/null-document-window-open-crash.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<p>This test checks for a NULL document crash that can happen when calling
-window.open. If the test passes, you'll see a PASS message below.</p>
-<hr>
-<pre id="pre"></pre>
-<iframe name="iframe" style="visibility:hidden" src="does-not-exist.bogus"></iframe> <!-- forces asynchronous load -->
-<script>
-<!--
-function log(s)
-{
-    document.getElementById("pre").appendChild(document.createTextNode(s));
-}
-
-function test()
-{
-    window.open("javascript:'<script>parent.pass()</script>'", "iframe");
-}
-
-function pass()
-{
-    log("PASS: You didn't crash.");
-
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-function main()
-{
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }    
-    
-    // setTimeout forces execution in the context of the frame
-    frames[0].setTimeout(test, 0);
-}
-
-main();
--->
-</script>
diff --git a/third_party/WebKit/LayoutTests/fast/js/webidl-sequence-conversion.html b/third_party/WebKit/LayoutTests/fast/js/webidl-sequence-conversion.html
new file mode 100644
index 0000000..7d69910c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/js/webidl-sequence-conversion.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<body>
+<div></div>
+<script>
+
+  test(function () {
+
+    var div = document.querySelector("div");
+    var clickEvent = null;
+
+    div.addEventListener("click", function (ev) { clickEvent = ev; });
+    div.click();
+
+    assert_not_equals(clickEvent, null, "click event captured");
+
+    var getter_called = false;
+    var setter_called = false;
+
+    Object.defineProperty(Array.prototype, "0", {
+      get: function () { getter_called = true; },
+      set: function () { setter_called = true; }
+    });
+
+    var path = clickEvent.path;
+
+    delete Array.prototype["0"];
+
+    assert_false(getter_called, "Array.prototype[0] getter called");
+    assert_false(setter_called, "Array.prototype[0] setter called");
+
+    assert_equals(clickEvent.path.length, 5, "click event path length");
+
+  }, "conversion should use [[DefineOwnProperty]]");
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/fragment-scrolling-anchors.html b/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/fragment-scrolling-anchors.html
new file mode 100644
index 0000000..ef3a75f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/fragment-scrolling-anchors.html
@@ -0,0 +1,52 @@
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<style>
+  body {
+    margin: 0px;
+    height: 2000px;
+    width: 2000px;
+  }
+
+  #first {
+    height: 1000px;
+    background-color: #FFA5D2;
+  }
+
+  #anchor {
+    position: absolute;
+    background-color: #84BE6A;
+    height: 600px;
+    width: 100%;
+  }
+
+  #fragment {
+    position: relative;
+    background-color: orange;
+    height: 200px;
+    width: 200px;
+    margin: 10px;
+  }
+</style>
+
+<div id="first"></div>
+<div id="changer"></div>
+<div id="anchor">
+    <div id="fragment" name="fragment"></div>
+</div>
+
+<script>
+  test(function(t) {
+    // Note that this test passes even without scroll anchoring because of
+    // fragment anchoring.
+    window.location.hash = 'fragment';
+    // Height of first + fragment margin-top.
+    assert_equals(window.scrollY, 1010);
+
+    // Change height of content above fragment.
+    var ch = document.getElementById('changer');
+    ch.style.height = 100;
+
+    // Height of first + height changer + fragment margin-top.
+    assert_equals(window.scrollY, 1110);
+  }, 'Verify scroll anchoring interaction with fragment scrolls');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/history-restore-anchors.html b/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/history-restore-anchors.html
new file mode 100644
index 0000000..64907365
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/history-restore-anchors.html
@@ -0,0 +1,53 @@
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<style>
+  body {
+    margin: 0px;
+    height: 2000px;
+    width: 2000px;
+  }
+
+  #first {
+    height: 1000px;
+    background-color: #FFA5D2;
+  }
+
+  #anchor {
+    position: absolute;
+    background-color: #84BE6A;
+    height: 600px;
+    width: 100%;
+  }
+</style>
+
+<div id="first"></div>
+<div id="changer"></div>
+<div id="anchor"></div>
+
+<script>
+  // Navigation steps:
+  // 1- page gets loaded and anchor element gets scrolled into view.
+  // 2- loaded page refreshed.
+  async_test(function(t) {
+    // TODO(ymalik): Remove reference to internals when scroll anchoring is
+    // enabled by default.
+    assert_false(!window.internals, 'This test requires internals');
+    internals.runtimeFlags.scrollAnchoringEnabled = true;
+
+    if (window.name == 'second/load') {
+      assert_equals(window.scrollY, 1000);
+      // Change height of content above anchor.
+      var ch = document.getElementById('changer');
+      ch.style.height = 100;
+      // Height of first + height changer.
+      assert_equals(window.scrollY, 1100)
+      t.done();
+    } else {
+      var anchor = document.getElementById('anchor');
+      anchor.scrollIntoView();
+      assert_equals(window.scrollY, 1000);
+      window.name = "second/load";
+      window.location.reload();
+    }
+  }, 'Verify scroll anchoring interaction with history restoration');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/null-document-xmlhttprequest-open-expected.txt b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/null-document-xmlhttprequest-open-expected.txt
deleted file mode 100644
index 03842e9..0000000
--- a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/null-document-xmlhttprequest-open-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This test checks for a NULL document crash that can happen when calling XMLHttpRequest.open. If the test passes, you'll see a PASS message below.
-
-PASS: You didn't crash.
-
diff --git a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/null-document-xmlhttprequest-open.html b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/null-document-xmlhttprequest-open.html
deleted file mode 100644
index 5381258..0000000
--- a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/null-document-xmlhttprequest-open.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<p>This test checks for a NULL document crash that can happen when calling
-XMLHttpRequest.open. If the test passes, you'll see a PASS message below.</p>
-<hr>
-<pre id="pre"></pre>
-<iframe name="iframe" style="visibility:hidden" src="does-not-exist.bogus"></iframe> <!-- forces asynchronous load -->
-<script>
-<!--
-function log(s)
-{
-    document.getElementById("pre").appendChild(document.createTextNode(s));
-}
-
-function test()
-{
-    var request = new XMLHttpRequest();
-    request.onreadystatechange = function(event) { if (event.target.readyState == 1) parent.pass(); };
-    request.open("GET", window.location);
-}
-
-function pass()
-{
-    log("PASS: You didn't crash.");
-
-    if (window.testRunner)
-        testRunner.notifyDone();
-}
-
-function main()
-{
-    if (window.testRunner) {
-        testRunner.dumpAsText();
-        testRunner.waitUntilDone();
-    }    
-    
-    // setTimeout forces execution in the context of the frame
-    frames[0].setTimeout(test, 0);
-}
-
-main();
--->
-</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt b/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt
index 3d8ec31..dec83d0 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/bad-server-subframe-expected.txt
@@ -3,6 +3,11 @@
 frame "f1" - didStartProvisionalLoadForFrame
 main frame - didFinishDocumentLoadForFrame
 frame "f1" - didFailProvisionalLoadWithError
+frame "f1" - didStartProvisionalLoadForFrame
+frame "f1" - didCommitLoadForFrame
+frame "f1" - didFinishDocumentLoadForFrame
+frame "f1" - didHandleOnloadEventsForFrame
+frame "f1" - didFinishLoadForFrame
 main frame - didHandleOnloadEventsForFrame
 main frame - didFinishLoadForFrame
 This is a test of load callbacks. It is only useful inside the regression test tool.
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-avtracks.html b/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-avtracks.html
index 131e1d05..b2db51e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-avtracks.html
+++ b/third_party/WebKit/LayoutTests/http/tests/media/media-source/mediasource-avtracks.html
@@ -4,50 +4,122 @@
         <script src="/w3c/resources/testharness.js"></script>
         <script src="/w3c/resources/testharnessreport.js"></script>
         <script src="mediasource-util.js"></script>
-
-        <link rel='stylesheet' href='/w3c/resources/testharness.css'>
     </head>
     <body>
-        <div id="log"></div>
         <script>
-          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
-          {
-              var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
-              test.expectEvent(sourceBuffer, 'updateend', 'initSegment append ended.');
-              test.expectEvent(sourceBuffer.audioTracks, 'addtrack', 'sourceBuffer.videoTracks addtrack event');
-              test.expectEvent(sourceBuffer.videoTracks, 'addtrack', 'sourceBuffer.videoTracks addtrack event');
-              test.expectEvent(mediaElement.audioTracks, 'addtrack', 'mediaElement.videoTracks addtrack event');
-              test.expectEvent(mediaElement.videoTracks, 'addtrack', 'mediaElement.videoTracks addtrack event');
-              sourceBuffer.appendBuffer(initSegment);
-              test.waitForExpectedEvents(function()
-              {
+            function loadMediaAndVerifyAddedTracks(test, mediaElement, segmentInfo, sourceBuffer, mediaData, successCallback)
+            {
+                var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
+                test.expectEvent(sourceBuffer.audioTracks, "addtrack", "sourceBuffer.audioTracks addtrack event");
+                test.expectEvent(sourceBuffer.videoTracks, "addtrack", "sourceBuffer.videoTracks addtrack event");
+                test.expectEvent(mediaElement.audioTracks, "addtrack", "mediaElement.audioTracks addtrack event");
+                test.expectEvent(mediaElement.videoTracks, "addtrack", "mediaElement.videoTracks addtrack event");
+                test.expectEvent(mediaElement, "loadedmetadata", "loadedmetadata done.");
+                test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
+                sourceBuffer.appendBuffer(initSegment);
+                test.waitForExpectedEvents(function()
+                {
+                    assert_equals(sourceBuffer.videoTracks.length, 1, "videoTracks.length");
+                    assert_equals(sourceBuffer.videoTracks[0].kind, "main", "videoTrack.kind");
+                    assert_equals(sourceBuffer.videoTracks[0].label, "", "videoTrack.label");
+                    assert_equals(sourceBuffer.videoTracks[0].language, "eng", "videoTrack.language");
+                    assert_equals(sourceBuffer.videoTracks[0].sourceBuffer, sourceBuffer, "videoTrack.sourceBuffer");
+                    // The first video track is selected by default.
+                    assert_true(sourceBuffer.videoTracks[0].selected, "sourceBuffer.videoTracks[0].selected");
+
+                    assert_equals(sourceBuffer.audioTracks.length, 1, "audioTracks.length");
+                    assert_equals(sourceBuffer.audioTracks[0].kind, "main", "audioTrack.kind");
+                    assert_equals(sourceBuffer.audioTracks[0].label, "", "audioTrack.label");
+                    assert_equals(sourceBuffer.audioTracks[0].language, "eng", "audioTrack.language");
+                    assert_equals(sourceBuffer.audioTracks[0].sourceBuffer, sourceBuffer, "audioTrack.sourceBuffer");
+                    // The first audio track is enabled by default.
+                    assert_true(sourceBuffer.audioTracks[0].enabled, "sourceBuffer.audioTracks[0].enabled");
+
+                    assert_not_equals(sourceBuffer.audioTracks[0].id, sourceBuffer.videoTracks[0].id, "track ids must be unique");
+
+                    assert_equals(mediaElement.videoTracks.length, 1, "videoTracks.length");
+                    assert_equals(mediaElement.videoTracks[0], sourceBuffer.videoTracks[0], "mediaElement.videoTrack == sourceBuffer.videoTrack");
+
+                    assert_equals(mediaElement.audioTracks.length, 1, "audioTracks.length");
+                    assert_equals(mediaElement.audioTracks[0], sourceBuffer.audioTracks[0], "mediaElement.audioTrack == sourceBuffer.audioTrack");
+
+                    successCallback();
+                });
+            }
+
+            mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+            {
+                loadMediaAndVerifyAddedTracks(test, mediaElement, segmentInfo, sourceBuffer, mediaData, test.step_func_done());
+            }, "Check that media tracks and their properties are populated properly");
+
+            function verifyTrackRemoval(test, mediaElement, mediaSource, sourceBuffer, trackRemovalAction, successCallback) {
+                assert_equals(sourceBuffer.audioTracks.length, 1, "audioTracks.length");
+                assert_true(sourceBuffer.audioTracks[0].enabled, "sourceBuffer.audioTracks[0].enabled");
                 assert_equals(sourceBuffer.videoTracks.length, 1, "videoTracks.length");
-                assert_equals(sourceBuffer.videoTracks[0].id, "1", "videoTrack.id");
-                assert_equals(sourceBuffer.videoTracks[0].kind, "main", "videoTrack.kind");
-                assert_equals(sourceBuffer.videoTracks[0].label, "", "videoTrack.label");
-                assert_equals(sourceBuffer.videoTracks[0].language, "eng", "videoTrack.language");
-                assert_equals(sourceBuffer.videoTracks[0].sourceBuffer, sourceBuffer, "videoTrack.sourceBuffer");
-                // The first video track is selected by default.
                 assert_true(sourceBuffer.videoTracks[0].selected, "sourceBuffer.videoTracks[0].selected");
 
-                assert_equals(sourceBuffer.audioTracks.length, 1, "audioTracks.length");
-                assert_equals(sourceBuffer.audioTracks[0].id, "2", "audioTrack.id");
-                assert_equals(sourceBuffer.audioTracks[0].kind, "main", "audioTrack.kind");
-                assert_equals(sourceBuffer.audioTracks[0].label, "", "audioTrack.label");
-                assert_equals(sourceBuffer.audioTracks[0].language, "eng", "audioTrack.language");
-                assert_equals(sourceBuffer.audioTracks[0].sourceBuffer, sourceBuffer, "audioTrack.sourceBuffer");
-                // The first audio track is enabled by default.
-                assert_true(sourceBuffer.audioTracks[0].enabled, "sourceBuffer.audioTracks[0].enabled");
+                var audioTrack = sourceBuffer.audioTracks[0];
+                var videoTrack = sourceBuffer.videoTracks[0];
 
-                assert_equals(mediaElement.videoTracks.length, 1, "videoTracks.length");
-                assert_equals(mediaElement.videoTracks[0], sourceBuffer.videoTracks[0], "mediaElement.videoTrack == sourceBuffer.videoTrack");
+                // Verify removetrack events.
+                test.expectEvent(sourceBuffer.audioTracks, "removetrack", "sourceBuffer.audioTracks removetrack event");
+                test.expectEvent(sourceBuffer.videoTracks, "removetrack", "sourceBuffer.videoTracks removetrack event");
+                test.expectEvent(mediaElement.audioTracks, "removetrack", "mediaElement.audioTracks removetrack event");
+                test.expectEvent(mediaElement.videoTracks, "removetrack", "mediaElement.videoTracks removetrack event");
 
-                assert_equals(mediaElement.audioTracks.length, 1, "audioTracks.length");
-                assert_equals(mediaElement.audioTracks[0], sourceBuffer.audioTracks[0], "mediaElement.audioTrack == sourceBuffer.audioTrack");
+                // Removing enabled audio track and selected video track should fire "change" events on mediaElement track lists.
+                test.expectEvent(mediaElement.audioTracks, "change", "mediaElement.audioTracks changed.");
+                test.expectEvent(mediaElement.videoTracks, "change", "mediaElement.videoTracks changed.");
 
-                test.done();
-              });
-          }, "MediaSource media track properties");
+                trackRemovalAction();
+
+                test.waitForExpectedEvents(function()
+                {
+                    assert_equals(mediaSource.sourceBuffers.length, 0, "mediaSource.sourceBuffers.length");
+                    assert_equals(mediaElement.videoTracks.length, 0, "videoTracks.length");
+                    assert_equals(mediaElement.audioTracks.length, 0, "audioTracks.length");
+                    assert_equals(sourceBuffer.videoTracks.length, 0, "videoTracks.length");
+                    assert_equals(sourceBuffer.audioTracks.length, 0, "audioTracks.length");
+                    // Since audio and video tracks have been removed, their .sourceBuffer property should be null now.
+                    assert_equals(audioTrack.sourceBuffer, null, "audioTrack.sourceBuffer");
+                    assert_equals(videoTrack.sourceBuffer, null, "videoTrack.sourceBuffer");
+                    successCallback();
+                });
+            }
+
+            mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+            {
+                loadMediaAndVerifyAddedTracks(test, mediaElement, segmentInfo, sourceBuffer, mediaData, test.step_func(function ()
+                {
+                    verifyTrackRemoval(test, mediaElement, mediaSource, sourceBuffer, test.step_func(function ()
+                    {
+                        mediaSource.removeSourceBuffer(sourceBuffer);
+                    }), test.step_func_done());
+                }));
+            }, "Media tracks must be removed when the SourceBuffer is removed from the MediaSource");
+
+            mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+            {
+                loadMediaAndVerifyAddedTracks(test, mediaElement, segmentInfo, sourceBuffer, mediaData, test.step_func(function ()
+                {
+                    verifyTrackRemoval(test, mediaElement, mediaSource, sourceBuffer, test.step_func(function ()
+                    {
+                        mediaElement.src = "";
+                    }), test.step_func_done());
+                }));
+            }, "Media tracks must be removed when the HTMLMediaElement.src is changed");
+
+            mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
+            {
+                loadMediaAndVerifyAddedTracks(test, mediaElement, segmentInfo, sourceBuffer, mediaData, test.step_func(function ()
+                {
+                    verifyTrackRemoval(test, mediaElement, mediaSource, sourceBuffer, test.step_func(function ()
+                    {
+                        mediaElement.load();
+                    }), test.step_func_done());
+                }));
+            }, "Media tracks must be removed when the HTMLMediaElement.load() is called");
+
         </script>
     </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/preload/external_css_import_preload.html b/third_party/WebKit/LayoutTests/http/tests/preload/external_css_import_preload.html
new file mode 100644
index 0000000..fac4d73
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/preload/external_css_import_preload.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/slow-script.pl?delay=500"></script>
+<script>
+var t = async_test("We should scan external css for @imports and preload them");
+var boundedStart = window.performance.now();
+</script>
+<link rel="stylesheet" type="text/css" href="../resources/css_with_import.css"></link>
+<script>
+window.addEventListener("load", t.step_func(function() {
+  var entries = performance.getEntriesByType("resource");
+  entries.forEach(function(entry) {
+    if (entry.name.indexOf("dummy.css") != -1) {
+      assert_less_than(entry.startTime, boundedStart);
+      t.done();
+    }
+  });
+}));
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/resources/css_with_import.css b/third_party/WebKit/LayoutTests/http/tests/resources/css_with_import.css
new file mode 100644
index 0000000..77a8f6b4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/resources/css_with_import.css
@@ -0,0 +1 @@
+@import url("dummy.css");
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/javascriptURL/resources/javascriptURL-execution-context.js b/third_party/WebKit/LayoutTests/http/tests/security/javascriptURL/resources/javascriptURL-execution-context.js
index e1ce12cd..a166f4eb 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/javascriptURL/resources/javascriptURL-execution-context.js
+++ b/third_party/WebKit/LayoutTests/http/tests/security/javascriptURL/resources/javascriptURL-execution-context.js
@@ -4,30 +4,42 @@
     testRunner.waitUntilDone();
 }
 
-window.addEventListener('message', function() {
-    runTest();
-    if (window.testRunner)
-        testRunner.notifyDone();
-});
-
-setFrameLocation = function(url) {
+window.onload = function() {
     var frame = document.getElementById('aFrame');
-    var jsErrorMessage = 'Failed to set the \'location\' property on \'HTMLFrameElement\': Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame.';
-    try {
-        setter(frame, url);
-    } catch (e) {
-        console.log("Caught exception while setting frame's location to '" + url + "'. '" + e + "'.");
-        if (e.message == jsErrorMessage)
-            console.log("PASS: Exception was '" + e.message + "'.");
-        else
-            console.log("FAIL: Exception should have been '" + jsErrorMessage + "', was '" + e.message + "'.");
-    }
+    frame.onload = runNextTest;
+    runNextTest();
 }
 
-function runTest() {
-    setFrameLocation('javascript:"FAIL: this should not have been loaded."');
-    setFrameLocation(' javascript:"FAIL: this should not have been loaded."');
-    setFrameLocation('java\0script:"FAIL: this should not have been loaded."');
-    setFrameLocation('javascript\t:"FAIL: this should not have been loaded."');
-    setFrameLocation('javascript\1:"FAIL: this should not have been loaded."');
+var testURIs = [
+    'javascript:alert("FAIL: this should not have been loaded.")',
+    ' javascript:alert("FAIL: this should not have been loaded.")',
+    'javascript\t:alert("FAIL: this should not have been loaded.")',
+    'java\0script:alert("FAIL: this should not have been loaded.")',
+    'javascript\1:alert("FAIL: this should not have been loaded.")',
+    'http://localhost:8000/security/resources/cross-frame-iframe.html'
+];
+
+var currentTestIndex = 0;
+function runNextTest() {
+    testRunner.logToStderr("runNextTest: " + currentTestIndex);
+    if (currentTestIndex == testURIs.length) {
+        if (window.testRunner)
+            testRunner.notifyDone();
+        return;
+    }
+
+    var frame = document.getElementById('aFrame');
+    var uri = testURIs[currentTestIndex];
+    try {
+        setter(frame, uri);
+    } catch (e) {
+        console.log("FAIL: Unexpected exception: '" + e.message + "'.");
+    }
+
+    currentTestIndex++;
+    if (currentTestIndex <= 3) {
+        // First 3 uris will be silently ignored / will not get onload event.
+        // Therefore - we need to kick off the next test ourselves.
+        runNextTest();
+    }
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks-expected.txt
index f9cc440..474498e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks-expected.txt
@@ -1,11 +1,2 @@
-frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
-main frame - didFinishDocumentLoadForFrame
-frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
 CONSOLE ERROR: line 4: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.
-didDetectXSS
-frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
-frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
-frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
-main frame - didHandleOnloadEventsForFrame
-main frame - didFinishLoadForFrame
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks.html b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks.html
index d3740886..20add7d5 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-with-callbacks.html
@@ -4,7 +4,6 @@
 <script>
 if (window.testRunner) {
     testRunner.dumpAsText();
-    testRunner.dumpFrameLoadCallbacks();
     testRunner.setXSSAuditorEnabled(true);
 }
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-frame-resource.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-frame-resource.html
index 2395278..693c9f3 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-frame-resource.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-frame-resource.html
@@ -71,16 +71,14 @@
             scope + '?mode=no-cors&url=' +
             encodeURIComponent(host_info['HTTP_REMOTE_ORIGIN'] + path);
           document.body.appendChild(frame);
-          // We can't catch the network error on iframe. So we use the timer.
           return new Promise(function(resolve) {
-              setTimeout(function() { resolve(frame); }, 1000);
-            });
+              frame.onload = function () { resolve(frame) };
+          });
         })
       .then(function(frame) {
-          assert_equals(
-            frame.contentDocument.body.textContent,
-            '',
-            'Opaque type response could not be loaded in the iframe.');
+          assert_throws('SecurityError', _ => {
+              assert_equals(frame.contentDocument.body.textContent, '');
+          }, 'Opaque response renders error page in the iframe.');
           frame.remove();
           return service_worker_unregister_and_done(t, scope);
         })
@@ -145,23 +143,22 @@
           return wait_for_state(t, reg.installing, 'activated');
         })
       .then(function() {
-          var win = window.open(
+          return window.open(
             scope + '?mode=no-cors&url=' +
             encodeURIComponent(host_info['HTTP_REMOTE_ORIGIN'] + path));
-          // We can't catch the network error on window. So we use the timer.
-          return new Promise(function(resolve) {
-              setTimeout(function() { resolve(win); }, 1000);
-            });
         })
       .then(function(win) {
-          assert_equals(
-            win.document.body.textContent,
-            '',
-            'Opaque type response could not be loaded in the new window.');
-          win.close();
-          return service_worker_unregister_and_done(t, scope);
+          // Give the window time to load: we won't get any error or load events
+          // so we'll set a timeout instead:
+          setTimeout(_ => {
+              assert_throws('SecurityError', _ => {
+                  assert_equals(win.document.body.textContent, '');
+              }, 'Opaque response renders error page in the new window.');
+              win.close();
+              return service_worker_unregister_and_done(t, scope);
+          }, 1000);
         })
-      .catch(unreached_rejection(t));
+//      .catch(unreached_rejection(t));
   }, 'Opaque type response could not be loaded in the new window.');
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-redirect.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-redirect.html
index 1d8e7e7f..de3affe2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-redirect.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-redirect.html
@@ -33,10 +33,14 @@
       frame.onload = function() {
         if (timeout_enabled)
           clearTimeout(timer);
-        if (frame.contentDocument.body.textContent == 'Hello world\n')
-          resolve();
-        else
-          reject(new Error('content mismatch'));
+        try {
+            if (frame.contentDocument.body.textContent == 'Hello world\n')
+              resolve();
+            else
+              reject(new Error('content mismatch'));
+        } catch (e) {
+            reject(new Error(e));
+        }
         frame.remove();
       };
       document.body.appendChild(frame);
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/README.md b/third_party/WebKit/LayoutTests/imported/web-platform-tests/README.md
index d207a8b..32d6503c 100644
--- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/README.md
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/README.md
@@ -27,12 +27,13 @@
 following entries are required:
 
 ```
-127.0.0.1	web-platform.test
-127.0.0.1	www.web-platform.test
-127.0.0.1	www1.web-platform.test
-127.0.0.1	www2.web-platform.test
-127.0.0.1	xn--n8j6ds53lwwkrqhv28a.web-platform.test
-127.0.0.1	xn--lve-6lad.web-platform.test
+127.0.0.1   web-platform.test
+127.0.0.1   www.web-platform.test
+127.0.0.1   www1.web-platform.test
+127.0.0.1   www2.web-platform.test
+127.0.0.1   xn--n8j6ds53lwwkrqhv28a.web-platform.test
+127.0.0.1   xn--lve-6lad.web-platform.test
+0.0.0.0     nonexistent-origin.web-platform.test
 ```
 
 Because web-platform-tests uses git submodules, you must ensure that
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/encoding/textdecoder-fatal-single-byte-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/encoding/textdecoder-fatal-single-byte-expected.txt
new file mode 100644
index 0000000..0ee27da
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/encoding/textdecoder-fatal-single-byte-expected.txt
@@ -0,0 +1,7322 @@
+This is a testharness.js-based test.
+PASS Not throw: IBM866 has a pointer 0 
+PASS Not throw: IBM866 has a pointer 1 
+PASS Not throw: IBM866 has a pointer 2 
+PASS Not throw: IBM866 has a pointer 3 
+PASS Not throw: IBM866 has a pointer 4 
+PASS Not throw: IBM866 has a pointer 5 
+PASS Not throw: IBM866 has a pointer 6 
+PASS Not throw: IBM866 has a pointer 7 
+PASS Not throw: IBM866 has a pointer 8 
+PASS Not throw: IBM866 has a pointer 9 
+PASS Not throw: IBM866 has a pointer 10 
+PASS Not throw: IBM866 has a pointer 11 
+PASS Not throw: IBM866 has a pointer 12 
+PASS Not throw: IBM866 has a pointer 13 
+PASS Not throw: IBM866 has a pointer 14 
+PASS Not throw: IBM866 has a pointer 15 
+PASS Not throw: IBM866 has a pointer 16 
+PASS Not throw: IBM866 has a pointer 17 
+PASS Not throw: IBM866 has a pointer 18 
+PASS Not throw: IBM866 has a pointer 19 
+PASS Not throw: IBM866 has a pointer 20 
+PASS Not throw: IBM866 has a pointer 21 
+PASS Not throw: IBM866 has a pointer 22 
+PASS Not throw: IBM866 has a pointer 23 
+PASS Not throw: IBM866 has a pointer 24 
+PASS Not throw: IBM866 has a pointer 25 
+PASS Not throw: IBM866 has a pointer 26 
+PASS Not throw: IBM866 has a pointer 27 
+PASS Not throw: IBM866 has a pointer 28 
+PASS Not throw: IBM866 has a pointer 29 
+PASS Not throw: IBM866 has a pointer 30 
+PASS Not throw: IBM866 has a pointer 31 
+PASS Not throw: IBM866 has a pointer 32 
+PASS Not throw: IBM866 has a pointer 33 
+PASS Not throw: IBM866 has a pointer 34 
+PASS Not throw: IBM866 has a pointer 35 
+PASS Not throw: IBM866 has a pointer 36 
+PASS Not throw: IBM866 has a pointer 37 
+PASS Not throw: IBM866 has a pointer 38 
+PASS Not throw: IBM866 has a pointer 39 
+PASS Not throw: IBM866 has a pointer 40 
+PASS Not throw: IBM866 has a pointer 41 
+PASS Not throw: IBM866 has a pointer 42 
+PASS Not throw: IBM866 has a pointer 43 
+PASS Not throw: IBM866 has a pointer 44 
+PASS Not throw: IBM866 has a pointer 45 
+PASS Not throw: IBM866 has a pointer 46 
+PASS Not throw: IBM866 has a pointer 47 
+PASS Not throw: IBM866 has a pointer 48 
+PASS Not throw: IBM866 has a pointer 49 
+PASS Not throw: IBM866 has a pointer 50 
+PASS Not throw: IBM866 has a pointer 51 
+PASS Not throw: IBM866 has a pointer 52 
+PASS Not throw: IBM866 has a pointer 53 
+PASS Not throw: IBM866 has a pointer 54 
+PASS Not throw: IBM866 has a pointer 55 
+PASS Not throw: IBM866 has a pointer 56 
+PASS Not throw: IBM866 has a pointer 57 
+PASS Not throw: IBM866 has a pointer 58 
+PASS Not throw: IBM866 has a pointer 59 
+PASS Not throw: IBM866 has a pointer 60 
+PASS Not throw: IBM866 has a pointer 61 
+PASS Not throw: IBM866 has a pointer 62 
+PASS Not throw: IBM866 has a pointer 63 
+PASS Not throw: IBM866 has a pointer 64 
+PASS Not throw: IBM866 has a pointer 65 
+PASS Not throw: IBM866 has a pointer 66 
+PASS Not throw: IBM866 has a pointer 67 
+PASS Not throw: IBM866 has a pointer 68 
+PASS Not throw: IBM866 has a pointer 69 
+PASS Not throw: IBM866 has a pointer 70 
+PASS Not throw: IBM866 has a pointer 71 
+PASS Not throw: IBM866 has a pointer 72 
+PASS Not throw: IBM866 has a pointer 73 
+PASS Not throw: IBM866 has a pointer 74 
+PASS Not throw: IBM866 has a pointer 75 
+PASS Not throw: IBM866 has a pointer 76 
+PASS Not throw: IBM866 has a pointer 77 
+PASS Not throw: IBM866 has a pointer 78 
+PASS Not throw: IBM866 has a pointer 79 
+PASS Not throw: IBM866 has a pointer 80 
+PASS Not throw: IBM866 has a pointer 81 
+PASS Not throw: IBM866 has a pointer 82 
+PASS Not throw: IBM866 has a pointer 83 
+PASS Not throw: IBM866 has a pointer 84 
+PASS Not throw: IBM866 has a pointer 85 
+PASS Not throw: IBM866 has a pointer 86 
+PASS Not throw: IBM866 has a pointer 87 
+PASS Not throw: IBM866 has a pointer 88 
+PASS Not throw: IBM866 has a pointer 89 
+PASS Not throw: IBM866 has a pointer 90 
+PASS Not throw: IBM866 has a pointer 91 
+PASS Not throw: IBM866 has a pointer 92 
+PASS Not throw: IBM866 has a pointer 93 
+PASS Not throw: IBM866 has a pointer 94 
+PASS Not throw: IBM866 has a pointer 95 
+PASS Not throw: IBM866 has a pointer 96 
+PASS Not throw: IBM866 has a pointer 97 
+PASS Not throw: IBM866 has a pointer 98 
+PASS Not throw: IBM866 has a pointer 99 
+PASS Not throw: IBM866 has a pointer 100 
+PASS Not throw: IBM866 has a pointer 101 
+PASS Not throw: IBM866 has a pointer 102 
+PASS Not throw: IBM866 has a pointer 103 
+PASS Not throw: IBM866 has a pointer 104 
+PASS Not throw: IBM866 has a pointer 105 
+PASS Not throw: IBM866 has a pointer 106 
+PASS Not throw: IBM866 has a pointer 107 
+PASS Not throw: IBM866 has a pointer 108 
+PASS Not throw: IBM866 has a pointer 109 
+PASS Not throw: IBM866 has a pointer 110 
+PASS Not throw: IBM866 has a pointer 111 
+PASS Not throw: IBM866 has a pointer 112 
+PASS Not throw: IBM866 has a pointer 113 
+PASS Not throw: IBM866 has a pointer 114 
+PASS Not throw: IBM866 has a pointer 115 
+PASS Not throw: IBM866 has a pointer 116 
+PASS Not throw: IBM866 has a pointer 117 
+PASS Not throw: IBM866 has a pointer 118 
+PASS Not throw: IBM866 has a pointer 119 
+PASS Not throw: IBM866 has a pointer 120 
+PASS Not throw: IBM866 has a pointer 121 
+PASS Not throw: IBM866 has a pointer 122 
+PASS Not throw: IBM866 has a pointer 123 
+PASS Not throw: IBM866 has a pointer 124 
+PASS Not throw: IBM866 has a pointer 125 
+PASS Not throw: IBM866 has a pointer 126 
+PASS Not throw: IBM866 has a pointer 127 
+PASS Not throw: IBM866 has a pointer 128 
+PASS Not throw: IBM866 has a pointer 129 
+PASS Not throw: IBM866 has a pointer 130 
+PASS Not throw: IBM866 has a pointer 131 
+PASS Not throw: IBM866 has a pointer 132 
+PASS Not throw: IBM866 has a pointer 133 
+PASS Not throw: IBM866 has a pointer 134 
+PASS Not throw: IBM866 has a pointer 135 
+PASS Not throw: IBM866 has a pointer 136 
+PASS Not throw: IBM866 has a pointer 137 
+PASS Not throw: IBM866 has a pointer 138 
+PASS Not throw: IBM866 has a pointer 139 
+PASS Not throw: IBM866 has a pointer 140 
+PASS Not throw: IBM866 has a pointer 141 
+PASS Not throw: IBM866 has a pointer 142 
+PASS Not throw: IBM866 has a pointer 143 
+PASS Not throw: IBM866 has a pointer 144 
+PASS Not throw: IBM866 has a pointer 145 
+PASS Not throw: IBM866 has a pointer 146 
+PASS Not throw: IBM866 has a pointer 147 
+PASS Not throw: IBM866 has a pointer 148 
+PASS Not throw: IBM866 has a pointer 149 
+PASS Not throw: IBM866 has a pointer 150 
+PASS Not throw: IBM866 has a pointer 151 
+PASS Not throw: IBM866 has a pointer 152 
+PASS Not throw: IBM866 has a pointer 153 
+PASS Not throw: IBM866 has a pointer 154 
+PASS Not throw: IBM866 has a pointer 155 
+PASS Not throw: IBM866 has a pointer 156 
+PASS Not throw: IBM866 has a pointer 157 
+PASS Not throw: IBM866 has a pointer 158 
+PASS Not throw: IBM866 has a pointer 159 
+PASS Not throw: IBM866 has a pointer 160 
+PASS Not throw: IBM866 has a pointer 161 
+PASS Not throw: IBM866 has a pointer 162 
+PASS Not throw: IBM866 has a pointer 163 
+PASS Not throw: IBM866 has a pointer 164 
+PASS Not throw: IBM866 has a pointer 165 
+PASS Not throw: IBM866 has a pointer 166 
+PASS Not throw: IBM866 has a pointer 167 
+PASS Not throw: IBM866 has a pointer 168 
+PASS Not throw: IBM866 has a pointer 169 
+PASS Not throw: IBM866 has a pointer 170 
+PASS Not throw: IBM866 has a pointer 171 
+PASS Not throw: IBM866 has a pointer 172 
+PASS Not throw: IBM866 has a pointer 173 
+PASS Not throw: IBM866 has a pointer 174 
+PASS Not throw: IBM866 has a pointer 175 
+PASS Not throw: IBM866 has a pointer 176 
+PASS Not throw: IBM866 has a pointer 177 
+PASS Not throw: IBM866 has a pointer 178 
+PASS Not throw: IBM866 has a pointer 179 
+PASS Not throw: IBM866 has a pointer 180 
+PASS Not throw: IBM866 has a pointer 181 
+PASS Not throw: IBM866 has a pointer 182 
+PASS Not throw: IBM866 has a pointer 183 
+PASS Not throw: IBM866 has a pointer 184 
+PASS Not throw: IBM866 has a pointer 185 
+PASS Not throw: IBM866 has a pointer 186 
+PASS Not throw: IBM866 has a pointer 187 
+PASS Not throw: IBM866 has a pointer 188 
+PASS Not throw: IBM866 has a pointer 189 
+PASS Not throw: IBM866 has a pointer 190 
+PASS Not throw: IBM866 has a pointer 191 
+PASS Not throw: IBM866 has a pointer 192 
+PASS Not throw: IBM866 has a pointer 193 
+PASS Not throw: IBM866 has a pointer 194 
+PASS Not throw: IBM866 has a pointer 195 
+PASS Not throw: IBM866 has a pointer 196 
+PASS Not throw: IBM866 has a pointer 197 
+PASS Not throw: IBM866 has a pointer 198 
+PASS Not throw: IBM866 has a pointer 199 
+PASS Not throw: IBM866 has a pointer 200 
+PASS Not throw: IBM866 has a pointer 201 
+PASS Not throw: IBM866 has a pointer 202 
+PASS Not throw: IBM866 has a pointer 203 
+PASS Not throw: IBM866 has a pointer 204 
+PASS Not throw: IBM866 has a pointer 205 
+PASS Not throw: IBM866 has a pointer 206 
+PASS Not throw: IBM866 has a pointer 207 
+PASS Not throw: IBM866 has a pointer 208 
+PASS Not throw: IBM866 has a pointer 209 
+PASS Not throw: IBM866 has a pointer 210 
+PASS Not throw: IBM866 has a pointer 211 
+PASS Not throw: IBM866 has a pointer 212 
+PASS Not throw: IBM866 has a pointer 213 
+PASS Not throw: IBM866 has a pointer 214 
+PASS Not throw: IBM866 has a pointer 215 
+PASS Not throw: IBM866 has a pointer 216 
+PASS Not throw: IBM866 has a pointer 217 
+PASS Not throw: IBM866 has a pointer 218 
+PASS Not throw: IBM866 has a pointer 219 
+PASS Not throw: IBM866 has a pointer 220 
+PASS Not throw: IBM866 has a pointer 221 
+PASS Not throw: IBM866 has a pointer 222 
+PASS Not throw: IBM866 has a pointer 223 
+PASS Not throw: IBM866 has a pointer 224 
+PASS Not throw: IBM866 has a pointer 225 
+PASS Not throw: IBM866 has a pointer 226 
+PASS Not throw: IBM866 has a pointer 227 
+PASS Not throw: IBM866 has a pointer 228 
+PASS Not throw: IBM866 has a pointer 229 
+PASS Not throw: IBM866 has a pointer 230 
+PASS Not throw: IBM866 has a pointer 231 
+PASS Not throw: IBM866 has a pointer 232 
+PASS Not throw: IBM866 has a pointer 233 
+PASS Not throw: IBM866 has a pointer 234 
+PASS Not throw: IBM866 has a pointer 235 
+PASS Not throw: IBM866 has a pointer 236 
+PASS Not throw: IBM866 has a pointer 237 
+PASS Not throw: IBM866 has a pointer 238 
+PASS Not throw: IBM866 has a pointer 239 
+PASS Not throw: IBM866 has a pointer 240 
+PASS Not throw: IBM866 has a pointer 241 
+PASS Not throw: IBM866 has a pointer 242 
+PASS Not throw: IBM866 has a pointer 243 
+PASS Not throw: IBM866 has a pointer 244 
+PASS Not throw: IBM866 has a pointer 245 
+PASS Not throw: IBM866 has a pointer 246 
+PASS Not throw: IBM866 has a pointer 247 
+PASS Not throw: IBM866 has a pointer 248 
+PASS Not throw: IBM866 has a pointer 249 
+PASS Not throw: IBM866 has a pointer 250 
+PASS Not throw: IBM866 has a pointer 251 
+PASS Not throw: IBM866 has a pointer 252 
+PASS Not throw: IBM866 has a pointer 253 
+PASS Not throw: IBM866 has a pointer 254 
+PASS Not throw: IBM866 has a pointer 255 
+PASS Not throw: ISO-8859-2 has a pointer 0 
+PASS Not throw: ISO-8859-2 has a pointer 1 
+PASS Not throw: ISO-8859-2 has a pointer 2 
+PASS Not throw: ISO-8859-2 has a pointer 3 
+PASS Not throw: ISO-8859-2 has a pointer 4 
+PASS Not throw: ISO-8859-2 has a pointer 5 
+PASS Not throw: ISO-8859-2 has a pointer 6 
+PASS Not throw: ISO-8859-2 has a pointer 7 
+PASS Not throw: ISO-8859-2 has a pointer 8 
+PASS Not throw: ISO-8859-2 has a pointer 9 
+PASS Not throw: ISO-8859-2 has a pointer 10 
+PASS Not throw: ISO-8859-2 has a pointer 11 
+PASS Not throw: ISO-8859-2 has a pointer 12 
+PASS Not throw: ISO-8859-2 has a pointer 13 
+PASS Not throw: ISO-8859-2 has a pointer 14 
+PASS Not throw: ISO-8859-2 has a pointer 15 
+PASS Not throw: ISO-8859-2 has a pointer 16 
+PASS Not throw: ISO-8859-2 has a pointer 17 
+PASS Not throw: ISO-8859-2 has a pointer 18 
+PASS Not throw: ISO-8859-2 has a pointer 19 
+PASS Not throw: ISO-8859-2 has a pointer 20 
+PASS Not throw: ISO-8859-2 has a pointer 21 
+PASS Not throw: ISO-8859-2 has a pointer 22 
+PASS Not throw: ISO-8859-2 has a pointer 23 
+PASS Not throw: ISO-8859-2 has a pointer 24 
+PASS Not throw: ISO-8859-2 has a pointer 25 
+PASS Not throw: ISO-8859-2 has a pointer 26 
+PASS Not throw: ISO-8859-2 has a pointer 27 
+PASS Not throw: ISO-8859-2 has a pointer 28 
+PASS Not throw: ISO-8859-2 has a pointer 29 
+PASS Not throw: ISO-8859-2 has a pointer 30 
+PASS Not throw: ISO-8859-2 has a pointer 31 
+PASS Not throw: ISO-8859-2 has a pointer 32 
+PASS Not throw: ISO-8859-2 has a pointer 33 
+PASS Not throw: ISO-8859-2 has a pointer 34 
+PASS Not throw: ISO-8859-2 has a pointer 35 
+PASS Not throw: ISO-8859-2 has a pointer 36 
+PASS Not throw: ISO-8859-2 has a pointer 37 
+PASS Not throw: ISO-8859-2 has a pointer 38 
+PASS Not throw: ISO-8859-2 has a pointer 39 
+PASS Not throw: ISO-8859-2 has a pointer 40 
+PASS Not throw: ISO-8859-2 has a pointer 41 
+PASS Not throw: ISO-8859-2 has a pointer 42 
+PASS Not throw: ISO-8859-2 has a pointer 43 
+PASS Not throw: ISO-8859-2 has a pointer 44 
+PASS Not throw: ISO-8859-2 has a pointer 45 
+PASS Not throw: ISO-8859-2 has a pointer 46 
+PASS Not throw: ISO-8859-2 has a pointer 47 
+PASS Not throw: ISO-8859-2 has a pointer 48 
+PASS Not throw: ISO-8859-2 has a pointer 49 
+PASS Not throw: ISO-8859-2 has a pointer 50 
+PASS Not throw: ISO-8859-2 has a pointer 51 
+PASS Not throw: ISO-8859-2 has a pointer 52 
+PASS Not throw: ISO-8859-2 has a pointer 53 
+PASS Not throw: ISO-8859-2 has a pointer 54 
+PASS Not throw: ISO-8859-2 has a pointer 55 
+PASS Not throw: ISO-8859-2 has a pointer 56 
+PASS Not throw: ISO-8859-2 has a pointer 57 
+PASS Not throw: ISO-8859-2 has a pointer 58 
+PASS Not throw: ISO-8859-2 has a pointer 59 
+PASS Not throw: ISO-8859-2 has a pointer 60 
+PASS Not throw: ISO-8859-2 has a pointer 61 
+PASS Not throw: ISO-8859-2 has a pointer 62 
+PASS Not throw: ISO-8859-2 has a pointer 63 
+PASS Not throw: ISO-8859-2 has a pointer 64 
+PASS Not throw: ISO-8859-2 has a pointer 65 
+PASS Not throw: ISO-8859-2 has a pointer 66 
+PASS Not throw: ISO-8859-2 has a pointer 67 
+PASS Not throw: ISO-8859-2 has a pointer 68 
+PASS Not throw: ISO-8859-2 has a pointer 69 
+PASS Not throw: ISO-8859-2 has a pointer 70 
+PASS Not throw: ISO-8859-2 has a pointer 71 
+PASS Not throw: ISO-8859-2 has a pointer 72 
+PASS Not throw: ISO-8859-2 has a pointer 73 
+PASS Not throw: ISO-8859-2 has a pointer 74 
+PASS Not throw: ISO-8859-2 has a pointer 75 
+PASS Not throw: ISO-8859-2 has a pointer 76 
+PASS Not throw: ISO-8859-2 has a pointer 77 
+PASS Not throw: ISO-8859-2 has a pointer 78 
+PASS Not throw: ISO-8859-2 has a pointer 79 
+PASS Not throw: ISO-8859-2 has a pointer 80 
+PASS Not throw: ISO-8859-2 has a pointer 81 
+PASS Not throw: ISO-8859-2 has a pointer 82 
+PASS Not throw: ISO-8859-2 has a pointer 83 
+PASS Not throw: ISO-8859-2 has a pointer 84 
+PASS Not throw: ISO-8859-2 has a pointer 85 
+PASS Not throw: ISO-8859-2 has a pointer 86 
+PASS Not throw: ISO-8859-2 has a pointer 87 
+PASS Not throw: ISO-8859-2 has a pointer 88 
+PASS Not throw: ISO-8859-2 has a pointer 89 
+PASS Not throw: ISO-8859-2 has a pointer 90 
+PASS Not throw: ISO-8859-2 has a pointer 91 
+PASS Not throw: ISO-8859-2 has a pointer 92 
+PASS Not throw: ISO-8859-2 has a pointer 93 
+PASS Not throw: ISO-8859-2 has a pointer 94 
+PASS Not throw: ISO-8859-2 has a pointer 95 
+PASS Not throw: ISO-8859-2 has a pointer 96 
+PASS Not throw: ISO-8859-2 has a pointer 97 
+PASS Not throw: ISO-8859-2 has a pointer 98 
+PASS Not throw: ISO-8859-2 has a pointer 99 
+PASS Not throw: ISO-8859-2 has a pointer 100 
+PASS Not throw: ISO-8859-2 has a pointer 101 
+PASS Not throw: ISO-8859-2 has a pointer 102 
+PASS Not throw: ISO-8859-2 has a pointer 103 
+PASS Not throw: ISO-8859-2 has a pointer 104 
+PASS Not throw: ISO-8859-2 has a pointer 105 
+PASS Not throw: ISO-8859-2 has a pointer 106 
+PASS Not throw: ISO-8859-2 has a pointer 107 
+PASS Not throw: ISO-8859-2 has a pointer 108 
+PASS Not throw: ISO-8859-2 has a pointer 109 
+PASS Not throw: ISO-8859-2 has a pointer 110 
+PASS Not throw: ISO-8859-2 has a pointer 111 
+PASS Not throw: ISO-8859-2 has a pointer 112 
+PASS Not throw: ISO-8859-2 has a pointer 113 
+PASS Not throw: ISO-8859-2 has a pointer 114 
+PASS Not throw: ISO-8859-2 has a pointer 115 
+PASS Not throw: ISO-8859-2 has a pointer 116 
+PASS Not throw: ISO-8859-2 has a pointer 117 
+PASS Not throw: ISO-8859-2 has a pointer 118 
+PASS Not throw: ISO-8859-2 has a pointer 119 
+PASS Not throw: ISO-8859-2 has a pointer 120 
+PASS Not throw: ISO-8859-2 has a pointer 121 
+PASS Not throw: ISO-8859-2 has a pointer 122 
+PASS Not throw: ISO-8859-2 has a pointer 123 
+PASS Not throw: ISO-8859-2 has a pointer 124 
+PASS Not throw: ISO-8859-2 has a pointer 125 
+PASS Not throw: ISO-8859-2 has a pointer 126 
+PASS Not throw: ISO-8859-2 has a pointer 127 
+PASS Not throw: ISO-8859-2 has a pointer 128 
+PASS Not throw: ISO-8859-2 has a pointer 129 
+PASS Not throw: ISO-8859-2 has a pointer 130 
+PASS Not throw: ISO-8859-2 has a pointer 131 
+PASS Not throw: ISO-8859-2 has a pointer 132 
+PASS Not throw: ISO-8859-2 has a pointer 133 
+PASS Not throw: ISO-8859-2 has a pointer 134 
+PASS Not throw: ISO-8859-2 has a pointer 135 
+PASS Not throw: ISO-8859-2 has a pointer 136 
+PASS Not throw: ISO-8859-2 has a pointer 137 
+PASS Not throw: ISO-8859-2 has a pointer 138 
+PASS Not throw: ISO-8859-2 has a pointer 139 
+PASS Not throw: ISO-8859-2 has a pointer 140 
+PASS Not throw: ISO-8859-2 has a pointer 141 
+PASS Not throw: ISO-8859-2 has a pointer 142 
+PASS Not throw: ISO-8859-2 has a pointer 143 
+PASS Not throw: ISO-8859-2 has a pointer 144 
+PASS Not throw: ISO-8859-2 has a pointer 145 
+PASS Not throw: ISO-8859-2 has a pointer 146 
+PASS Not throw: ISO-8859-2 has a pointer 147 
+PASS Not throw: ISO-8859-2 has a pointer 148 
+PASS Not throw: ISO-8859-2 has a pointer 149 
+PASS Not throw: ISO-8859-2 has a pointer 150 
+PASS Not throw: ISO-8859-2 has a pointer 151 
+PASS Not throw: ISO-8859-2 has a pointer 152 
+PASS Not throw: ISO-8859-2 has a pointer 153 
+PASS Not throw: ISO-8859-2 has a pointer 154 
+PASS Not throw: ISO-8859-2 has a pointer 155 
+PASS Not throw: ISO-8859-2 has a pointer 156 
+PASS Not throw: ISO-8859-2 has a pointer 157 
+PASS Not throw: ISO-8859-2 has a pointer 158 
+PASS Not throw: ISO-8859-2 has a pointer 159 
+PASS Not throw: ISO-8859-2 has a pointer 160 
+PASS Not throw: ISO-8859-2 has a pointer 161 
+PASS Not throw: ISO-8859-2 has a pointer 162 
+PASS Not throw: ISO-8859-2 has a pointer 163 
+PASS Not throw: ISO-8859-2 has a pointer 164 
+PASS Not throw: ISO-8859-2 has a pointer 165 
+PASS Not throw: ISO-8859-2 has a pointer 166 
+PASS Not throw: ISO-8859-2 has a pointer 167 
+PASS Not throw: ISO-8859-2 has a pointer 168 
+PASS Not throw: ISO-8859-2 has a pointer 169 
+PASS Not throw: ISO-8859-2 has a pointer 170 
+PASS Not throw: ISO-8859-2 has a pointer 171 
+PASS Not throw: ISO-8859-2 has a pointer 172 
+PASS Not throw: ISO-8859-2 has a pointer 173 
+PASS Not throw: ISO-8859-2 has a pointer 174 
+PASS Not throw: ISO-8859-2 has a pointer 175 
+PASS Not throw: ISO-8859-2 has a pointer 176 
+PASS Not throw: ISO-8859-2 has a pointer 177 
+PASS Not throw: ISO-8859-2 has a pointer 178 
+PASS Not throw: ISO-8859-2 has a pointer 179 
+PASS Not throw: ISO-8859-2 has a pointer 180 
+PASS Not throw: ISO-8859-2 has a pointer 181 
+PASS Not throw: ISO-8859-2 has a pointer 182 
+PASS Not throw: ISO-8859-2 has a pointer 183 
+PASS Not throw: ISO-8859-2 has a pointer 184 
+PASS Not throw: ISO-8859-2 has a pointer 185 
+PASS Not throw: ISO-8859-2 has a pointer 186 
+PASS Not throw: ISO-8859-2 has a pointer 187 
+PASS Not throw: ISO-8859-2 has a pointer 188 
+PASS Not throw: ISO-8859-2 has a pointer 189 
+PASS Not throw: ISO-8859-2 has a pointer 190 
+PASS Not throw: ISO-8859-2 has a pointer 191 
+PASS Not throw: ISO-8859-2 has a pointer 192 
+PASS Not throw: ISO-8859-2 has a pointer 193 
+PASS Not throw: ISO-8859-2 has a pointer 194 
+PASS Not throw: ISO-8859-2 has a pointer 195 
+PASS Not throw: ISO-8859-2 has a pointer 196 
+PASS Not throw: ISO-8859-2 has a pointer 197 
+PASS Not throw: ISO-8859-2 has a pointer 198 
+PASS Not throw: ISO-8859-2 has a pointer 199 
+PASS Not throw: ISO-8859-2 has a pointer 200 
+PASS Not throw: ISO-8859-2 has a pointer 201 
+PASS Not throw: ISO-8859-2 has a pointer 202 
+PASS Not throw: ISO-8859-2 has a pointer 203 
+PASS Not throw: ISO-8859-2 has a pointer 204 
+PASS Not throw: ISO-8859-2 has a pointer 205 
+PASS Not throw: ISO-8859-2 has a pointer 206 
+PASS Not throw: ISO-8859-2 has a pointer 207 
+PASS Not throw: ISO-8859-2 has a pointer 208 
+PASS Not throw: ISO-8859-2 has a pointer 209 
+PASS Not throw: ISO-8859-2 has a pointer 210 
+PASS Not throw: ISO-8859-2 has a pointer 211 
+PASS Not throw: ISO-8859-2 has a pointer 212 
+PASS Not throw: ISO-8859-2 has a pointer 213 
+PASS Not throw: ISO-8859-2 has a pointer 214 
+PASS Not throw: ISO-8859-2 has a pointer 215 
+PASS Not throw: ISO-8859-2 has a pointer 216 
+PASS Not throw: ISO-8859-2 has a pointer 217 
+PASS Not throw: ISO-8859-2 has a pointer 218 
+PASS Not throw: ISO-8859-2 has a pointer 219 
+PASS Not throw: ISO-8859-2 has a pointer 220 
+PASS Not throw: ISO-8859-2 has a pointer 221 
+PASS Not throw: ISO-8859-2 has a pointer 222 
+PASS Not throw: ISO-8859-2 has a pointer 223 
+PASS Not throw: ISO-8859-2 has a pointer 224 
+PASS Not throw: ISO-8859-2 has a pointer 225 
+PASS Not throw: ISO-8859-2 has a pointer 226 
+PASS Not throw: ISO-8859-2 has a pointer 227 
+PASS Not throw: ISO-8859-2 has a pointer 228 
+PASS Not throw: ISO-8859-2 has a pointer 229 
+PASS Not throw: ISO-8859-2 has a pointer 230 
+PASS Not throw: ISO-8859-2 has a pointer 231 
+PASS Not throw: ISO-8859-2 has a pointer 232 
+PASS Not throw: ISO-8859-2 has a pointer 233 
+PASS Not throw: ISO-8859-2 has a pointer 234 
+PASS Not throw: ISO-8859-2 has a pointer 235 
+PASS Not throw: ISO-8859-2 has a pointer 236 
+PASS Not throw: ISO-8859-2 has a pointer 237 
+PASS Not throw: ISO-8859-2 has a pointer 238 
+PASS Not throw: ISO-8859-2 has a pointer 239 
+PASS Not throw: ISO-8859-2 has a pointer 240 
+PASS Not throw: ISO-8859-2 has a pointer 241 
+PASS Not throw: ISO-8859-2 has a pointer 242 
+PASS Not throw: ISO-8859-2 has a pointer 243 
+PASS Not throw: ISO-8859-2 has a pointer 244 
+PASS Not throw: ISO-8859-2 has a pointer 245 
+PASS Not throw: ISO-8859-2 has a pointer 246 
+PASS Not throw: ISO-8859-2 has a pointer 247 
+PASS Not throw: ISO-8859-2 has a pointer 248 
+PASS Not throw: ISO-8859-2 has a pointer 249 
+PASS Not throw: ISO-8859-2 has a pointer 250 
+PASS Not throw: ISO-8859-2 has a pointer 251 
+PASS Not throw: ISO-8859-2 has a pointer 252 
+PASS Not throw: ISO-8859-2 has a pointer 253 
+PASS Not throw: ISO-8859-2 has a pointer 254 
+PASS Not throw: ISO-8859-2 has a pointer 255 
+PASS Not throw: ISO-8859-3 has a pointer 0 
+PASS Not throw: ISO-8859-3 has a pointer 1 
+PASS Not throw: ISO-8859-3 has a pointer 2 
+PASS Not throw: ISO-8859-3 has a pointer 3 
+PASS Not throw: ISO-8859-3 has a pointer 4 
+PASS Not throw: ISO-8859-3 has a pointer 5 
+PASS Not throw: ISO-8859-3 has a pointer 6 
+PASS Not throw: ISO-8859-3 has a pointer 7 
+PASS Not throw: ISO-8859-3 has a pointer 8 
+PASS Not throw: ISO-8859-3 has a pointer 9 
+PASS Not throw: ISO-8859-3 has a pointer 10 
+PASS Not throw: ISO-8859-3 has a pointer 11 
+PASS Not throw: ISO-8859-3 has a pointer 12 
+PASS Not throw: ISO-8859-3 has a pointer 13 
+PASS Not throw: ISO-8859-3 has a pointer 14 
+PASS Not throw: ISO-8859-3 has a pointer 15 
+PASS Not throw: ISO-8859-3 has a pointer 16 
+PASS Not throw: ISO-8859-3 has a pointer 17 
+PASS Not throw: ISO-8859-3 has a pointer 18 
+PASS Not throw: ISO-8859-3 has a pointer 19 
+PASS Not throw: ISO-8859-3 has a pointer 20 
+PASS Not throw: ISO-8859-3 has a pointer 21 
+PASS Not throw: ISO-8859-3 has a pointer 22 
+PASS Not throw: ISO-8859-3 has a pointer 23 
+PASS Not throw: ISO-8859-3 has a pointer 24 
+PASS Not throw: ISO-8859-3 has a pointer 25 
+PASS Not throw: ISO-8859-3 has a pointer 26 
+PASS Not throw: ISO-8859-3 has a pointer 27 
+PASS Not throw: ISO-8859-3 has a pointer 28 
+PASS Not throw: ISO-8859-3 has a pointer 29 
+PASS Not throw: ISO-8859-3 has a pointer 30 
+PASS Not throw: ISO-8859-3 has a pointer 31 
+PASS Not throw: ISO-8859-3 has a pointer 32 
+PASS Not throw: ISO-8859-3 has a pointer 33 
+PASS Not throw: ISO-8859-3 has a pointer 34 
+PASS Not throw: ISO-8859-3 has a pointer 35 
+PASS Not throw: ISO-8859-3 has a pointer 36 
+PASS Not throw: ISO-8859-3 has a pointer 37 
+PASS Not throw: ISO-8859-3 has a pointer 38 
+PASS Not throw: ISO-8859-3 has a pointer 39 
+PASS Not throw: ISO-8859-3 has a pointer 40 
+PASS Not throw: ISO-8859-3 has a pointer 41 
+PASS Not throw: ISO-8859-3 has a pointer 42 
+PASS Not throw: ISO-8859-3 has a pointer 43 
+PASS Not throw: ISO-8859-3 has a pointer 44 
+PASS Not throw: ISO-8859-3 has a pointer 45 
+PASS Not throw: ISO-8859-3 has a pointer 46 
+PASS Not throw: ISO-8859-3 has a pointer 47 
+PASS Not throw: ISO-8859-3 has a pointer 48 
+PASS Not throw: ISO-8859-3 has a pointer 49 
+PASS Not throw: ISO-8859-3 has a pointer 50 
+PASS Not throw: ISO-8859-3 has a pointer 51 
+PASS Not throw: ISO-8859-3 has a pointer 52 
+PASS Not throw: ISO-8859-3 has a pointer 53 
+PASS Not throw: ISO-8859-3 has a pointer 54 
+PASS Not throw: ISO-8859-3 has a pointer 55 
+PASS Not throw: ISO-8859-3 has a pointer 56 
+PASS Not throw: ISO-8859-3 has a pointer 57 
+PASS Not throw: ISO-8859-3 has a pointer 58 
+PASS Not throw: ISO-8859-3 has a pointer 59 
+PASS Not throw: ISO-8859-3 has a pointer 60 
+PASS Not throw: ISO-8859-3 has a pointer 61 
+PASS Not throw: ISO-8859-3 has a pointer 62 
+PASS Not throw: ISO-8859-3 has a pointer 63 
+PASS Not throw: ISO-8859-3 has a pointer 64 
+PASS Not throw: ISO-8859-3 has a pointer 65 
+PASS Not throw: ISO-8859-3 has a pointer 66 
+PASS Not throw: ISO-8859-3 has a pointer 67 
+PASS Not throw: ISO-8859-3 has a pointer 68 
+PASS Not throw: ISO-8859-3 has a pointer 69 
+PASS Not throw: ISO-8859-3 has a pointer 70 
+PASS Not throw: ISO-8859-3 has a pointer 71 
+PASS Not throw: ISO-8859-3 has a pointer 72 
+PASS Not throw: ISO-8859-3 has a pointer 73 
+PASS Not throw: ISO-8859-3 has a pointer 74 
+PASS Not throw: ISO-8859-3 has a pointer 75 
+PASS Not throw: ISO-8859-3 has a pointer 76 
+PASS Not throw: ISO-8859-3 has a pointer 77 
+PASS Not throw: ISO-8859-3 has a pointer 78 
+PASS Not throw: ISO-8859-3 has a pointer 79 
+PASS Not throw: ISO-8859-3 has a pointer 80 
+PASS Not throw: ISO-8859-3 has a pointer 81 
+PASS Not throw: ISO-8859-3 has a pointer 82 
+PASS Not throw: ISO-8859-3 has a pointer 83 
+PASS Not throw: ISO-8859-3 has a pointer 84 
+PASS Not throw: ISO-8859-3 has a pointer 85 
+PASS Not throw: ISO-8859-3 has a pointer 86 
+PASS Not throw: ISO-8859-3 has a pointer 87 
+PASS Not throw: ISO-8859-3 has a pointer 88 
+PASS Not throw: ISO-8859-3 has a pointer 89 
+PASS Not throw: ISO-8859-3 has a pointer 90 
+PASS Not throw: ISO-8859-3 has a pointer 91 
+PASS Not throw: ISO-8859-3 has a pointer 92 
+PASS Not throw: ISO-8859-3 has a pointer 93 
+PASS Not throw: ISO-8859-3 has a pointer 94 
+PASS Not throw: ISO-8859-3 has a pointer 95 
+PASS Not throw: ISO-8859-3 has a pointer 96 
+PASS Not throw: ISO-8859-3 has a pointer 97 
+PASS Not throw: ISO-8859-3 has a pointer 98 
+PASS Not throw: ISO-8859-3 has a pointer 99 
+PASS Not throw: ISO-8859-3 has a pointer 100 
+PASS Not throw: ISO-8859-3 has a pointer 101 
+PASS Not throw: ISO-8859-3 has a pointer 102 
+PASS Not throw: ISO-8859-3 has a pointer 103 
+PASS Not throw: ISO-8859-3 has a pointer 104 
+PASS Not throw: ISO-8859-3 has a pointer 105 
+PASS Not throw: ISO-8859-3 has a pointer 106 
+PASS Not throw: ISO-8859-3 has a pointer 107 
+PASS Not throw: ISO-8859-3 has a pointer 108 
+PASS Not throw: ISO-8859-3 has a pointer 109 
+PASS Not throw: ISO-8859-3 has a pointer 110 
+PASS Not throw: ISO-8859-3 has a pointer 111 
+PASS Not throw: ISO-8859-3 has a pointer 112 
+PASS Not throw: ISO-8859-3 has a pointer 113 
+PASS Not throw: ISO-8859-3 has a pointer 114 
+PASS Not throw: ISO-8859-3 has a pointer 115 
+PASS Not throw: ISO-8859-3 has a pointer 116 
+PASS Not throw: ISO-8859-3 has a pointer 117 
+PASS Not throw: ISO-8859-3 has a pointer 118 
+PASS Not throw: ISO-8859-3 has a pointer 119 
+PASS Not throw: ISO-8859-3 has a pointer 120 
+PASS Not throw: ISO-8859-3 has a pointer 121 
+PASS Not throw: ISO-8859-3 has a pointer 122 
+PASS Not throw: ISO-8859-3 has a pointer 123 
+PASS Not throw: ISO-8859-3 has a pointer 124 
+PASS Not throw: ISO-8859-3 has a pointer 125 
+PASS Not throw: ISO-8859-3 has a pointer 126 
+PASS Not throw: ISO-8859-3 has a pointer 127 
+PASS Not throw: ISO-8859-3 has a pointer 128 
+PASS Not throw: ISO-8859-3 has a pointer 129 
+PASS Not throw: ISO-8859-3 has a pointer 130 
+PASS Not throw: ISO-8859-3 has a pointer 131 
+PASS Not throw: ISO-8859-3 has a pointer 132 
+PASS Not throw: ISO-8859-3 has a pointer 133 
+PASS Not throw: ISO-8859-3 has a pointer 134 
+PASS Not throw: ISO-8859-3 has a pointer 135 
+PASS Not throw: ISO-8859-3 has a pointer 136 
+PASS Not throw: ISO-8859-3 has a pointer 137 
+PASS Not throw: ISO-8859-3 has a pointer 138 
+PASS Not throw: ISO-8859-3 has a pointer 139 
+PASS Not throw: ISO-8859-3 has a pointer 140 
+PASS Not throw: ISO-8859-3 has a pointer 141 
+PASS Not throw: ISO-8859-3 has a pointer 142 
+PASS Not throw: ISO-8859-3 has a pointer 143 
+PASS Not throw: ISO-8859-3 has a pointer 144 
+PASS Not throw: ISO-8859-3 has a pointer 145 
+PASS Not throw: ISO-8859-3 has a pointer 146 
+PASS Not throw: ISO-8859-3 has a pointer 147 
+PASS Not throw: ISO-8859-3 has a pointer 148 
+PASS Not throw: ISO-8859-3 has a pointer 149 
+PASS Not throw: ISO-8859-3 has a pointer 150 
+PASS Not throw: ISO-8859-3 has a pointer 151 
+PASS Not throw: ISO-8859-3 has a pointer 152 
+PASS Not throw: ISO-8859-3 has a pointer 153 
+PASS Not throw: ISO-8859-3 has a pointer 154 
+PASS Not throw: ISO-8859-3 has a pointer 155 
+PASS Not throw: ISO-8859-3 has a pointer 156 
+PASS Not throw: ISO-8859-3 has a pointer 157 
+PASS Not throw: ISO-8859-3 has a pointer 158 
+PASS Not throw: ISO-8859-3 has a pointer 159 
+PASS Not throw: ISO-8859-3 has a pointer 160 
+PASS Not throw: ISO-8859-3 has a pointer 161 
+PASS Not throw: ISO-8859-3 has a pointer 162 
+PASS Not throw: ISO-8859-3 has a pointer 163 
+PASS Not throw: ISO-8859-3 has a pointer 164 
+FAIL Throw due to fatal flag: ISO-8859-3 doesn't have a pointer 165 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-3 has a pointer 166 
+PASS Not throw: ISO-8859-3 has a pointer 167 
+PASS Not throw: ISO-8859-3 has a pointer 168 
+PASS Not throw: ISO-8859-3 has a pointer 169 
+PASS Not throw: ISO-8859-3 has a pointer 170 
+PASS Not throw: ISO-8859-3 has a pointer 171 
+PASS Not throw: ISO-8859-3 has a pointer 172 
+PASS Not throw: ISO-8859-3 has a pointer 173 
+FAIL Throw due to fatal flag: ISO-8859-3 doesn't have a pointer 174 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-3 has a pointer 175 
+PASS Not throw: ISO-8859-3 has a pointer 176 
+PASS Not throw: ISO-8859-3 has a pointer 177 
+PASS Not throw: ISO-8859-3 has a pointer 178 
+PASS Not throw: ISO-8859-3 has a pointer 179 
+PASS Not throw: ISO-8859-3 has a pointer 180 
+PASS Not throw: ISO-8859-3 has a pointer 181 
+PASS Not throw: ISO-8859-3 has a pointer 182 
+PASS Not throw: ISO-8859-3 has a pointer 183 
+PASS Not throw: ISO-8859-3 has a pointer 184 
+PASS Not throw: ISO-8859-3 has a pointer 185 
+PASS Not throw: ISO-8859-3 has a pointer 186 
+PASS Not throw: ISO-8859-3 has a pointer 187 
+PASS Not throw: ISO-8859-3 has a pointer 188 
+PASS Not throw: ISO-8859-3 has a pointer 189 
+FAIL Throw due to fatal flag: ISO-8859-3 doesn't have a pointer 190 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-3 has a pointer 191 
+PASS Not throw: ISO-8859-3 has a pointer 192 
+PASS Not throw: ISO-8859-3 has a pointer 193 
+PASS Not throw: ISO-8859-3 has a pointer 194 
+FAIL Throw due to fatal flag: ISO-8859-3 doesn't have a pointer 195 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-3 has a pointer 196 
+PASS Not throw: ISO-8859-3 has a pointer 197 
+PASS Not throw: ISO-8859-3 has a pointer 198 
+PASS Not throw: ISO-8859-3 has a pointer 199 
+PASS Not throw: ISO-8859-3 has a pointer 200 
+PASS Not throw: ISO-8859-3 has a pointer 201 
+PASS Not throw: ISO-8859-3 has a pointer 202 
+PASS Not throw: ISO-8859-3 has a pointer 203 
+PASS Not throw: ISO-8859-3 has a pointer 204 
+PASS Not throw: ISO-8859-3 has a pointer 205 
+PASS Not throw: ISO-8859-3 has a pointer 206 
+PASS Not throw: ISO-8859-3 has a pointer 207 
+FAIL Throw due to fatal flag: ISO-8859-3 doesn't have a pointer 208 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-3 has a pointer 209 
+PASS Not throw: ISO-8859-3 has a pointer 210 
+PASS Not throw: ISO-8859-3 has a pointer 211 
+PASS Not throw: ISO-8859-3 has a pointer 212 
+PASS Not throw: ISO-8859-3 has a pointer 213 
+PASS Not throw: ISO-8859-3 has a pointer 214 
+PASS Not throw: ISO-8859-3 has a pointer 215 
+PASS Not throw: ISO-8859-3 has a pointer 216 
+PASS Not throw: ISO-8859-3 has a pointer 217 
+PASS Not throw: ISO-8859-3 has a pointer 218 
+PASS Not throw: ISO-8859-3 has a pointer 219 
+PASS Not throw: ISO-8859-3 has a pointer 220 
+PASS Not throw: ISO-8859-3 has a pointer 221 
+PASS Not throw: ISO-8859-3 has a pointer 222 
+PASS Not throw: ISO-8859-3 has a pointer 223 
+PASS Not throw: ISO-8859-3 has a pointer 224 
+PASS Not throw: ISO-8859-3 has a pointer 225 
+PASS Not throw: ISO-8859-3 has a pointer 226 
+FAIL Throw due to fatal flag: ISO-8859-3 doesn't have a pointer 227 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-3 has a pointer 228 
+PASS Not throw: ISO-8859-3 has a pointer 229 
+PASS Not throw: ISO-8859-3 has a pointer 230 
+PASS Not throw: ISO-8859-3 has a pointer 231 
+PASS Not throw: ISO-8859-3 has a pointer 232 
+PASS Not throw: ISO-8859-3 has a pointer 233 
+PASS Not throw: ISO-8859-3 has a pointer 234 
+PASS Not throw: ISO-8859-3 has a pointer 235 
+PASS Not throw: ISO-8859-3 has a pointer 236 
+PASS Not throw: ISO-8859-3 has a pointer 237 
+PASS Not throw: ISO-8859-3 has a pointer 238 
+PASS Not throw: ISO-8859-3 has a pointer 239 
+FAIL Throw due to fatal flag: ISO-8859-3 doesn't have a pointer 240 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-3 has a pointer 241 
+PASS Not throw: ISO-8859-3 has a pointer 242 
+PASS Not throw: ISO-8859-3 has a pointer 243 
+PASS Not throw: ISO-8859-3 has a pointer 244 
+PASS Not throw: ISO-8859-3 has a pointer 245 
+PASS Not throw: ISO-8859-3 has a pointer 246 
+PASS Not throw: ISO-8859-3 has a pointer 247 
+PASS Not throw: ISO-8859-3 has a pointer 248 
+PASS Not throw: ISO-8859-3 has a pointer 249 
+PASS Not throw: ISO-8859-3 has a pointer 250 
+PASS Not throw: ISO-8859-3 has a pointer 251 
+PASS Not throw: ISO-8859-3 has a pointer 252 
+PASS Not throw: ISO-8859-3 has a pointer 253 
+PASS Not throw: ISO-8859-3 has a pointer 254 
+PASS Not throw: ISO-8859-3 has a pointer 255 
+PASS Not throw: ISO-8859-4 has a pointer 0 
+PASS Not throw: ISO-8859-4 has a pointer 1 
+PASS Not throw: ISO-8859-4 has a pointer 2 
+PASS Not throw: ISO-8859-4 has a pointer 3 
+PASS Not throw: ISO-8859-4 has a pointer 4 
+PASS Not throw: ISO-8859-4 has a pointer 5 
+PASS Not throw: ISO-8859-4 has a pointer 6 
+PASS Not throw: ISO-8859-4 has a pointer 7 
+PASS Not throw: ISO-8859-4 has a pointer 8 
+PASS Not throw: ISO-8859-4 has a pointer 9 
+PASS Not throw: ISO-8859-4 has a pointer 10 
+PASS Not throw: ISO-8859-4 has a pointer 11 
+PASS Not throw: ISO-8859-4 has a pointer 12 
+PASS Not throw: ISO-8859-4 has a pointer 13 
+PASS Not throw: ISO-8859-4 has a pointer 14 
+PASS Not throw: ISO-8859-4 has a pointer 15 
+PASS Not throw: ISO-8859-4 has a pointer 16 
+PASS Not throw: ISO-8859-4 has a pointer 17 
+PASS Not throw: ISO-8859-4 has a pointer 18 
+PASS Not throw: ISO-8859-4 has a pointer 19 
+PASS Not throw: ISO-8859-4 has a pointer 20 
+PASS Not throw: ISO-8859-4 has a pointer 21 
+PASS Not throw: ISO-8859-4 has a pointer 22 
+PASS Not throw: ISO-8859-4 has a pointer 23 
+PASS Not throw: ISO-8859-4 has a pointer 24 
+PASS Not throw: ISO-8859-4 has a pointer 25 
+PASS Not throw: ISO-8859-4 has a pointer 26 
+PASS Not throw: ISO-8859-4 has a pointer 27 
+PASS Not throw: ISO-8859-4 has a pointer 28 
+PASS Not throw: ISO-8859-4 has a pointer 29 
+PASS Not throw: ISO-8859-4 has a pointer 30 
+PASS Not throw: ISO-8859-4 has a pointer 31 
+PASS Not throw: ISO-8859-4 has a pointer 32 
+PASS Not throw: ISO-8859-4 has a pointer 33 
+PASS Not throw: ISO-8859-4 has a pointer 34 
+PASS Not throw: ISO-8859-4 has a pointer 35 
+PASS Not throw: ISO-8859-4 has a pointer 36 
+PASS Not throw: ISO-8859-4 has a pointer 37 
+PASS Not throw: ISO-8859-4 has a pointer 38 
+PASS Not throw: ISO-8859-4 has a pointer 39 
+PASS Not throw: ISO-8859-4 has a pointer 40 
+PASS Not throw: ISO-8859-4 has a pointer 41 
+PASS Not throw: ISO-8859-4 has a pointer 42 
+PASS Not throw: ISO-8859-4 has a pointer 43 
+PASS Not throw: ISO-8859-4 has a pointer 44 
+PASS Not throw: ISO-8859-4 has a pointer 45 
+PASS Not throw: ISO-8859-4 has a pointer 46 
+PASS Not throw: ISO-8859-4 has a pointer 47 
+PASS Not throw: ISO-8859-4 has a pointer 48 
+PASS Not throw: ISO-8859-4 has a pointer 49 
+PASS Not throw: ISO-8859-4 has a pointer 50 
+PASS Not throw: ISO-8859-4 has a pointer 51 
+PASS Not throw: ISO-8859-4 has a pointer 52 
+PASS Not throw: ISO-8859-4 has a pointer 53 
+PASS Not throw: ISO-8859-4 has a pointer 54 
+PASS Not throw: ISO-8859-4 has a pointer 55 
+PASS Not throw: ISO-8859-4 has a pointer 56 
+PASS Not throw: ISO-8859-4 has a pointer 57 
+PASS Not throw: ISO-8859-4 has a pointer 58 
+PASS Not throw: ISO-8859-4 has a pointer 59 
+PASS Not throw: ISO-8859-4 has a pointer 60 
+PASS Not throw: ISO-8859-4 has a pointer 61 
+PASS Not throw: ISO-8859-4 has a pointer 62 
+PASS Not throw: ISO-8859-4 has a pointer 63 
+PASS Not throw: ISO-8859-4 has a pointer 64 
+PASS Not throw: ISO-8859-4 has a pointer 65 
+PASS Not throw: ISO-8859-4 has a pointer 66 
+PASS Not throw: ISO-8859-4 has a pointer 67 
+PASS Not throw: ISO-8859-4 has a pointer 68 
+PASS Not throw: ISO-8859-4 has a pointer 69 
+PASS Not throw: ISO-8859-4 has a pointer 70 
+PASS Not throw: ISO-8859-4 has a pointer 71 
+PASS Not throw: ISO-8859-4 has a pointer 72 
+PASS Not throw: ISO-8859-4 has a pointer 73 
+PASS Not throw: ISO-8859-4 has a pointer 74 
+PASS Not throw: ISO-8859-4 has a pointer 75 
+PASS Not throw: ISO-8859-4 has a pointer 76 
+PASS Not throw: ISO-8859-4 has a pointer 77 
+PASS Not throw: ISO-8859-4 has a pointer 78 
+PASS Not throw: ISO-8859-4 has a pointer 79 
+PASS Not throw: ISO-8859-4 has a pointer 80 
+PASS Not throw: ISO-8859-4 has a pointer 81 
+PASS Not throw: ISO-8859-4 has a pointer 82 
+PASS Not throw: ISO-8859-4 has a pointer 83 
+PASS Not throw: ISO-8859-4 has a pointer 84 
+PASS Not throw: ISO-8859-4 has a pointer 85 
+PASS Not throw: ISO-8859-4 has a pointer 86 
+PASS Not throw: ISO-8859-4 has a pointer 87 
+PASS Not throw: ISO-8859-4 has a pointer 88 
+PASS Not throw: ISO-8859-4 has a pointer 89 
+PASS Not throw: ISO-8859-4 has a pointer 90 
+PASS Not throw: ISO-8859-4 has a pointer 91 
+PASS Not throw: ISO-8859-4 has a pointer 92 
+PASS Not throw: ISO-8859-4 has a pointer 93 
+PASS Not throw: ISO-8859-4 has a pointer 94 
+PASS Not throw: ISO-8859-4 has a pointer 95 
+PASS Not throw: ISO-8859-4 has a pointer 96 
+PASS Not throw: ISO-8859-4 has a pointer 97 
+PASS Not throw: ISO-8859-4 has a pointer 98 
+PASS Not throw: ISO-8859-4 has a pointer 99 
+PASS Not throw: ISO-8859-4 has a pointer 100 
+PASS Not throw: ISO-8859-4 has a pointer 101 
+PASS Not throw: ISO-8859-4 has a pointer 102 
+PASS Not throw: ISO-8859-4 has a pointer 103 
+PASS Not throw: ISO-8859-4 has a pointer 104 
+PASS Not throw: ISO-8859-4 has a pointer 105 
+PASS Not throw: ISO-8859-4 has a pointer 106 
+PASS Not throw: ISO-8859-4 has a pointer 107 
+PASS Not throw: ISO-8859-4 has a pointer 108 
+PASS Not throw: ISO-8859-4 has a pointer 109 
+PASS Not throw: ISO-8859-4 has a pointer 110 
+PASS Not throw: ISO-8859-4 has a pointer 111 
+PASS Not throw: ISO-8859-4 has a pointer 112 
+PASS Not throw: ISO-8859-4 has a pointer 113 
+PASS Not throw: ISO-8859-4 has a pointer 114 
+PASS Not throw: ISO-8859-4 has a pointer 115 
+PASS Not throw: ISO-8859-4 has a pointer 116 
+PASS Not throw: ISO-8859-4 has a pointer 117 
+PASS Not throw: ISO-8859-4 has a pointer 118 
+PASS Not throw: ISO-8859-4 has a pointer 119 
+PASS Not throw: ISO-8859-4 has a pointer 120 
+PASS Not throw: ISO-8859-4 has a pointer 121 
+PASS Not throw: ISO-8859-4 has a pointer 122 
+PASS Not throw: ISO-8859-4 has a pointer 123 
+PASS Not throw: ISO-8859-4 has a pointer 124 
+PASS Not throw: ISO-8859-4 has a pointer 125 
+PASS Not throw: ISO-8859-4 has a pointer 126 
+PASS Not throw: ISO-8859-4 has a pointer 127 
+PASS Not throw: ISO-8859-4 has a pointer 128 
+PASS Not throw: ISO-8859-4 has a pointer 129 
+PASS Not throw: ISO-8859-4 has a pointer 130 
+PASS Not throw: ISO-8859-4 has a pointer 131 
+PASS Not throw: ISO-8859-4 has a pointer 132 
+PASS Not throw: ISO-8859-4 has a pointer 133 
+PASS Not throw: ISO-8859-4 has a pointer 134 
+PASS Not throw: ISO-8859-4 has a pointer 135 
+PASS Not throw: ISO-8859-4 has a pointer 136 
+PASS Not throw: ISO-8859-4 has a pointer 137 
+PASS Not throw: ISO-8859-4 has a pointer 138 
+PASS Not throw: ISO-8859-4 has a pointer 139 
+PASS Not throw: ISO-8859-4 has a pointer 140 
+PASS Not throw: ISO-8859-4 has a pointer 141 
+PASS Not throw: ISO-8859-4 has a pointer 142 
+PASS Not throw: ISO-8859-4 has a pointer 143 
+PASS Not throw: ISO-8859-4 has a pointer 144 
+PASS Not throw: ISO-8859-4 has a pointer 145 
+PASS Not throw: ISO-8859-4 has a pointer 146 
+PASS Not throw: ISO-8859-4 has a pointer 147 
+PASS Not throw: ISO-8859-4 has a pointer 148 
+PASS Not throw: ISO-8859-4 has a pointer 149 
+PASS Not throw: ISO-8859-4 has a pointer 150 
+PASS Not throw: ISO-8859-4 has a pointer 151 
+PASS Not throw: ISO-8859-4 has a pointer 152 
+PASS Not throw: ISO-8859-4 has a pointer 153 
+PASS Not throw: ISO-8859-4 has a pointer 154 
+PASS Not throw: ISO-8859-4 has a pointer 155 
+PASS Not throw: ISO-8859-4 has a pointer 156 
+PASS Not throw: ISO-8859-4 has a pointer 157 
+PASS Not throw: ISO-8859-4 has a pointer 158 
+PASS Not throw: ISO-8859-4 has a pointer 159 
+PASS Not throw: ISO-8859-4 has a pointer 160 
+PASS Not throw: ISO-8859-4 has a pointer 161 
+PASS Not throw: ISO-8859-4 has a pointer 162 
+PASS Not throw: ISO-8859-4 has a pointer 163 
+PASS Not throw: ISO-8859-4 has a pointer 164 
+PASS Not throw: ISO-8859-4 has a pointer 165 
+PASS Not throw: ISO-8859-4 has a pointer 166 
+PASS Not throw: ISO-8859-4 has a pointer 167 
+PASS Not throw: ISO-8859-4 has a pointer 168 
+PASS Not throw: ISO-8859-4 has a pointer 169 
+PASS Not throw: ISO-8859-4 has a pointer 170 
+PASS Not throw: ISO-8859-4 has a pointer 171 
+PASS Not throw: ISO-8859-4 has a pointer 172 
+PASS Not throw: ISO-8859-4 has a pointer 173 
+PASS Not throw: ISO-8859-4 has a pointer 174 
+PASS Not throw: ISO-8859-4 has a pointer 175 
+PASS Not throw: ISO-8859-4 has a pointer 176 
+PASS Not throw: ISO-8859-4 has a pointer 177 
+PASS Not throw: ISO-8859-4 has a pointer 178 
+PASS Not throw: ISO-8859-4 has a pointer 179 
+PASS Not throw: ISO-8859-4 has a pointer 180 
+PASS Not throw: ISO-8859-4 has a pointer 181 
+PASS Not throw: ISO-8859-4 has a pointer 182 
+PASS Not throw: ISO-8859-4 has a pointer 183 
+PASS Not throw: ISO-8859-4 has a pointer 184 
+PASS Not throw: ISO-8859-4 has a pointer 185 
+PASS Not throw: ISO-8859-4 has a pointer 186 
+PASS Not throw: ISO-8859-4 has a pointer 187 
+PASS Not throw: ISO-8859-4 has a pointer 188 
+PASS Not throw: ISO-8859-4 has a pointer 189 
+PASS Not throw: ISO-8859-4 has a pointer 190 
+PASS Not throw: ISO-8859-4 has a pointer 191 
+PASS Not throw: ISO-8859-4 has a pointer 192 
+PASS Not throw: ISO-8859-4 has a pointer 193 
+PASS Not throw: ISO-8859-4 has a pointer 194 
+PASS Not throw: ISO-8859-4 has a pointer 195 
+PASS Not throw: ISO-8859-4 has a pointer 196 
+PASS Not throw: ISO-8859-4 has a pointer 197 
+PASS Not throw: ISO-8859-4 has a pointer 198 
+PASS Not throw: ISO-8859-4 has a pointer 199 
+PASS Not throw: ISO-8859-4 has a pointer 200 
+PASS Not throw: ISO-8859-4 has a pointer 201 
+PASS Not throw: ISO-8859-4 has a pointer 202 
+PASS Not throw: ISO-8859-4 has a pointer 203 
+PASS Not throw: ISO-8859-4 has a pointer 204 
+PASS Not throw: ISO-8859-4 has a pointer 205 
+PASS Not throw: ISO-8859-4 has a pointer 206 
+PASS Not throw: ISO-8859-4 has a pointer 207 
+PASS Not throw: ISO-8859-4 has a pointer 208 
+PASS Not throw: ISO-8859-4 has a pointer 209 
+PASS Not throw: ISO-8859-4 has a pointer 210 
+PASS Not throw: ISO-8859-4 has a pointer 211 
+PASS Not throw: ISO-8859-4 has a pointer 212 
+PASS Not throw: ISO-8859-4 has a pointer 213 
+PASS Not throw: ISO-8859-4 has a pointer 214 
+PASS Not throw: ISO-8859-4 has a pointer 215 
+PASS Not throw: ISO-8859-4 has a pointer 216 
+PASS Not throw: ISO-8859-4 has a pointer 217 
+PASS Not throw: ISO-8859-4 has a pointer 218 
+PASS Not throw: ISO-8859-4 has a pointer 219 
+PASS Not throw: ISO-8859-4 has a pointer 220 
+PASS Not throw: ISO-8859-4 has a pointer 221 
+PASS Not throw: ISO-8859-4 has a pointer 222 
+PASS Not throw: ISO-8859-4 has a pointer 223 
+PASS Not throw: ISO-8859-4 has a pointer 224 
+PASS Not throw: ISO-8859-4 has a pointer 225 
+PASS Not throw: ISO-8859-4 has a pointer 226 
+PASS Not throw: ISO-8859-4 has a pointer 227 
+PASS Not throw: ISO-8859-4 has a pointer 228 
+PASS Not throw: ISO-8859-4 has a pointer 229 
+PASS Not throw: ISO-8859-4 has a pointer 230 
+PASS Not throw: ISO-8859-4 has a pointer 231 
+PASS Not throw: ISO-8859-4 has a pointer 232 
+PASS Not throw: ISO-8859-4 has a pointer 233 
+PASS Not throw: ISO-8859-4 has a pointer 234 
+PASS Not throw: ISO-8859-4 has a pointer 235 
+PASS Not throw: ISO-8859-4 has a pointer 236 
+PASS Not throw: ISO-8859-4 has a pointer 237 
+PASS Not throw: ISO-8859-4 has a pointer 238 
+PASS Not throw: ISO-8859-4 has a pointer 239 
+PASS Not throw: ISO-8859-4 has a pointer 240 
+PASS Not throw: ISO-8859-4 has a pointer 241 
+PASS Not throw: ISO-8859-4 has a pointer 242 
+PASS Not throw: ISO-8859-4 has a pointer 243 
+PASS Not throw: ISO-8859-4 has a pointer 244 
+PASS Not throw: ISO-8859-4 has a pointer 245 
+PASS Not throw: ISO-8859-4 has a pointer 246 
+PASS Not throw: ISO-8859-4 has a pointer 247 
+PASS Not throw: ISO-8859-4 has a pointer 248 
+PASS Not throw: ISO-8859-4 has a pointer 249 
+PASS Not throw: ISO-8859-4 has a pointer 250 
+PASS Not throw: ISO-8859-4 has a pointer 251 
+PASS Not throw: ISO-8859-4 has a pointer 252 
+PASS Not throw: ISO-8859-4 has a pointer 253 
+PASS Not throw: ISO-8859-4 has a pointer 254 
+PASS Not throw: ISO-8859-4 has a pointer 255 
+PASS Not throw: ISO-8859-5 has a pointer 0 
+PASS Not throw: ISO-8859-5 has a pointer 1 
+PASS Not throw: ISO-8859-5 has a pointer 2 
+PASS Not throw: ISO-8859-5 has a pointer 3 
+PASS Not throw: ISO-8859-5 has a pointer 4 
+PASS Not throw: ISO-8859-5 has a pointer 5 
+PASS Not throw: ISO-8859-5 has a pointer 6 
+PASS Not throw: ISO-8859-5 has a pointer 7 
+PASS Not throw: ISO-8859-5 has a pointer 8 
+PASS Not throw: ISO-8859-5 has a pointer 9 
+PASS Not throw: ISO-8859-5 has a pointer 10 
+PASS Not throw: ISO-8859-5 has a pointer 11 
+PASS Not throw: ISO-8859-5 has a pointer 12 
+PASS Not throw: ISO-8859-5 has a pointer 13 
+PASS Not throw: ISO-8859-5 has a pointer 14 
+PASS Not throw: ISO-8859-5 has a pointer 15 
+PASS Not throw: ISO-8859-5 has a pointer 16 
+PASS Not throw: ISO-8859-5 has a pointer 17 
+PASS Not throw: ISO-8859-5 has a pointer 18 
+PASS Not throw: ISO-8859-5 has a pointer 19 
+PASS Not throw: ISO-8859-5 has a pointer 20 
+PASS Not throw: ISO-8859-5 has a pointer 21 
+PASS Not throw: ISO-8859-5 has a pointer 22 
+PASS Not throw: ISO-8859-5 has a pointer 23 
+PASS Not throw: ISO-8859-5 has a pointer 24 
+PASS Not throw: ISO-8859-5 has a pointer 25 
+PASS Not throw: ISO-8859-5 has a pointer 26 
+PASS Not throw: ISO-8859-5 has a pointer 27 
+PASS Not throw: ISO-8859-5 has a pointer 28 
+PASS Not throw: ISO-8859-5 has a pointer 29 
+PASS Not throw: ISO-8859-5 has a pointer 30 
+PASS Not throw: ISO-8859-5 has a pointer 31 
+PASS Not throw: ISO-8859-5 has a pointer 32 
+PASS Not throw: ISO-8859-5 has a pointer 33 
+PASS Not throw: ISO-8859-5 has a pointer 34 
+PASS Not throw: ISO-8859-5 has a pointer 35 
+PASS Not throw: ISO-8859-5 has a pointer 36 
+PASS Not throw: ISO-8859-5 has a pointer 37 
+PASS Not throw: ISO-8859-5 has a pointer 38 
+PASS Not throw: ISO-8859-5 has a pointer 39 
+PASS Not throw: ISO-8859-5 has a pointer 40 
+PASS Not throw: ISO-8859-5 has a pointer 41 
+PASS Not throw: ISO-8859-5 has a pointer 42 
+PASS Not throw: ISO-8859-5 has a pointer 43 
+PASS Not throw: ISO-8859-5 has a pointer 44 
+PASS Not throw: ISO-8859-5 has a pointer 45 
+PASS Not throw: ISO-8859-5 has a pointer 46 
+PASS Not throw: ISO-8859-5 has a pointer 47 
+PASS Not throw: ISO-8859-5 has a pointer 48 
+PASS Not throw: ISO-8859-5 has a pointer 49 
+PASS Not throw: ISO-8859-5 has a pointer 50 
+PASS Not throw: ISO-8859-5 has a pointer 51 
+PASS Not throw: ISO-8859-5 has a pointer 52 
+PASS Not throw: ISO-8859-5 has a pointer 53 
+PASS Not throw: ISO-8859-5 has a pointer 54 
+PASS Not throw: ISO-8859-5 has a pointer 55 
+PASS Not throw: ISO-8859-5 has a pointer 56 
+PASS Not throw: ISO-8859-5 has a pointer 57 
+PASS Not throw: ISO-8859-5 has a pointer 58 
+PASS Not throw: ISO-8859-5 has a pointer 59 
+PASS Not throw: ISO-8859-5 has a pointer 60 
+PASS Not throw: ISO-8859-5 has a pointer 61 
+PASS Not throw: ISO-8859-5 has a pointer 62 
+PASS Not throw: ISO-8859-5 has a pointer 63 
+PASS Not throw: ISO-8859-5 has a pointer 64 
+PASS Not throw: ISO-8859-5 has a pointer 65 
+PASS Not throw: ISO-8859-5 has a pointer 66 
+PASS Not throw: ISO-8859-5 has a pointer 67 
+PASS Not throw: ISO-8859-5 has a pointer 68 
+PASS Not throw: ISO-8859-5 has a pointer 69 
+PASS Not throw: ISO-8859-5 has a pointer 70 
+PASS Not throw: ISO-8859-5 has a pointer 71 
+PASS Not throw: ISO-8859-5 has a pointer 72 
+PASS Not throw: ISO-8859-5 has a pointer 73 
+PASS Not throw: ISO-8859-5 has a pointer 74 
+PASS Not throw: ISO-8859-5 has a pointer 75 
+PASS Not throw: ISO-8859-5 has a pointer 76 
+PASS Not throw: ISO-8859-5 has a pointer 77 
+PASS Not throw: ISO-8859-5 has a pointer 78 
+PASS Not throw: ISO-8859-5 has a pointer 79 
+PASS Not throw: ISO-8859-5 has a pointer 80 
+PASS Not throw: ISO-8859-5 has a pointer 81 
+PASS Not throw: ISO-8859-5 has a pointer 82 
+PASS Not throw: ISO-8859-5 has a pointer 83 
+PASS Not throw: ISO-8859-5 has a pointer 84 
+PASS Not throw: ISO-8859-5 has a pointer 85 
+PASS Not throw: ISO-8859-5 has a pointer 86 
+PASS Not throw: ISO-8859-5 has a pointer 87 
+PASS Not throw: ISO-8859-5 has a pointer 88 
+PASS Not throw: ISO-8859-5 has a pointer 89 
+PASS Not throw: ISO-8859-5 has a pointer 90 
+PASS Not throw: ISO-8859-5 has a pointer 91 
+PASS Not throw: ISO-8859-5 has a pointer 92 
+PASS Not throw: ISO-8859-5 has a pointer 93 
+PASS Not throw: ISO-8859-5 has a pointer 94 
+PASS Not throw: ISO-8859-5 has a pointer 95 
+PASS Not throw: ISO-8859-5 has a pointer 96 
+PASS Not throw: ISO-8859-5 has a pointer 97 
+PASS Not throw: ISO-8859-5 has a pointer 98 
+PASS Not throw: ISO-8859-5 has a pointer 99 
+PASS Not throw: ISO-8859-5 has a pointer 100 
+PASS Not throw: ISO-8859-5 has a pointer 101 
+PASS Not throw: ISO-8859-5 has a pointer 102 
+PASS Not throw: ISO-8859-5 has a pointer 103 
+PASS Not throw: ISO-8859-5 has a pointer 104 
+PASS Not throw: ISO-8859-5 has a pointer 105 
+PASS Not throw: ISO-8859-5 has a pointer 106 
+PASS Not throw: ISO-8859-5 has a pointer 107 
+PASS Not throw: ISO-8859-5 has a pointer 108 
+PASS Not throw: ISO-8859-5 has a pointer 109 
+PASS Not throw: ISO-8859-5 has a pointer 110 
+PASS Not throw: ISO-8859-5 has a pointer 111 
+PASS Not throw: ISO-8859-5 has a pointer 112 
+PASS Not throw: ISO-8859-5 has a pointer 113 
+PASS Not throw: ISO-8859-5 has a pointer 114 
+PASS Not throw: ISO-8859-5 has a pointer 115 
+PASS Not throw: ISO-8859-5 has a pointer 116 
+PASS Not throw: ISO-8859-5 has a pointer 117 
+PASS Not throw: ISO-8859-5 has a pointer 118 
+PASS Not throw: ISO-8859-5 has a pointer 119 
+PASS Not throw: ISO-8859-5 has a pointer 120 
+PASS Not throw: ISO-8859-5 has a pointer 121 
+PASS Not throw: ISO-8859-5 has a pointer 122 
+PASS Not throw: ISO-8859-5 has a pointer 123 
+PASS Not throw: ISO-8859-5 has a pointer 124 
+PASS Not throw: ISO-8859-5 has a pointer 125 
+PASS Not throw: ISO-8859-5 has a pointer 126 
+PASS Not throw: ISO-8859-5 has a pointer 127 
+PASS Not throw: ISO-8859-5 has a pointer 128 
+PASS Not throw: ISO-8859-5 has a pointer 129 
+PASS Not throw: ISO-8859-5 has a pointer 130 
+PASS Not throw: ISO-8859-5 has a pointer 131 
+PASS Not throw: ISO-8859-5 has a pointer 132 
+PASS Not throw: ISO-8859-5 has a pointer 133 
+PASS Not throw: ISO-8859-5 has a pointer 134 
+PASS Not throw: ISO-8859-5 has a pointer 135 
+PASS Not throw: ISO-8859-5 has a pointer 136 
+PASS Not throw: ISO-8859-5 has a pointer 137 
+PASS Not throw: ISO-8859-5 has a pointer 138 
+PASS Not throw: ISO-8859-5 has a pointer 139 
+PASS Not throw: ISO-8859-5 has a pointer 140 
+PASS Not throw: ISO-8859-5 has a pointer 141 
+PASS Not throw: ISO-8859-5 has a pointer 142 
+PASS Not throw: ISO-8859-5 has a pointer 143 
+PASS Not throw: ISO-8859-5 has a pointer 144 
+PASS Not throw: ISO-8859-5 has a pointer 145 
+PASS Not throw: ISO-8859-5 has a pointer 146 
+PASS Not throw: ISO-8859-5 has a pointer 147 
+PASS Not throw: ISO-8859-5 has a pointer 148 
+PASS Not throw: ISO-8859-5 has a pointer 149 
+PASS Not throw: ISO-8859-5 has a pointer 150 
+PASS Not throw: ISO-8859-5 has a pointer 151 
+PASS Not throw: ISO-8859-5 has a pointer 152 
+PASS Not throw: ISO-8859-5 has a pointer 153 
+PASS Not throw: ISO-8859-5 has a pointer 154 
+PASS Not throw: ISO-8859-5 has a pointer 155 
+PASS Not throw: ISO-8859-5 has a pointer 156 
+PASS Not throw: ISO-8859-5 has a pointer 157 
+PASS Not throw: ISO-8859-5 has a pointer 158 
+PASS Not throw: ISO-8859-5 has a pointer 159 
+PASS Not throw: ISO-8859-5 has a pointer 160 
+PASS Not throw: ISO-8859-5 has a pointer 161 
+PASS Not throw: ISO-8859-5 has a pointer 162 
+PASS Not throw: ISO-8859-5 has a pointer 163 
+PASS Not throw: ISO-8859-5 has a pointer 164 
+PASS Not throw: ISO-8859-5 has a pointer 165 
+PASS Not throw: ISO-8859-5 has a pointer 166 
+PASS Not throw: ISO-8859-5 has a pointer 167 
+PASS Not throw: ISO-8859-5 has a pointer 168 
+PASS Not throw: ISO-8859-5 has a pointer 169 
+PASS Not throw: ISO-8859-5 has a pointer 170 
+PASS Not throw: ISO-8859-5 has a pointer 171 
+PASS Not throw: ISO-8859-5 has a pointer 172 
+PASS Not throw: ISO-8859-5 has a pointer 173 
+PASS Not throw: ISO-8859-5 has a pointer 174 
+PASS Not throw: ISO-8859-5 has a pointer 175 
+PASS Not throw: ISO-8859-5 has a pointer 176 
+PASS Not throw: ISO-8859-5 has a pointer 177 
+PASS Not throw: ISO-8859-5 has a pointer 178 
+PASS Not throw: ISO-8859-5 has a pointer 179 
+PASS Not throw: ISO-8859-5 has a pointer 180 
+PASS Not throw: ISO-8859-5 has a pointer 181 
+PASS Not throw: ISO-8859-5 has a pointer 182 
+PASS Not throw: ISO-8859-5 has a pointer 183 
+PASS Not throw: ISO-8859-5 has a pointer 184 
+PASS Not throw: ISO-8859-5 has a pointer 185 
+PASS Not throw: ISO-8859-5 has a pointer 186 
+PASS Not throw: ISO-8859-5 has a pointer 187 
+PASS Not throw: ISO-8859-5 has a pointer 188 
+PASS Not throw: ISO-8859-5 has a pointer 189 
+PASS Not throw: ISO-8859-5 has a pointer 190 
+PASS Not throw: ISO-8859-5 has a pointer 191 
+PASS Not throw: ISO-8859-5 has a pointer 192 
+PASS Not throw: ISO-8859-5 has a pointer 193 
+PASS Not throw: ISO-8859-5 has a pointer 194 
+PASS Not throw: ISO-8859-5 has a pointer 195 
+PASS Not throw: ISO-8859-5 has a pointer 196 
+PASS Not throw: ISO-8859-5 has a pointer 197 
+PASS Not throw: ISO-8859-5 has a pointer 198 
+PASS Not throw: ISO-8859-5 has a pointer 199 
+PASS Not throw: ISO-8859-5 has a pointer 200 
+PASS Not throw: ISO-8859-5 has a pointer 201 
+PASS Not throw: ISO-8859-5 has a pointer 202 
+PASS Not throw: ISO-8859-5 has a pointer 203 
+PASS Not throw: ISO-8859-5 has a pointer 204 
+PASS Not throw: ISO-8859-5 has a pointer 205 
+PASS Not throw: ISO-8859-5 has a pointer 206 
+PASS Not throw: ISO-8859-5 has a pointer 207 
+PASS Not throw: ISO-8859-5 has a pointer 208 
+PASS Not throw: ISO-8859-5 has a pointer 209 
+PASS Not throw: ISO-8859-5 has a pointer 210 
+PASS Not throw: ISO-8859-5 has a pointer 211 
+PASS Not throw: ISO-8859-5 has a pointer 212 
+PASS Not throw: ISO-8859-5 has a pointer 213 
+PASS Not throw: ISO-8859-5 has a pointer 214 
+PASS Not throw: ISO-8859-5 has a pointer 215 
+PASS Not throw: ISO-8859-5 has a pointer 216 
+PASS Not throw: ISO-8859-5 has a pointer 217 
+PASS Not throw: ISO-8859-5 has a pointer 218 
+PASS Not throw: ISO-8859-5 has a pointer 219 
+PASS Not throw: ISO-8859-5 has a pointer 220 
+PASS Not throw: ISO-8859-5 has a pointer 221 
+PASS Not throw: ISO-8859-5 has a pointer 222 
+PASS Not throw: ISO-8859-5 has a pointer 223 
+PASS Not throw: ISO-8859-5 has a pointer 224 
+PASS Not throw: ISO-8859-5 has a pointer 225 
+PASS Not throw: ISO-8859-5 has a pointer 226 
+PASS Not throw: ISO-8859-5 has a pointer 227 
+PASS Not throw: ISO-8859-5 has a pointer 228 
+PASS Not throw: ISO-8859-5 has a pointer 229 
+PASS Not throw: ISO-8859-5 has a pointer 230 
+PASS Not throw: ISO-8859-5 has a pointer 231 
+PASS Not throw: ISO-8859-5 has a pointer 232 
+PASS Not throw: ISO-8859-5 has a pointer 233 
+PASS Not throw: ISO-8859-5 has a pointer 234 
+PASS Not throw: ISO-8859-5 has a pointer 235 
+PASS Not throw: ISO-8859-5 has a pointer 236 
+PASS Not throw: ISO-8859-5 has a pointer 237 
+PASS Not throw: ISO-8859-5 has a pointer 238 
+PASS Not throw: ISO-8859-5 has a pointer 239 
+PASS Not throw: ISO-8859-5 has a pointer 240 
+PASS Not throw: ISO-8859-5 has a pointer 241 
+PASS Not throw: ISO-8859-5 has a pointer 242 
+PASS Not throw: ISO-8859-5 has a pointer 243 
+PASS Not throw: ISO-8859-5 has a pointer 244 
+PASS Not throw: ISO-8859-5 has a pointer 245 
+PASS Not throw: ISO-8859-5 has a pointer 246 
+PASS Not throw: ISO-8859-5 has a pointer 247 
+PASS Not throw: ISO-8859-5 has a pointer 248 
+PASS Not throw: ISO-8859-5 has a pointer 249 
+PASS Not throw: ISO-8859-5 has a pointer 250 
+PASS Not throw: ISO-8859-5 has a pointer 251 
+PASS Not throw: ISO-8859-5 has a pointer 252 
+PASS Not throw: ISO-8859-5 has a pointer 253 
+PASS Not throw: ISO-8859-5 has a pointer 254 
+PASS Not throw: ISO-8859-5 has a pointer 255 
+PASS Not throw: ISO-8859-6 has a pointer 0 
+PASS Not throw: ISO-8859-6 has a pointer 1 
+PASS Not throw: ISO-8859-6 has a pointer 2 
+PASS Not throw: ISO-8859-6 has a pointer 3 
+PASS Not throw: ISO-8859-6 has a pointer 4 
+PASS Not throw: ISO-8859-6 has a pointer 5 
+PASS Not throw: ISO-8859-6 has a pointer 6 
+PASS Not throw: ISO-8859-6 has a pointer 7 
+PASS Not throw: ISO-8859-6 has a pointer 8 
+PASS Not throw: ISO-8859-6 has a pointer 9 
+PASS Not throw: ISO-8859-6 has a pointer 10 
+PASS Not throw: ISO-8859-6 has a pointer 11 
+PASS Not throw: ISO-8859-6 has a pointer 12 
+PASS Not throw: ISO-8859-6 has a pointer 13 
+PASS Not throw: ISO-8859-6 has a pointer 14 
+PASS Not throw: ISO-8859-6 has a pointer 15 
+PASS Not throw: ISO-8859-6 has a pointer 16 
+PASS Not throw: ISO-8859-6 has a pointer 17 
+PASS Not throw: ISO-8859-6 has a pointer 18 
+PASS Not throw: ISO-8859-6 has a pointer 19 
+PASS Not throw: ISO-8859-6 has a pointer 20 
+PASS Not throw: ISO-8859-6 has a pointer 21 
+PASS Not throw: ISO-8859-6 has a pointer 22 
+PASS Not throw: ISO-8859-6 has a pointer 23 
+PASS Not throw: ISO-8859-6 has a pointer 24 
+PASS Not throw: ISO-8859-6 has a pointer 25 
+PASS Not throw: ISO-8859-6 has a pointer 26 
+PASS Not throw: ISO-8859-6 has a pointer 27 
+PASS Not throw: ISO-8859-6 has a pointer 28 
+PASS Not throw: ISO-8859-6 has a pointer 29 
+PASS Not throw: ISO-8859-6 has a pointer 30 
+PASS Not throw: ISO-8859-6 has a pointer 31 
+PASS Not throw: ISO-8859-6 has a pointer 32 
+PASS Not throw: ISO-8859-6 has a pointer 33 
+PASS Not throw: ISO-8859-6 has a pointer 34 
+PASS Not throw: ISO-8859-6 has a pointer 35 
+PASS Not throw: ISO-8859-6 has a pointer 36 
+PASS Not throw: ISO-8859-6 has a pointer 37 
+PASS Not throw: ISO-8859-6 has a pointer 38 
+PASS Not throw: ISO-8859-6 has a pointer 39 
+PASS Not throw: ISO-8859-6 has a pointer 40 
+PASS Not throw: ISO-8859-6 has a pointer 41 
+PASS Not throw: ISO-8859-6 has a pointer 42 
+PASS Not throw: ISO-8859-6 has a pointer 43 
+PASS Not throw: ISO-8859-6 has a pointer 44 
+PASS Not throw: ISO-8859-6 has a pointer 45 
+PASS Not throw: ISO-8859-6 has a pointer 46 
+PASS Not throw: ISO-8859-6 has a pointer 47 
+PASS Not throw: ISO-8859-6 has a pointer 48 
+PASS Not throw: ISO-8859-6 has a pointer 49 
+PASS Not throw: ISO-8859-6 has a pointer 50 
+PASS Not throw: ISO-8859-6 has a pointer 51 
+PASS Not throw: ISO-8859-6 has a pointer 52 
+PASS Not throw: ISO-8859-6 has a pointer 53 
+PASS Not throw: ISO-8859-6 has a pointer 54 
+PASS Not throw: ISO-8859-6 has a pointer 55 
+PASS Not throw: ISO-8859-6 has a pointer 56 
+PASS Not throw: ISO-8859-6 has a pointer 57 
+PASS Not throw: ISO-8859-6 has a pointer 58 
+PASS Not throw: ISO-8859-6 has a pointer 59 
+PASS Not throw: ISO-8859-6 has a pointer 60 
+PASS Not throw: ISO-8859-6 has a pointer 61 
+PASS Not throw: ISO-8859-6 has a pointer 62 
+PASS Not throw: ISO-8859-6 has a pointer 63 
+PASS Not throw: ISO-8859-6 has a pointer 64 
+PASS Not throw: ISO-8859-6 has a pointer 65 
+PASS Not throw: ISO-8859-6 has a pointer 66 
+PASS Not throw: ISO-8859-6 has a pointer 67 
+PASS Not throw: ISO-8859-6 has a pointer 68 
+PASS Not throw: ISO-8859-6 has a pointer 69 
+PASS Not throw: ISO-8859-6 has a pointer 70 
+PASS Not throw: ISO-8859-6 has a pointer 71 
+PASS Not throw: ISO-8859-6 has a pointer 72 
+PASS Not throw: ISO-8859-6 has a pointer 73 
+PASS Not throw: ISO-8859-6 has a pointer 74 
+PASS Not throw: ISO-8859-6 has a pointer 75 
+PASS Not throw: ISO-8859-6 has a pointer 76 
+PASS Not throw: ISO-8859-6 has a pointer 77 
+PASS Not throw: ISO-8859-6 has a pointer 78 
+PASS Not throw: ISO-8859-6 has a pointer 79 
+PASS Not throw: ISO-8859-6 has a pointer 80 
+PASS Not throw: ISO-8859-6 has a pointer 81 
+PASS Not throw: ISO-8859-6 has a pointer 82 
+PASS Not throw: ISO-8859-6 has a pointer 83 
+PASS Not throw: ISO-8859-6 has a pointer 84 
+PASS Not throw: ISO-8859-6 has a pointer 85 
+PASS Not throw: ISO-8859-6 has a pointer 86 
+PASS Not throw: ISO-8859-6 has a pointer 87 
+PASS Not throw: ISO-8859-6 has a pointer 88 
+PASS Not throw: ISO-8859-6 has a pointer 89 
+PASS Not throw: ISO-8859-6 has a pointer 90 
+PASS Not throw: ISO-8859-6 has a pointer 91 
+PASS Not throw: ISO-8859-6 has a pointer 92 
+PASS Not throw: ISO-8859-6 has a pointer 93 
+PASS Not throw: ISO-8859-6 has a pointer 94 
+PASS Not throw: ISO-8859-6 has a pointer 95 
+PASS Not throw: ISO-8859-6 has a pointer 96 
+PASS Not throw: ISO-8859-6 has a pointer 97 
+PASS Not throw: ISO-8859-6 has a pointer 98 
+PASS Not throw: ISO-8859-6 has a pointer 99 
+PASS Not throw: ISO-8859-6 has a pointer 100 
+PASS Not throw: ISO-8859-6 has a pointer 101 
+PASS Not throw: ISO-8859-6 has a pointer 102 
+PASS Not throw: ISO-8859-6 has a pointer 103 
+PASS Not throw: ISO-8859-6 has a pointer 104 
+PASS Not throw: ISO-8859-6 has a pointer 105 
+PASS Not throw: ISO-8859-6 has a pointer 106 
+PASS Not throw: ISO-8859-6 has a pointer 107 
+PASS Not throw: ISO-8859-6 has a pointer 108 
+PASS Not throw: ISO-8859-6 has a pointer 109 
+PASS Not throw: ISO-8859-6 has a pointer 110 
+PASS Not throw: ISO-8859-6 has a pointer 111 
+PASS Not throw: ISO-8859-6 has a pointer 112 
+PASS Not throw: ISO-8859-6 has a pointer 113 
+PASS Not throw: ISO-8859-6 has a pointer 114 
+PASS Not throw: ISO-8859-6 has a pointer 115 
+PASS Not throw: ISO-8859-6 has a pointer 116 
+PASS Not throw: ISO-8859-6 has a pointer 117 
+PASS Not throw: ISO-8859-6 has a pointer 118 
+PASS Not throw: ISO-8859-6 has a pointer 119 
+PASS Not throw: ISO-8859-6 has a pointer 120 
+PASS Not throw: ISO-8859-6 has a pointer 121 
+PASS Not throw: ISO-8859-6 has a pointer 122 
+PASS Not throw: ISO-8859-6 has a pointer 123 
+PASS Not throw: ISO-8859-6 has a pointer 124 
+PASS Not throw: ISO-8859-6 has a pointer 125 
+PASS Not throw: ISO-8859-6 has a pointer 126 
+PASS Not throw: ISO-8859-6 has a pointer 127 
+PASS Not throw: ISO-8859-6 has a pointer 128 
+PASS Not throw: ISO-8859-6 has a pointer 129 
+PASS Not throw: ISO-8859-6 has a pointer 130 
+PASS Not throw: ISO-8859-6 has a pointer 131 
+PASS Not throw: ISO-8859-6 has a pointer 132 
+PASS Not throw: ISO-8859-6 has a pointer 133 
+PASS Not throw: ISO-8859-6 has a pointer 134 
+PASS Not throw: ISO-8859-6 has a pointer 135 
+PASS Not throw: ISO-8859-6 has a pointer 136 
+PASS Not throw: ISO-8859-6 has a pointer 137 
+PASS Not throw: ISO-8859-6 has a pointer 138 
+PASS Not throw: ISO-8859-6 has a pointer 139 
+PASS Not throw: ISO-8859-6 has a pointer 140 
+PASS Not throw: ISO-8859-6 has a pointer 141 
+PASS Not throw: ISO-8859-6 has a pointer 142 
+PASS Not throw: ISO-8859-6 has a pointer 143 
+PASS Not throw: ISO-8859-6 has a pointer 144 
+PASS Not throw: ISO-8859-6 has a pointer 145 
+PASS Not throw: ISO-8859-6 has a pointer 146 
+PASS Not throw: ISO-8859-6 has a pointer 147 
+PASS Not throw: ISO-8859-6 has a pointer 148 
+PASS Not throw: ISO-8859-6 has a pointer 149 
+PASS Not throw: ISO-8859-6 has a pointer 150 
+PASS Not throw: ISO-8859-6 has a pointer 151 
+PASS Not throw: ISO-8859-6 has a pointer 152 
+PASS Not throw: ISO-8859-6 has a pointer 153 
+PASS Not throw: ISO-8859-6 has a pointer 154 
+PASS Not throw: ISO-8859-6 has a pointer 155 
+PASS Not throw: ISO-8859-6 has a pointer 156 
+PASS Not throw: ISO-8859-6 has a pointer 157 
+PASS Not throw: ISO-8859-6 has a pointer 158 
+PASS Not throw: ISO-8859-6 has a pointer 159 
+PASS Not throw: ISO-8859-6 has a pointer 160 
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 161 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 162 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 163 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-6 has a pointer 164 
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 165 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 166 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 167 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 168 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 169 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 170 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 171 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-6 has a pointer 172 
+PASS Not throw: ISO-8859-6 has a pointer 173 
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 174 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 175 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 176 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 177 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 178 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 179 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 180 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 181 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 182 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 183 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 184 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 185 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 186 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-6 has a pointer 187 
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 188 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 189 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 190 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-6 has a pointer 191 
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 192 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-6 has a pointer 193 
+PASS Not throw: ISO-8859-6 has a pointer 194 
+PASS Not throw: ISO-8859-6 has a pointer 195 
+PASS Not throw: ISO-8859-6 has a pointer 196 
+PASS Not throw: ISO-8859-6 has a pointer 197 
+PASS Not throw: ISO-8859-6 has a pointer 198 
+PASS Not throw: ISO-8859-6 has a pointer 199 
+PASS Not throw: ISO-8859-6 has a pointer 200 
+PASS Not throw: ISO-8859-6 has a pointer 201 
+PASS Not throw: ISO-8859-6 has a pointer 202 
+PASS Not throw: ISO-8859-6 has a pointer 203 
+PASS Not throw: ISO-8859-6 has a pointer 204 
+PASS Not throw: ISO-8859-6 has a pointer 205 
+PASS Not throw: ISO-8859-6 has a pointer 206 
+PASS Not throw: ISO-8859-6 has a pointer 207 
+PASS Not throw: ISO-8859-6 has a pointer 208 
+PASS Not throw: ISO-8859-6 has a pointer 209 
+PASS Not throw: ISO-8859-6 has a pointer 210 
+PASS Not throw: ISO-8859-6 has a pointer 211 
+PASS Not throw: ISO-8859-6 has a pointer 212 
+PASS Not throw: ISO-8859-6 has a pointer 213 
+PASS Not throw: ISO-8859-6 has a pointer 214 
+PASS Not throw: ISO-8859-6 has a pointer 215 
+PASS Not throw: ISO-8859-6 has a pointer 216 
+PASS Not throw: ISO-8859-6 has a pointer 217 
+PASS Not throw: ISO-8859-6 has a pointer 218 
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 219 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 220 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 221 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 222 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 223 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-6 has a pointer 224 
+PASS Not throw: ISO-8859-6 has a pointer 225 
+PASS Not throw: ISO-8859-6 has a pointer 226 
+PASS Not throw: ISO-8859-6 has a pointer 227 
+PASS Not throw: ISO-8859-6 has a pointer 228 
+PASS Not throw: ISO-8859-6 has a pointer 229 
+PASS Not throw: ISO-8859-6 has a pointer 230 
+PASS Not throw: ISO-8859-6 has a pointer 231 
+PASS Not throw: ISO-8859-6 has a pointer 232 
+PASS Not throw: ISO-8859-6 has a pointer 233 
+PASS Not throw: ISO-8859-6 has a pointer 234 
+PASS Not throw: ISO-8859-6 has a pointer 235 
+PASS Not throw: ISO-8859-6 has a pointer 236 
+PASS Not throw: ISO-8859-6 has a pointer 237 
+PASS Not throw: ISO-8859-6 has a pointer 238 
+PASS Not throw: ISO-8859-6 has a pointer 239 
+PASS Not throw: ISO-8859-6 has a pointer 240 
+PASS Not throw: ISO-8859-6 has a pointer 241 
+PASS Not throw: ISO-8859-6 has a pointer 242 
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 243 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 244 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 245 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 246 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 247 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 248 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 249 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 250 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 251 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 252 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 253 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 254 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-6 doesn't have a pointer 255 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-7 has a pointer 0 
+PASS Not throw: ISO-8859-7 has a pointer 1 
+PASS Not throw: ISO-8859-7 has a pointer 2 
+PASS Not throw: ISO-8859-7 has a pointer 3 
+PASS Not throw: ISO-8859-7 has a pointer 4 
+PASS Not throw: ISO-8859-7 has a pointer 5 
+PASS Not throw: ISO-8859-7 has a pointer 6 
+PASS Not throw: ISO-8859-7 has a pointer 7 
+PASS Not throw: ISO-8859-7 has a pointer 8 
+PASS Not throw: ISO-8859-7 has a pointer 9 
+PASS Not throw: ISO-8859-7 has a pointer 10 
+PASS Not throw: ISO-8859-7 has a pointer 11 
+PASS Not throw: ISO-8859-7 has a pointer 12 
+PASS Not throw: ISO-8859-7 has a pointer 13 
+PASS Not throw: ISO-8859-7 has a pointer 14 
+PASS Not throw: ISO-8859-7 has a pointer 15 
+PASS Not throw: ISO-8859-7 has a pointer 16 
+PASS Not throw: ISO-8859-7 has a pointer 17 
+PASS Not throw: ISO-8859-7 has a pointer 18 
+PASS Not throw: ISO-8859-7 has a pointer 19 
+PASS Not throw: ISO-8859-7 has a pointer 20 
+PASS Not throw: ISO-8859-7 has a pointer 21 
+PASS Not throw: ISO-8859-7 has a pointer 22 
+PASS Not throw: ISO-8859-7 has a pointer 23 
+PASS Not throw: ISO-8859-7 has a pointer 24 
+PASS Not throw: ISO-8859-7 has a pointer 25 
+PASS Not throw: ISO-8859-7 has a pointer 26 
+PASS Not throw: ISO-8859-7 has a pointer 27 
+PASS Not throw: ISO-8859-7 has a pointer 28 
+PASS Not throw: ISO-8859-7 has a pointer 29 
+PASS Not throw: ISO-8859-7 has a pointer 30 
+PASS Not throw: ISO-8859-7 has a pointer 31 
+PASS Not throw: ISO-8859-7 has a pointer 32 
+PASS Not throw: ISO-8859-7 has a pointer 33 
+PASS Not throw: ISO-8859-7 has a pointer 34 
+PASS Not throw: ISO-8859-7 has a pointer 35 
+PASS Not throw: ISO-8859-7 has a pointer 36 
+PASS Not throw: ISO-8859-7 has a pointer 37 
+PASS Not throw: ISO-8859-7 has a pointer 38 
+PASS Not throw: ISO-8859-7 has a pointer 39 
+PASS Not throw: ISO-8859-7 has a pointer 40 
+PASS Not throw: ISO-8859-7 has a pointer 41 
+PASS Not throw: ISO-8859-7 has a pointer 42 
+PASS Not throw: ISO-8859-7 has a pointer 43 
+PASS Not throw: ISO-8859-7 has a pointer 44 
+PASS Not throw: ISO-8859-7 has a pointer 45 
+PASS Not throw: ISO-8859-7 has a pointer 46 
+PASS Not throw: ISO-8859-7 has a pointer 47 
+PASS Not throw: ISO-8859-7 has a pointer 48 
+PASS Not throw: ISO-8859-7 has a pointer 49 
+PASS Not throw: ISO-8859-7 has a pointer 50 
+PASS Not throw: ISO-8859-7 has a pointer 51 
+PASS Not throw: ISO-8859-7 has a pointer 52 
+PASS Not throw: ISO-8859-7 has a pointer 53 
+PASS Not throw: ISO-8859-7 has a pointer 54 
+PASS Not throw: ISO-8859-7 has a pointer 55 
+PASS Not throw: ISO-8859-7 has a pointer 56 
+PASS Not throw: ISO-8859-7 has a pointer 57 
+PASS Not throw: ISO-8859-7 has a pointer 58 
+PASS Not throw: ISO-8859-7 has a pointer 59 
+PASS Not throw: ISO-8859-7 has a pointer 60 
+PASS Not throw: ISO-8859-7 has a pointer 61 
+PASS Not throw: ISO-8859-7 has a pointer 62 
+PASS Not throw: ISO-8859-7 has a pointer 63 
+PASS Not throw: ISO-8859-7 has a pointer 64 
+PASS Not throw: ISO-8859-7 has a pointer 65 
+PASS Not throw: ISO-8859-7 has a pointer 66 
+PASS Not throw: ISO-8859-7 has a pointer 67 
+PASS Not throw: ISO-8859-7 has a pointer 68 
+PASS Not throw: ISO-8859-7 has a pointer 69 
+PASS Not throw: ISO-8859-7 has a pointer 70 
+PASS Not throw: ISO-8859-7 has a pointer 71 
+PASS Not throw: ISO-8859-7 has a pointer 72 
+PASS Not throw: ISO-8859-7 has a pointer 73 
+PASS Not throw: ISO-8859-7 has a pointer 74 
+PASS Not throw: ISO-8859-7 has a pointer 75 
+PASS Not throw: ISO-8859-7 has a pointer 76 
+PASS Not throw: ISO-8859-7 has a pointer 77 
+PASS Not throw: ISO-8859-7 has a pointer 78 
+PASS Not throw: ISO-8859-7 has a pointer 79 
+PASS Not throw: ISO-8859-7 has a pointer 80 
+PASS Not throw: ISO-8859-7 has a pointer 81 
+PASS Not throw: ISO-8859-7 has a pointer 82 
+PASS Not throw: ISO-8859-7 has a pointer 83 
+PASS Not throw: ISO-8859-7 has a pointer 84 
+PASS Not throw: ISO-8859-7 has a pointer 85 
+PASS Not throw: ISO-8859-7 has a pointer 86 
+PASS Not throw: ISO-8859-7 has a pointer 87 
+PASS Not throw: ISO-8859-7 has a pointer 88 
+PASS Not throw: ISO-8859-7 has a pointer 89 
+PASS Not throw: ISO-8859-7 has a pointer 90 
+PASS Not throw: ISO-8859-7 has a pointer 91 
+PASS Not throw: ISO-8859-7 has a pointer 92 
+PASS Not throw: ISO-8859-7 has a pointer 93 
+PASS Not throw: ISO-8859-7 has a pointer 94 
+PASS Not throw: ISO-8859-7 has a pointer 95 
+PASS Not throw: ISO-8859-7 has a pointer 96 
+PASS Not throw: ISO-8859-7 has a pointer 97 
+PASS Not throw: ISO-8859-7 has a pointer 98 
+PASS Not throw: ISO-8859-7 has a pointer 99 
+PASS Not throw: ISO-8859-7 has a pointer 100 
+PASS Not throw: ISO-8859-7 has a pointer 101 
+PASS Not throw: ISO-8859-7 has a pointer 102 
+PASS Not throw: ISO-8859-7 has a pointer 103 
+PASS Not throw: ISO-8859-7 has a pointer 104 
+PASS Not throw: ISO-8859-7 has a pointer 105 
+PASS Not throw: ISO-8859-7 has a pointer 106 
+PASS Not throw: ISO-8859-7 has a pointer 107 
+PASS Not throw: ISO-8859-7 has a pointer 108 
+PASS Not throw: ISO-8859-7 has a pointer 109 
+PASS Not throw: ISO-8859-7 has a pointer 110 
+PASS Not throw: ISO-8859-7 has a pointer 111 
+PASS Not throw: ISO-8859-7 has a pointer 112 
+PASS Not throw: ISO-8859-7 has a pointer 113 
+PASS Not throw: ISO-8859-7 has a pointer 114 
+PASS Not throw: ISO-8859-7 has a pointer 115 
+PASS Not throw: ISO-8859-7 has a pointer 116 
+PASS Not throw: ISO-8859-7 has a pointer 117 
+PASS Not throw: ISO-8859-7 has a pointer 118 
+PASS Not throw: ISO-8859-7 has a pointer 119 
+PASS Not throw: ISO-8859-7 has a pointer 120 
+PASS Not throw: ISO-8859-7 has a pointer 121 
+PASS Not throw: ISO-8859-7 has a pointer 122 
+PASS Not throw: ISO-8859-7 has a pointer 123 
+PASS Not throw: ISO-8859-7 has a pointer 124 
+PASS Not throw: ISO-8859-7 has a pointer 125 
+PASS Not throw: ISO-8859-7 has a pointer 126 
+PASS Not throw: ISO-8859-7 has a pointer 127 
+PASS Not throw: ISO-8859-7 has a pointer 128 
+PASS Not throw: ISO-8859-7 has a pointer 129 
+PASS Not throw: ISO-8859-7 has a pointer 130 
+PASS Not throw: ISO-8859-7 has a pointer 131 
+PASS Not throw: ISO-8859-7 has a pointer 132 
+PASS Not throw: ISO-8859-7 has a pointer 133 
+PASS Not throw: ISO-8859-7 has a pointer 134 
+PASS Not throw: ISO-8859-7 has a pointer 135 
+PASS Not throw: ISO-8859-7 has a pointer 136 
+PASS Not throw: ISO-8859-7 has a pointer 137 
+PASS Not throw: ISO-8859-7 has a pointer 138 
+PASS Not throw: ISO-8859-7 has a pointer 139 
+PASS Not throw: ISO-8859-7 has a pointer 140 
+PASS Not throw: ISO-8859-7 has a pointer 141 
+PASS Not throw: ISO-8859-7 has a pointer 142 
+PASS Not throw: ISO-8859-7 has a pointer 143 
+PASS Not throw: ISO-8859-7 has a pointer 144 
+PASS Not throw: ISO-8859-7 has a pointer 145 
+PASS Not throw: ISO-8859-7 has a pointer 146 
+PASS Not throw: ISO-8859-7 has a pointer 147 
+PASS Not throw: ISO-8859-7 has a pointer 148 
+PASS Not throw: ISO-8859-7 has a pointer 149 
+PASS Not throw: ISO-8859-7 has a pointer 150 
+PASS Not throw: ISO-8859-7 has a pointer 151 
+PASS Not throw: ISO-8859-7 has a pointer 152 
+PASS Not throw: ISO-8859-7 has a pointer 153 
+PASS Not throw: ISO-8859-7 has a pointer 154 
+PASS Not throw: ISO-8859-7 has a pointer 155 
+PASS Not throw: ISO-8859-7 has a pointer 156 
+PASS Not throw: ISO-8859-7 has a pointer 157 
+PASS Not throw: ISO-8859-7 has a pointer 158 
+PASS Not throw: ISO-8859-7 has a pointer 159 
+PASS Not throw: ISO-8859-7 has a pointer 160 
+PASS Not throw: ISO-8859-7 has a pointer 161 
+PASS Not throw: ISO-8859-7 has a pointer 162 
+PASS Not throw: ISO-8859-7 has a pointer 163 
+PASS Not throw: ISO-8859-7 has a pointer 164 
+PASS Not throw: ISO-8859-7 has a pointer 165 
+PASS Not throw: ISO-8859-7 has a pointer 166 
+PASS Not throw: ISO-8859-7 has a pointer 167 
+PASS Not throw: ISO-8859-7 has a pointer 168 
+PASS Not throw: ISO-8859-7 has a pointer 169 
+PASS Not throw: ISO-8859-7 has a pointer 170 
+PASS Not throw: ISO-8859-7 has a pointer 171 
+PASS Not throw: ISO-8859-7 has a pointer 172 
+PASS Not throw: ISO-8859-7 has a pointer 173 
+FAIL Throw due to fatal flag: ISO-8859-7 doesn't have a pointer 174 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-7 has a pointer 175 
+PASS Not throw: ISO-8859-7 has a pointer 176 
+PASS Not throw: ISO-8859-7 has a pointer 177 
+PASS Not throw: ISO-8859-7 has a pointer 178 
+PASS Not throw: ISO-8859-7 has a pointer 179 
+PASS Not throw: ISO-8859-7 has a pointer 180 
+PASS Not throw: ISO-8859-7 has a pointer 181 
+PASS Not throw: ISO-8859-7 has a pointer 182 
+PASS Not throw: ISO-8859-7 has a pointer 183 
+PASS Not throw: ISO-8859-7 has a pointer 184 
+PASS Not throw: ISO-8859-7 has a pointer 185 
+PASS Not throw: ISO-8859-7 has a pointer 186 
+PASS Not throw: ISO-8859-7 has a pointer 187 
+PASS Not throw: ISO-8859-7 has a pointer 188 
+PASS Not throw: ISO-8859-7 has a pointer 189 
+PASS Not throw: ISO-8859-7 has a pointer 190 
+PASS Not throw: ISO-8859-7 has a pointer 191 
+PASS Not throw: ISO-8859-7 has a pointer 192 
+PASS Not throw: ISO-8859-7 has a pointer 193 
+PASS Not throw: ISO-8859-7 has a pointer 194 
+PASS Not throw: ISO-8859-7 has a pointer 195 
+PASS Not throw: ISO-8859-7 has a pointer 196 
+PASS Not throw: ISO-8859-7 has a pointer 197 
+PASS Not throw: ISO-8859-7 has a pointer 198 
+PASS Not throw: ISO-8859-7 has a pointer 199 
+PASS Not throw: ISO-8859-7 has a pointer 200 
+PASS Not throw: ISO-8859-7 has a pointer 201 
+PASS Not throw: ISO-8859-7 has a pointer 202 
+PASS Not throw: ISO-8859-7 has a pointer 203 
+PASS Not throw: ISO-8859-7 has a pointer 204 
+PASS Not throw: ISO-8859-7 has a pointer 205 
+PASS Not throw: ISO-8859-7 has a pointer 206 
+PASS Not throw: ISO-8859-7 has a pointer 207 
+PASS Not throw: ISO-8859-7 has a pointer 208 
+PASS Not throw: ISO-8859-7 has a pointer 209 
+FAIL Throw due to fatal flag: ISO-8859-7 doesn't have a pointer 210 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-7 has a pointer 211 
+PASS Not throw: ISO-8859-7 has a pointer 212 
+PASS Not throw: ISO-8859-7 has a pointer 213 
+PASS Not throw: ISO-8859-7 has a pointer 214 
+PASS Not throw: ISO-8859-7 has a pointer 215 
+PASS Not throw: ISO-8859-7 has a pointer 216 
+PASS Not throw: ISO-8859-7 has a pointer 217 
+PASS Not throw: ISO-8859-7 has a pointer 218 
+PASS Not throw: ISO-8859-7 has a pointer 219 
+PASS Not throw: ISO-8859-7 has a pointer 220 
+PASS Not throw: ISO-8859-7 has a pointer 221 
+PASS Not throw: ISO-8859-7 has a pointer 222 
+PASS Not throw: ISO-8859-7 has a pointer 223 
+PASS Not throw: ISO-8859-7 has a pointer 224 
+PASS Not throw: ISO-8859-7 has a pointer 225 
+PASS Not throw: ISO-8859-7 has a pointer 226 
+PASS Not throw: ISO-8859-7 has a pointer 227 
+PASS Not throw: ISO-8859-7 has a pointer 228 
+PASS Not throw: ISO-8859-7 has a pointer 229 
+PASS Not throw: ISO-8859-7 has a pointer 230 
+PASS Not throw: ISO-8859-7 has a pointer 231 
+PASS Not throw: ISO-8859-7 has a pointer 232 
+PASS Not throw: ISO-8859-7 has a pointer 233 
+PASS Not throw: ISO-8859-7 has a pointer 234 
+PASS Not throw: ISO-8859-7 has a pointer 235 
+PASS Not throw: ISO-8859-7 has a pointer 236 
+PASS Not throw: ISO-8859-7 has a pointer 237 
+PASS Not throw: ISO-8859-7 has a pointer 238 
+PASS Not throw: ISO-8859-7 has a pointer 239 
+PASS Not throw: ISO-8859-7 has a pointer 240 
+PASS Not throw: ISO-8859-7 has a pointer 241 
+PASS Not throw: ISO-8859-7 has a pointer 242 
+PASS Not throw: ISO-8859-7 has a pointer 243 
+PASS Not throw: ISO-8859-7 has a pointer 244 
+PASS Not throw: ISO-8859-7 has a pointer 245 
+PASS Not throw: ISO-8859-7 has a pointer 246 
+PASS Not throw: ISO-8859-7 has a pointer 247 
+PASS Not throw: ISO-8859-7 has a pointer 248 
+PASS Not throw: ISO-8859-7 has a pointer 249 
+PASS Not throw: ISO-8859-7 has a pointer 250 
+PASS Not throw: ISO-8859-7 has a pointer 251 
+PASS Not throw: ISO-8859-7 has a pointer 252 
+PASS Not throw: ISO-8859-7 has a pointer 253 
+PASS Not throw: ISO-8859-7 has a pointer 254 
+FAIL Throw due to fatal flag: ISO-8859-7 doesn't have a pointer 255 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8 has a pointer 0 
+PASS Not throw: ISO-8859-8 has a pointer 1 
+PASS Not throw: ISO-8859-8 has a pointer 2 
+PASS Not throw: ISO-8859-8 has a pointer 3 
+PASS Not throw: ISO-8859-8 has a pointer 4 
+PASS Not throw: ISO-8859-8 has a pointer 5 
+PASS Not throw: ISO-8859-8 has a pointer 6 
+PASS Not throw: ISO-8859-8 has a pointer 7 
+PASS Not throw: ISO-8859-8 has a pointer 8 
+PASS Not throw: ISO-8859-8 has a pointer 9 
+PASS Not throw: ISO-8859-8 has a pointer 10 
+PASS Not throw: ISO-8859-8 has a pointer 11 
+PASS Not throw: ISO-8859-8 has a pointer 12 
+PASS Not throw: ISO-8859-8 has a pointer 13 
+PASS Not throw: ISO-8859-8 has a pointer 14 
+PASS Not throw: ISO-8859-8 has a pointer 15 
+PASS Not throw: ISO-8859-8 has a pointer 16 
+PASS Not throw: ISO-8859-8 has a pointer 17 
+PASS Not throw: ISO-8859-8 has a pointer 18 
+PASS Not throw: ISO-8859-8 has a pointer 19 
+PASS Not throw: ISO-8859-8 has a pointer 20 
+PASS Not throw: ISO-8859-8 has a pointer 21 
+PASS Not throw: ISO-8859-8 has a pointer 22 
+PASS Not throw: ISO-8859-8 has a pointer 23 
+PASS Not throw: ISO-8859-8 has a pointer 24 
+PASS Not throw: ISO-8859-8 has a pointer 25 
+PASS Not throw: ISO-8859-8 has a pointer 26 
+PASS Not throw: ISO-8859-8 has a pointer 27 
+PASS Not throw: ISO-8859-8 has a pointer 28 
+PASS Not throw: ISO-8859-8 has a pointer 29 
+PASS Not throw: ISO-8859-8 has a pointer 30 
+PASS Not throw: ISO-8859-8 has a pointer 31 
+PASS Not throw: ISO-8859-8 has a pointer 32 
+PASS Not throw: ISO-8859-8 has a pointer 33 
+PASS Not throw: ISO-8859-8 has a pointer 34 
+PASS Not throw: ISO-8859-8 has a pointer 35 
+PASS Not throw: ISO-8859-8 has a pointer 36 
+PASS Not throw: ISO-8859-8 has a pointer 37 
+PASS Not throw: ISO-8859-8 has a pointer 38 
+PASS Not throw: ISO-8859-8 has a pointer 39 
+PASS Not throw: ISO-8859-8 has a pointer 40 
+PASS Not throw: ISO-8859-8 has a pointer 41 
+PASS Not throw: ISO-8859-8 has a pointer 42 
+PASS Not throw: ISO-8859-8 has a pointer 43 
+PASS Not throw: ISO-8859-8 has a pointer 44 
+PASS Not throw: ISO-8859-8 has a pointer 45 
+PASS Not throw: ISO-8859-8 has a pointer 46 
+PASS Not throw: ISO-8859-8 has a pointer 47 
+PASS Not throw: ISO-8859-8 has a pointer 48 
+PASS Not throw: ISO-8859-8 has a pointer 49 
+PASS Not throw: ISO-8859-8 has a pointer 50 
+PASS Not throw: ISO-8859-8 has a pointer 51 
+PASS Not throw: ISO-8859-8 has a pointer 52 
+PASS Not throw: ISO-8859-8 has a pointer 53 
+PASS Not throw: ISO-8859-8 has a pointer 54 
+PASS Not throw: ISO-8859-8 has a pointer 55 
+PASS Not throw: ISO-8859-8 has a pointer 56 
+PASS Not throw: ISO-8859-8 has a pointer 57 
+PASS Not throw: ISO-8859-8 has a pointer 58 
+PASS Not throw: ISO-8859-8 has a pointer 59 
+PASS Not throw: ISO-8859-8 has a pointer 60 
+PASS Not throw: ISO-8859-8 has a pointer 61 
+PASS Not throw: ISO-8859-8 has a pointer 62 
+PASS Not throw: ISO-8859-8 has a pointer 63 
+PASS Not throw: ISO-8859-8 has a pointer 64 
+PASS Not throw: ISO-8859-8 has a pointer 65 
+PASS Not throw: ISO-8859-8 has a pointer 66 
+PASS Not throw: ISO-8859-8 has a pointer 67 
+PASS Not throw: ISO-8859-8 has a pointer 68 
+PASS Not throw: ISO-8859-8 has a pointer 69 
+PASS Not throw: ISO-8859-8 has a pointer 70 
+PASS Not throw: ISO-8859-8 has a pointer 71 
+PASS Not throw: ISO-8859-8 has a pointer 72 
+PASS Not throw: ISO-8859-8 has a pointer 73 
+PASS Not throw: ISO-8859-8 has a pointer 74 
+PASS Not throw: ISO-8859-8 has a pointer 75 
+PASS Not throw: ISO-8859-8 has a pointer 76 
+PASS Not throw: ISO-8859-8 has a pointer 77 
+PASS Not throw: ISO-8859-8 has a pointer 78 
+PASS Not throw: ISO-8859-8 has a pointer 79 
+PASS Not throw: ISO-8859-8 has a pointer 80 
+PASS Not throw: ISO-8859-8 has a pointer 81 
+PASS Not throw: ISO-8859-8 has a pointer 82 
+PASS Not throw: ISO-8859-8 has a pointer 83 
+PASS Not throw: ISO-8859-8 has a pointer 84 
+PASS Not throw: ISO-8859-8 has a pointer 85 
+PASS Not throw: ISO-8859-8 has a pointer 86 
+PASS Not throw: ISO-8859-8 has a pointer 87 
+PASS Not throw: ISO-8859-8 has a pointer 88 
+PASS Not throw: ISO-8859-8 has a pointer 89 
+PASS Not throw: ISO-8859-8 has a pointer 90 
+PASS Not throw: ISO-8859-8 has a pointer 91 
+PASS Not throw: ISO-8859-8 has a pointer 92 
+PASS Not throw: ISO-8859-8 has a pointer 93 
+PASS Not throw: ISO-8859-8 has a pointer 94 
+PASS Not throw: ISO-8859-8 has a pointer 95 
+PASS Not throw: ISO-8859-8 has a pointer 96 
+PASS Not throw: ISO-8859-8 has a pointer 97 
+PASS Not throw: ISO-8859-8 has a pointer 98 
+PASS Not throw: ISO-8859-8 has a pointer 99 
+PASS Not throw: ISO-8859-8 has a pointer 100 
+PASS Not throw: ISO-8859-8 has a pointer 101 
+PASS Not throw: ISO-8859-8 has a pointer 102 
+PASS Not throw: ISO-8859-8 has a pointer 103 
+PASS Not throw: ISO-8859-8 has a pointer 104 
+PASS Not throw: ISO-8859-8 has a pointer 105 
+PASS Not throw: ISO-8859-8 has a pointer 106 
+PASS Not throw: ISO-8859-8 has a pointer 107 
+PASS Not throw: ISO-8859-8 has a pointer 108 
+PASS Not throw: ISO-8859-8 has a pointer 109 
+PASS Not throw: ISO-8859-8 has a pointer 110 
+PASS Not throw: ISO-8859-8 has a pointer 111 
+PASS Not throw: ISO-8859-8 has a pointer 112 
+PASS Not throw: ISO-8859-8 has a pointer 113 
+PASS Not throw: ISO-8859-8 has a pointer 114 
+PASS Not throw: ISO-8859-8 has a pointer 115 
+PASS Not throw: ISO-8859-8 has a pointer 116 
+PASS Not throw: ISO-8859-8 has a pointer 117 
+PASS Not throw: ISO-8859-8 has a pointer 118 
+PASS Not throw: ISO-8859-8 has a pointer 119 
+PASS Not throw: ISO-8859-8 has a pointer 120 
+PASS Not throw: ISO-8859-8 has a pointer 121 
+PASS Not throw: ISO-8859-8 has a pointer 122 
+PASS Not throw: ISO-8859-8 has a pointer 123 
+PASS Not throw: ISO-8859-8 has a pointer 124 
+PASS Not throw: ISO-8859-8 has a pointer 125 
+PASS Not throw: ISO-8859-8 has a pointer 126 
+PASS Not throw: ISO-8859-8 has a pointer 127 
+PASS Not throw: ISO-8859-8 has a pointer 128 
+PASS Not throw: ISO-8859-8 has a pointer 129 
+PASS Not throw: ISO-8859-8 has a pointer 130 
+PASS Not throw: ISO-8859-8 has a pointer 131 
+PASS Not throw: ISO-8859-8 has a pointer 132 
+PASS Not throw: ISO-8859-8 has a pointer 133 
+PASS Not throw: ISO-8859-8 has a pointer 134 
+PASS Not throw: ISO-8859-8 has a pointer 135 
+PASS Not throw: ISO-8859-8 has a pointer 136 
+PASS Not throw: ISO-8859-8 has a pointer 137 
+PASS Not throw: ISO-8859-8 has a pointer 138 
+PASS Not throw: ISO-8859-8 has a pointer 139 
+PASS Not throw: ISO-8859-8 has a pointer 140 
+PASS Not throw: ISO-8859-8 has a pointer 141 
+PASS Not throw: ISO-8859-8 has a pointer 142 
+PASS Not throw: ISO-8859-8 has a pointer 143 
+PASS Not throw: ISO-8859-8 has a pointer 144 
+PASS Not throw: ISO-8859-8 has a pointer 145 
+PASS Not throw: ISO-8859-8 has a pointer 146 
+PASS Not throw: ISO-8859-8 has a pointer 147 
+PASS Not throw: ISO-8859-8 has a pointer 148 
+PASS Not throw: ISO-8859-8 has a pointer 149 
+PASS Not throw: ISO-8859-8 has a pointer 150 
+PASS Not throw: ISO-8859-8 has a pointer 151 
+PASS Not throw: ISO-8859-8 has a pointer 152 
+PASS Not throw: ISO-8859-8 has a pointer 153 
+PASS Not throw: ISO-8859-8 has a pointer 154 
+PASS Not throw: ISO-8859-8 has a pointer 155 
+PASS Not throw: ISO-8859-8 has a pointer 156 
+PASS Not throw: ISO-8859-8 has a pointer 157 
+PASS Not throw: ISO-8859-8 has a pointer 158 
+PASS Not throw: ISO-8859-8 has a pointer 159 
+PASS Not throw: ISO-8859-8 has a pointer 160 
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 161 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8 has a pointer 162 
+PASS Not throw: ISO-8859-8 has a pointer 163 
+PASS Not throw: ISO-8859-8 has a pointer 164 
+PASS Not throw: ISO-8859-8 has a pointer 165 
+PASS Not throw: ISO-8859-8 has a pointer 166 
+PASS Not throw: ISO-8859-8 has a pointer 167 
+PASS Not throw: ISO-8859-8 has a pointer 168 
+PASS Not throw: ISO-8859-8 has a pointer 169 
+PASS Not throw: ISO-8859-8 has a pointer 170 
+PASS Not throw: ISO-8859-8 has a pointer 171 
+PASS Not throw: ISO-8859-8 has a pointer 172 
+PASS Not throw: ISO-8859-8 has a pointer 173 
+PASS Not throw: ISO-8859-8 has a pointer 174 
+PASS Not throw: ISO-8859-8 has a pointer 175 
+PASS Not throw: ISO-8859-8 has a pointer 176 
+PASS Not throw: ISO-8859-8 has a pointer 177 
+PASS Not throw: ISO-8859-8 has a pointer 178 
+PASS Not throw: ISO-8859-8 has a pointer 179 
+PASS Not throw: ISO-8859-8 has a pointer 180 
+PASS Not throw: ISO-8859-8 has a pointer 181 
+PASS Not throw: ISO-8859-8 has a pointer 182 
+PASS Not throw: ISO-8859-8 has a pointer 183 
+PASS Not throw: ISO-8859-8 has a pointer 184 
+PASS Not throw: ISO-8859-8 has a pointer 185 
+PASS Not throw: ISO-8859-8 has a pointer 186 
+PASS Not throw: ISO-8859-8 has a pointer 187 
+PASS Not throw: ISO-8859-8 has a pointer 188 
+PASS Not throw: ISO-8859-8 has a pointer 189 
+PASS Not throw: ISO-8859-8 has a pointer 190 
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 191 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 192 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 193 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 194 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 195 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 196 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 197 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 198 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 199 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 200 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 201 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 202 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 203 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 204 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 205 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 206 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 207 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 208 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 209 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 210 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 211 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 212 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 213 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 214 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 215 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 216 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 217 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 218 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 219 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 220 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 221 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 222 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8 has a pointer 223 
+PASS Not throw: ISO-8859-8 has a pointer 224 
+PASS Not throw: ISO-8859-8 has a pointer 225 
+PASS Not throw: ISO-8859-8 has a pointer 226 
+PASS Not throw: ISO-8859-8 has a pointer 227 
+PASS Not throw: ISO-8859-8 has a pointer 228 
+PASS Not throw: ISO-8859-8 has a pointer 229 
+PASS Not throw: ISO-8859-8 has a pointer 230 
+PASS Not throw: ISO-8859-8 has a pointer 231 
+PASS Not throw: ISO-8859-8 has a pointer 232 
+PASS Not throw: ISO-8859-8 has a pointer 233 
+PASS Not throw: ISO-8859-8 has a pointer 234 
+PASS Not throw: ISO-8859-8 has a pointer 235 
+PASS Not throw: ISO-8859-8 has a pointer 236 
+PASS Not throw: ISO-8859-8 has a pointer 237 
+PASS Not throw: ISO-8859-8 has a pointer 238 
+PASS Not throw: ISO-8859-8 has a pointer 239 
+PASS Not throw: ISO-8859-8 has a pointer 240 
+PASS Not throw: ISO-8859-8 has a pointer 241 
+PASS Not throw: ISO-8859-8 has a pointer 242 
+PASS Not throw: ISO-8859-8 has a pointer 243 
+PASS Not throw: ISO-8859-8 has a pointer 244 
+PASS Not throw: ISO-8859-8 has a pointer 245 
+PASS Not throw: ISO-8859-8 has a pointer 246 
+PASS Not throw: ISO-8859-8 has a pointer 247 
+PASS Not throw: ISO-8859-8 has a pointer 248 
+PASS Not throw: ISO-8859-8 has a pointer 249 
+PASS Not throw: ISO-8859-8 has a pointer 250 
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 251 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 252 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8 has a pointer 253 
+PASS Not throw: ISO-8859-8 has a pointer 254 
+FAIL Throw due to fatal flag: ISO-8859-8 doesn't have a pointer 255 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8-I has a pointer 0 
+PASS Not throw: ISO-8859-8-I has a pointer 1 
+PASS Not throw: ISO-8859-8-I has a pointer 2 
+PASS Not throw: ISO-8859-8-I has a pointer 3 
+PASS Not throw: ISO-8859-8-I has a pointer 4 
+PASS Not throw: ISO-8859-8-I has a pointer 5 
+PASS Not throw: ISO-8859-8-I has a pointer 6 
+PASS Not throw: ISO-8859-8-I has a pointer 7 
+PASS Not throw: ISO-8859-8-I has a pointer 8 
+PASS Not throw: ISO-8859-8-I has a pointer 9 
+PASS Not throw: ISO-8859-8-I has a pointer 10 
+PASS Not throw: ISO-8859-8-I has a pointer 11 
+PASS Not throw: ISO-8859-8-I has a pointer 12 
+PASS Not throw: ISO-8859-8-I has a pointer 13 
+PASS Not throw: ISO-8859-8-I has a pointer 14 
+PASS Not throw: ISO-8859-8-I has a pointer 15 
+PASS Not throw: ISO-8859-8-I has a pointer 16 
+PASS Not throw: ISO-8859-8-I has a pointer 17 
+PASS Not throw: ISO-8859-8-I has a pointer 18 
+PASS Not throw: ISO-8859-8-I has a pointer 19 
+PASS Not throw: ISO-8859-8-I has a pointer 20 
+PASS Not throw: ISO-8859-8-I has a pointer 21 
+PASS Not throw: ISO-8859-8-I has a pointer 22 
+PASS Not throw: ISO-8859-8-I has a pointer 23 
+PASS Not throw: ISO-8859-8-I has a pointer 24 
+PASS Not throw: ISO-8859-8-I has a pointer 25 
+PASS Not throw: ISO-8859-8-I has a pointer 26 
+PASS Not throw: ISO-8859-8-I has a pointer 27 
+PASS Not throw: ISO-8859-8-I has a pointer 28 
+PASS Not throw: ISO-8859-8-I has a pointer 29 
+PASS Not throw: ISO-8859-8-I has a pointer 30 
+PASS Not throw: ISO-8859-8-I has a pointer 31 
+PASS Not throw: ISO-8859-8-I has a pointer 32 
+PASS Not throw: ISO-8859-8-I has a pointer 33 
+PASS Not throw: ISO-8859-8-I has a pointer 34 
+PASS Not throw: ISO-8859-8-I has a pointer 35 
+PASS Not throw: ISO-8859-8-I has a pointer 36 
+PASS Not throw: ISO-8859-8-I has a pointer 37 
+PASS Not throw: ISO-8859-8-I has a pointer 38 
+PASS Not throw: ISO-8859-8-I has a pointer 39 
+PASS Not throw: ISO-8859-8-I has a pointer 40 
+PASS Not throw: ISO-8859-8-I has a pointer 41 
+PASS Not throw: ISO-8859-8-I has a pointer 42 
+PASS Not throw: ISO-8859-8-I has a pointer 43 
+PASS Not throw: ISO-8859-8-I has a pointer 44 
+PASS Not throw: ISO-8859-8-I has a pointer 45 
+PASS Not throw: ISO-8859-8-I has a pointer 46 
+PASS Not throw: ISO-8859-8-I has a pointer 47 
+PASS Not throw: ISO-8859-8-I has a pointer 48 
+PASS Not throw: ISO-8859-8-I has a pointer 49 
+PASS Not throw: ISO-8859-8-I has a pointer 50 
+PASS Not throw: ISO-8859-8-I has a pointer 51 
+PASS Not throw: ISO-8859-8-I has a pointer 52 
+PASS Not throw: ISO-8859-8-I has a pointer 53 
+PASS Not throw: ISO-8859-8-I has a pointer 54 
+PASS Not throw: ISO-8859-8-I has a pointer 55 
+PASS Not throw: ISO-8859-8-I has a pointer 56 
+PASS Not throw: ISO-8859-8-I has a pointer 57 
+PASS Not throw: ISO-8859-8-I has a pointer 58 
+PASS Not throw: ISO-8859-8-I has a pointer 59 
+PASS Not throw: ISO-8859-8-I has a pointer 60 
+PASS Not throw: ISO-8859-8-I has a pointer 61 
+PASS Not throw: ISO-8859-8-I has a pointer 62 
+PASS Not throw: ISO-8859-8-I has a pointer 63 
+PASS Not throw: ISO-8859-8-I has a pointer 64 
+PASS Not throw: ISO-8859-8-I has a pointer 65 
+PASS Not throw: ISO-8859-8-I has a pointer 66 
+PASS Not throw: ISO-8859-8-I has a pointer 67 
+PASS Not throw: ISO-8859-8-I has a pointer 68 
+PASS Not throw: ISO-8859-8-I has a pointer 69 
+PASS Not throw: ISO-8859-8-I has a pointer 70 
+PASS Not throw: ISO-8859-8-I has a pointer 71 
+PASS Not throw: ISO-8859-8-I has a pointer 72 
+PASS Not throw: ISO-8859-8-I has a pointer 73 
+PASS Not throw: ISO-8859-8-I has a pointer 74 
+PASS Not throw: ISO-8859-8-I has a pointer 75 
+PASS Not throw: ISO-8859-8-I has a pointer 76 
+PASS Not throw: ISO-8859-8-I has a pointer 77 
+PASS Not throw: ISO-8859-8-I has a pointer 78 
+PASS Not throw: ISO-8859-8-I has a pointer 79 
+PASS Not throw: ISO-8859-8-I has a pointer 80 
+PASS Not throw: ISO-8859-8-I has a pointer 81 
+PASS Not throw: ISO-8859-8-I has a pointer 82 
+PASS Not throw: ISO-8859-8-I has a pointer 83 
+PASS Not throw: ISO-8859-8-I has a pointer 84 
+PASS Not throw: ISO-8859-8-I has a pointer 85 
+PASS Not throw: ISO-8859-8-I has a pointer 86 
+PASS Not throw: ISO-8859-8-I has a pointer 87 
+PASS Not throw: ISO-8859-8-I has a pointer 88 
+PASS Not throw: ISO-8859-8-I has a pointer 89 
+PASS Not throw: ISO-8859-8-I has a pointer 90 
+PASS Not throw: ISO-8859-8-I has a pointer 91 
+PASS Not throw: ISO-8859-8-I has a pointer 92 
+PASS Not throw: ISO-8859-8-I has a pointer 93 
+PASS Not throw: ISO-8859-8-I has a pointer 94 
+PASS Not throw: ISO-8859-8-I has a pointer 95 
+PASS Not throw: ISO-8859-8-I has a pointer 96 
+PASS Not throw: ISO-8859-8-I has a pointer 97 
+PASS Not throw: ISO-8859-8-I has a pointer 98 
+PASS Not throw: ISO-8859-8-I has a pointer 99 
+PASS Not throw: ISO-8859-8-I has a pointer 100 
+PASS Not throw: ISO-8859-8-I has a pointer 101 
+PASS Not throw: ISO-8859-8-I has a pointer 102 
+PASS Not throw: ISO-8859-8-I has a pointer 103 
+PASS Not throw: ISO-8859-8-I has a pointer 104 
+PASS Not throw: ISO-8859-8-I has a pointer 105 
+PASS Not throw: ISO-8859-8-I has a pointer 106 
+PASS Not throw: ISO-8859-8-I has a pointer 107 
+PASS Not throw: ISO-8859-8-I has a pointer 108 
+PASS Not throw: ISO-8859-8-I has a pointer 109 
+PASS Not throw: ISO-8859-8-I has a pointer 110 
+PASS Not throw: ISO-8859-8-I has a pointer 111 
+PASS Not throw: ISO-8859-8-I has a pointer 112 
+PASS Not throw: ISO-8859-8-I has a pointer 113 
+PASS Not throw: ISO-8859-8-I has a pointer 114 
+PASS Not throw: ISO-8859-8-I has a pointer 115 
+PASS Not throw: ISO-8859-8-I has a pointer 116 
+PASS Not throw: ISO-8859-8-I has a pointer 117 
+PASS Not throw: ISO-8859-8-I has a pointer 118 
+PASS Not throw: ISO-8859-8-I has a pointer 119 
+PASS Not throw: ISO-8859-8-I has a pointer 120 
+PASS Not throw: ISO-8859-8-I has a pointer 121 
+PASS Not throw: ISO-8859-8-I has a pointer 122 
+PASS Not throw: ISO-8859-8-I has a pointer 123 
+PASS Not throw: ISO-8859-8-I has a pointer 124 
+PASS Not throw: ISO-8859-8-I has a pointer 125 
+PASS Not throw: ISO-8859-8-I has a pointer 126 
+PASS Not throw: ISO-8859-8-I has a pointer 127 
+PASS Not throw: ISO-8859-8-I has a pointer 128 
+PASS Not throw: ISO-8859-8-I has a pointer 129 
+PASS Not throw: ISO-8859-8-I has a pointer 130 
+PASS Not throw: ISO-8859-8-I has a pointer 131 
+PASS Not throw: ISO-8859-8-I has a pointer 132 
+PASS Not throw: ISO-8859-8-I has a pointer 133 
+PASS Not throw: ISO-8859-8-I has a pointer 134 
+PASS Not throw: ISO-8859-8-I has a pointer 135 
+PASS Not throw: ISO-8859-8-I has a pointer 136 
+PASS Not throw: ISO-8859-8-I has a pointer 137 
+PASS Not throw: ISO-8859-8-I has a pointer 138 
+PASS Not throw: ISO-8859-8-I has a pointer 139 
+PASS Not throw: ISO-8859-8-I has a pointer 140 
+PASS Not throw: ISO-8859-8-I has a pointer 141 
+PASS Not throw: ISO-8859-8-I has a pointer 142 
+PASS Not throw: ISO-8859-8-I has a pointer 143 
+PASS Not throw: ISO-8859-8-I has a pointer 144 
+PASS Not throw: ISO-8859-8-I has a pointer 145 
+PASS Not throw: ISO-8859-8-I has a pointer 146 
+PASS Not throw: ISO-8859-8-I has a pointer 147 
+PASS Not throw: ISO-8859-8-I has a pointer 148 
+PASS Not throw: ISO-8859-8-I has a pointer 149 
+PASS Not throw: ISO-8859-8-I has a pointer 150 
+PASS Not throw: ISO-8859-8-I has a pointer 151 
+PASS Not throw: ISO-8859-8-I has a pointer 152 
+PASS Not throw: ISO-8859-8-I has a pointer 153 
+PASS Not throw: ISO-8859-8-I has a pointer 154 
+PASS Not throw: ISO-8859-8-I has a pointer 155 
+PASS Not throw: ISO-8859-8-I has a pointer 156 
+PASS Not throw: ISO-8859-8-I has a pointer 157 
+PASS Not throw: ISO-8859-8-I has a pointer 158 
+PASS Not throw: ISO-8859-8-I has a pointer 159 
+PASS Not throw: ISO-8859-8-I has a pointer 160 
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 161 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8-I has a pointer 162 
+PASS Not throw: ISO-8859-8-I has a pointer 163 
+PASS Not throw: ISO-8859-8-I has a pointer 164 
+PASS Not throw: ISO-8859-8-I has a pointer 165 
+PASS Not throw: ISO-8859-8-I has a pointer 166 
+PASS Not throw: ISO-8859-8-I has a pointer 167 
+PASS Not throw: ISO-8859-8-I has a pointer 168 
+PASS Not throw: ISO-8859-8-I has a pointer 169 
+PASS Not throw: ISO-8859-8-I has a pointer 170 
+PASS Not throw: ISO-8859-8-I has a pointer 171 
+PASS Not throw: ISO-8859-8-I has a pointer 172 
+PASS Not throw: ISO-8859-8-I has a pointer 173 
+PASS Not throw: ISO-8859-8-I has a pointer 174 
+PASS Not throw: ISO-8859-8-I has a pointer 175 
+PASS Not throw: ISO-8859-8-I has a pointer 176 
+PASS Not throw: ISO-8859-8-I has a pointer 177 
+PASS Not throw: ISO-8859-8-I has a pointer 178 
+PASS Not throw: ISO-8859-8-I has a pointer 179 
+PASS Not throw: ISO-8859-8-I has a pointer 180 
+PASS Not throw: ISO-8859-8-I has a pointer 181 
+PASS Not throw: ISO-8859-8-I has a pointer 182 
+PASS Not throw: ISO-8859-8-I has a pointer 183 
+PASS Not throw: ISO-8859-8-I has a pointer 184 
+PASS Not throw: ISO-8859-8-I has a pointer 185 
+PASS Not throw: ISO-8859-8-I has a pointer 186 
+PASS Not throw: ISO-8859-8-I has a pointer 187 
+PASS Not throw: ISO-8859-8-I has a pointer 188 
+PASS Not throw: ISO-8859-8-I has a pointer 189 
+PASS Not throw: ISO-8859-8-I has a pointer 190 
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 191 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 192 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 193 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 194 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 195 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 196 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 197 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 198 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 199 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 200 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 201 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 202 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 203 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 204 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 205 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 206 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 207 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 208 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 209 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 210 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 211 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 212 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 213 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 214 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 215 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 216 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 217 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 218 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 219 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 220 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 221 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 222 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8-I has a pointer 223 
+PASS Not throw: ISO-8859-8-I has a pointer 224 
+PASS Not throw: ISO-8859-8-I has a pointer 225 
+PASS Not throw: ISO-8859-8-I has a pointer 226 
+PASS Not throw: ISO-8859-8-I has a pointer 227 
+PASS Not throw: ISO-8859-8-I has a pointer 228 
+PASS Not throw: ISO-8859-8-I has a pointer 229 
+PASS Not throw: ISO-8859-8-I has a pointer 230 
+PASS Not throw: ISO-8859-8-I has a pointer 231 
+PASS Not throw: ISO-8859-8-I has a pointer 232 
+PASS Not throw: ISO-8859-8-I has a pointer 233 
+PASS Not throw: ISO-8859-8-I has a pointer 234 
+PASS Not throw: ISO-8859-8-I has a pointer 235 
+PASS Not throw: ISO-8859-8-I has a pointer 236 
+PASS Not throw: ISO-8859-8-I has a pointer 237 
+PASS Not throw: ISO-8859-8-I has a pointer 238 
+PASS Not throw: ISO-8859-8-I has a pointer 239 
+PASS Not throw: ISO-8859-8-I has a pointer 240 
+PASS Not throw: ISO-8859-8-I has a pointer 241 
+PASS Not throw: ISO-8859-8-I has a pointer 242 
+PASS Not throw: ISO-8859-8-I has a pointer 243 
+PASS Not throw: ISO-8859-8-I has a pointer 244 
+PASS Not throw: ISO-8859-8-I has a pointer 245 
+PASS Not throw: ISO-8859-8-I has a pointer 246 
+PASS Not throw: ISO-8859-8-I has a pointer 247 
+PASS Not throw: ISO-8859-8-I has a pointer 248 
+PASS Not throw: ISO-8859-8-I has a pointer 249 
+PASS Not throw: ISO-8859-8-I has a pointer 250 
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 251 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 252 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-8-I has a pointer 253 
+PASS Not throw: ISO-8859-8-I has a pointer 254 
+FAIL Throw due to fatal flag: ISO-8859-8-I doesn't have a pointer 255 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: ISO-8859-10 has a pointer 0 
+PASS Not throw: ISO-8859-10 has a pointer 1 
+PASS Not throw: ISO-8859-10 has a pointer 2 
+PASS Not throw: ISO-8859-10 has a pointer 3 
+PASS Not throw: ISO-8859-10 has a pointer 4 
+PASS Not throw: ISO-8859-10 has a pointer 5 
+PASS Not throw: ISO-8859-10 has a pointer 6 
+PASS Not throw: ISO-8859-10 has a pointer 7 
+PASS Not throw: ISO-8859-10 has a pointer 8 
+PASS Not throw: ISO-8859-10 has a pointer 9 
+PASS Not throw: ISO-8859-10 has a pointer 10 
+PASS Not throw: ISO-8859-10 has a pointer 11 
+PASS Not throw: ISO-8859-10 has a pointer 12 
+PASS Not throw: ISO-8859-10 has a pointer 13 
+PASS Not throw: ISO-8859-10 has a pointer 14 
+PASS Not throw: ISO-8859-10 has a pointer 15 
+PASS Not throw: ISO-8859-10 has a pointer 16 
+PASS Not throw: ISO-8859-10 has a pointer 17 
+PASS Not throw: ISO-8859-10 has a pointer 18 
+PASS Not throw: ISO-8859-10 has a pointer 19 
+PASS Not throw: ISO-8859-10 has a pointer 20 
+PASS Not throw: ISO-8859-10 has a pointer 21 
+PASS Not throw: ISO-8859-10 has a pointer 22 
+PASS Not throw: ISO-8859-10 has a pointer 23 
+PASS Not throw: ISO-8859-10 has a pointer 24 
+PASS Not throw: ISO-8859-10 has a pointer 25 
+PASS Not throw: ISO-8859-10 has a pointer 26 
+PASS Not throw: ISO-8859-10 has a pointer 27 
+PASS Not throw: ISO-8859-10 has a pointer 28 
+PASS Not throw: ISO-8859-10 has a pointer 29 
+PASS Not throw: ISO-8859-10 has a pointer 30 
+PASS Not throw: ISO-8859-10 has a pointer 31 
+PASS Not throw: ISO-8859-10 has a pointer 32 
+PASS Not throw: ISO-8859-10 has a pointer 33 
+PASS Not throw: ISO-8859-10 has a pointer 34 
+PASS Not throw: ISO-8859-10 has a pointer 35 
+PASS Not throw: ISO-8859-10 has a pointer 36 
+PASS Not throw: ISO-8859-10 has a pointer 37 
+PASS Not throw: ISO-8859-10 has a pointer 38 
+PASS Not throw: ISO-8859-10 has a pointer 39 
+PASS Not throw: ISO-8859-10 has a pointer 40 
+PASS Not throw: ISO-8859-10 has a pointer 41 
+PASS Not throw: ISO-8859-10 has a pointer 42 
+PASS Not throw: ISO-8859-10 has a pointer 43 
+PASS Not throw: ISO-8859-10 has a pointer 44 
+PASS Not throw: ISO-8859-10 has a pointer 45 
+PASS Not throw: ISO-8859-10 has a pointer 46 
+PASS Not throw: ISO-8859-10 has a pointer 47 
+PASS Not throw: ISO-8859-10 has a pointer 48 
+PASS Not throw: ISO-8859-10 has a pointer 49 
+PASS Not throw: ISO-8859-10 has a pointer 50 
+PASS Not throw: ISO-8859-10 has a pointer 51 
+PASS Not throw: ISO-8859-10 has a pointer 52 
+PASS Not throw: ISO-8859-10 has a pointer 53 
+PASS Not throw: ISO-8859-10 has a pointer 54 
+PASS Not throw: ISO-8859-10 has a pointer 55 
+PASS Not throw: ISO-8859-10 has a pointer 56 
+PASS Not throw: ISO-8859-10 has a pointer 57 
+PASS Not throw: ISO-8859-10 has a pointer 58 
+PASS Not throw: ISO-8859-10 has a pointer 59 
+PASS Not throw: ISO-8859-10 has a pointer 60 
+PASS Not throw: ISO-8859-10 has a pointer 61 
+PASS Not throw: ISO-8859-10 has a pointer 62 
+PASS Not throw: ISO-8859-10 has a pointer 63 
+PASS Not throw: ISO-8859-10 has a pointer 64 
+PASS Not throw: ISO-8859-10 has a pointer 65 
+PASS Not throw: ISO-8859-10 has a pointer 66 
+PASS Not throw: ISO-8859-10 has a pointer 67 
+PASS Not throw: ISO-8859-10 has a pointer 68 
+PASS Not throw: ISO-8859-10 has a pointer 69 
+PASS Not throw: ISO-8859-10 has a pointer 70 
+PASS Not throw: ISO-8859-10 has a pointer 71 
+PASS Not throw: ISO-8859-10 has a pointer 72 
+PASS Not throw: ISO-8859-10 has a pointer 73 
+PASS Not throw: ISO-8859-10 has a pointer 74 
+PASS Not throw: ISO-8859-10 has a pointer 75 
+PASS Not throw: ISO-8859-10 has a pointer 76 
+PASS Not throw: ISO-8859-10 has a pointer 77 
+PASS Not throw: ISO-8859-10 has a pointer 78 
+PASS Not throw: ISO-8859-10 has a pointer 79 
+PASS Not throw: ISO-8859-10 has a pointer 80 
+PASS Not throw: ISO-8859-10 has a pointer 81 
+PASS Not throw: ISO-8859-10 has a pointer 82 
+PASS Not throw: ISO-8859-10 has a pointer 83 
+PASS Not throw: ISO-8859-10 has a pointer 84 
+PASS Not throw: ISO-8859-10 has a pointer 85 
+PASS Not throw: ISO-8859-10 has a pointer 86 
+PASS Not throw: ISO-8859-10 has a pointer 87 
+PASS Not throw: ISO-8859-10 has a pointer 88 
+PASS Not throw: ISO-8859-10 has a pointer 89 
+PASS Not throw: ISO-8859-10 has a pointer 90 
+PASS Not throw: ISO-8859-10 has a pointer 91 
+PASS Not throw: ISO-8859-10 has a pointer 92 
+PASS Not throw: ISO-8859-10 has a pointer 93 
+PASS Not throw: ISO-8859-10 has a pointer 94 
+PASS Not throw: ISO-8859-10 has a pointer 95 
+PASS Not throw: ISO-8859-10 has a pointer 96 
+PASS Not throw: ISO-8859-10 has a pointer 97 
+PASS Not throw: ISO-8859-10 has a pointer 98 
+PASS Not throw: ISO-8859-10 has a pointer 99 
+PASS Not throw: ISO-8859-10 has a pointer 100 
+PASS Not throw: ISO-8859-10 has a pointer 101 
+PASS Not throw: ISO-8859-10 has a pointer 102 
+PASS Not throw: ISO-8859-10 has a pointer 103 
+PASS Not throw: ISO-8859-10 has a pointer 104 
+PASS Not throw: ISO-8859-10 has a pointer 105 
+PASS Not throw: ISO-8859-10 has a pointer 106 
+PASS Not throw: ISO-8859-10 has a pointer 107 
+PASS Not throw: ISO-8859-10 has a pointer 108 
+PASS Not throw: ISO-8859-10 has a pointer 109 
+PASS Not throw: ISO-8859-10 has a pointer 110 
+PASS Not throw: ISO-8859-10 has a pointer 111 
+PASS Not throw: ISO-8859-10 has a pointer 112 
+PASS Not throw: ISO-8859-10 has a pointer 113 
+PASS Not throw: ISO-8859-10 has a pointer 114 
+PASS Not throw: ISO-8859-10 has a pointer 115 
+PASS Not throw: ISO-8859-10 has a pointer 116 
+PASS Not throw: ISO-8859-10 has a pointer 117 
+PASS Not throw: ISO-8859-10 has a pointer 118 
+PASS Not throw: ISO-8859-10 has a pointer 119 
+PASS Not throw: ISO-8859-10 has a pointer 120 
+PASS Not throw: ISO-8859-10 has a pointer 121 
+PASS Not throw: ISO-8859-10 has a pointer 122 
+PASS Not throw: ISO-8859-10 has a pointer 123 
+PASS Not throw: ISO-8859-10 has a pointer 124 
+PASS Not throw: ISO-8859-10 has a pointer 125 
+PASS Not throw: ISO-8859-10 has a pointer 126 
+PASS Not throw: ISO-8859-10 has a pointer 127 
+PASS Not throw: ISO-8859-10 has a pointer 128 
+PASS Not throw: ISO-8859-10 has a pointer 129 
+PASS Not throw: ISO-8859-10 has a pointer 130 
+PASS Not throw: ISO-8859-10 has a pointer 131 
+PASS Not throw: ISO-8859-10 has a pointer 132 
+PASS Not throw: ISO-8859-10 has a pointer 133 
+PASS Not throw: ISO-8859-10 has a pointer 134 
+PASS Not throw: ISO-8859-10 has a pointer 135 
+PASS Not throw: ISO-8859-10 has a pointer 136 
+PASS Not throw: ISO-8859-10 has a pointer 137 
+PASS Not throw: ISO-8859-10 has a pointer 138 
+PASS Not throw: ISO-8859-10 has a pointer 139 
+PASS Not throw: ISO-8859-10 has a pointer 140 
+PASS Not throw: ISO-8859-10 has a pointer 141 
+PASS Not throw: ISO-8859-10 has a pointer 142 
+PASS Not throw: ISO-8859-10 has a pointer 143 
+PASS Not throw: ISO-8859-10 has a pointer 144 
+PASS Not throw: ISO-8859-10 has a pointer 145 
+PASS Not throw: ISO-8859-10 has a pointer 146 
+PASS Not throw: ISO-8859-10 has a pointer 147 
+PASS Not throw: ISO-8859-10 has a pointer 148 
+PASS Not throw: ISO-8859-10 has a pointer 149 
+PASS Not throw: ISO-8859-10 has a pointer 150 
+PASS Not throw: ISO-8859-10 has a pointer 151 
+PASS Not throw: ISO-8859-10 has a pointer 152 
+PASS Not throw: ISO-8859-10 has a pointer 153 
+PASS Not throw: ISO-8859-10 has a pointer 154 
+PASS Not throw: ISO-8859-10 has a pointer 155 
+PASS Not throw: ISO-8859-10 has a pointer 156 
+PASS Not throw: ISO-8859-10 has a pointer 157 
+PASS Not throw: ISO-8859-10 has a pointer 158 
+PASS Not throw: ISO-8859-10 has a pointer 159 
+PASS Not throw: ISO-8859-10 has a pointer 160 
+PASS Not throw: ISO-8859-10 has a pointer 161 
+PASS Not throw: ISO-8859-10 has a pointer 162 
+PASS Not throw: ISO-8859-10 has a pointer 163 
+PASS Not throw: ISO-8859-10 has a pointer 164 
+PASS Not throw: ISO-8859-10 has a pointer 165 
+PASS Not throw: ISO-8859-10 has a pointer 166 
+PASS Not throw: ISO-8859-10 has a pointer 167 
+PASS Not throw: ISO-8859-10 has a pointer 168 
+PASS Not throw: ISO-8859-10 has a pointer 169 
+PASS Not throw: ISO-8859-10 has a pointer 170 
+PASS Not throw: ISO-8859-10 has a pointer 171 
+PASS Not throw: ISO-8859-10 has a pointer 172 
+PASS Not throw: ISO-8859-10 has a pointer 173 
+PASS Not throw: ISO-8859-10 has a pointer 174 
+PASS Not throw: ISO-8859-10 has a pointer 175 
+PASS Not throw: ISO-8859-10 has a pointer 176 
+PASS Not throw: ISO-8859-10 has a pointer 177 
+PASS Not throw: ISO-8859-10 has a pointer 178 
+PASS Not throw: ISO-8859-10 has a pointer 179 
+PASS Not throw: ISO-8859-10 has a pointer 180 
+PASS Not throw: ISO-8859-10 has a pointer 181 
+PASS Not throw: ISO-8859-10 has a pointer 182 
+PASS Not throw: ISO-8859-10 has a pointer 183 
+PASS Not throw: ISO-8859-10 has a pointer 184 
+PASS Not throw: ISO-8859-10 has a pointer 185 
+PASS Not throw: ISO-8859-10 has a pointer 186 
+PASS Not throw: ISO-8859-10 has a pointer 187 
+PASS Not throw: ISO-8859-10 has a pointer 188 
+PASS Not throw: ISO-8859-10 has a pointer 189 
+PASS Not throw: ISO-8859-10 has a pointer 190 
+PASS Not throw: ISO-8859-10 has a pointer 191 
+PASS Not throw: ISO-8859-10 has a pointer 192 
+PASS Not throw: ISO-8859-10 has a pointer 193 
+PASS Not throw: ISO-8859-10 has a pointer 194 
+PASS Not throw: ISO-8859-10 has a pointer 195 
+PASS Not throw: ISO-8859-10 has a pointer 196 
+PASS Not throw: ISO-8859-10 has a pointer 197 
+PASS Not throw: ISO-8859-10 has a pointer 198 
+PASS Not throw: ISO-8859-10 has a pointer 199 
+PASS Not throw: ISO-8859-10 has a pointer 200 
+PASS Not throw: ISO-8859-10 has a pointer 201 
+PASS Not throw: ISO-8859-10 has a pointer 202 
+PASS Not throw: ISO-8859-10 has a pointer 203 
+PASS Not throw: ISO-8859-10 has a pointer 204 
+PASS Not throw: ISO-8859-10 has a pointer 205 
+PASS Not throw: ISO-8859-10 has a pointer 206 
+PASS Not throw: ISO-8859-10 has a pointer 207 
+PASS Not throw: ISO-8859-10 has a pointer 208 
+PASS Not throw: ISO-8859-10 has a pointer 209 
+PASS Not throw: ISO-8859-10 has a pointer 210 
+PASS Not throw: ISO-8859-10 has a pointer 211 
+PASS Not throw: ISO-8859-10 has a pointer 212 
+PASS Not throw: ISO-8859-10 has a pointer 213 
+PASS Not throw: ISO-8859-10 has a pointer 214 
+PASS Not throw: ISO-8859-10 has a pointer 215 
+PASS Not throw: ISO-8859-10 has a pointer 216 
+PASS Not throw: ISO-8859-10 has a pointer 217 
+PASS Not throw: ISO-8859-10 has a pointer 218 
+PASS Not throw: ISO-8859-10 has a pointer 219 
+PASS Not throw: ISO-8859-10 has a pointer 220 
+PASS Not throw: ISO-8859-10 has a pointer 221 
+PASS Not throw: ISO-8859-10 has a pointer 222 
+PASS Not throw: ISO-8859-10 has a pointer 223 
+PASS Not throw: ISO-8859-10 has a pointer 224 
+PASS Not throw: ISO-8859-10 has a pointer 225 
+PASS Not throw: ISO-8859-10 has a pointer 226 
+PASS Not throw: ISO-8859-10 has a pointer 227 
+PASS Not throw: ISO-8859-10 has a pointer 228 
+PASS Not throw: ISO-8859-10 has a pointer 229 
+PASS Not throw: ISO-8859-10 has a pointer 230 
+PASS Not throw: ISO-8859-10 has a pointer 231 
+PASS Not throw: ISO-8859-10 has a pointer 232 
+PASS Not throw: ISO-8859-10 has a pointer 233 
+PASS Not throw: ISO-8859-10 has a pointer 234 
+PASS Not throw: ISO-8859-10 has a pointer 235 
+PASS Not throw: ISO-8859-10 has a pointer 236 
+PASS Not throw: ISO-8859-10 has a pointer 237 
+PASS Not throw: ISO-8859-10 has a pointer 238 
+PASS Not throw: ISO-8859-10 has a pointer 239 
+PASS Not throw: ISO-8859-10 has a pointer 240 
+PASS Not throw: ISO-8859-10 has a pointer 241 
+PASS Not throw: ISO-8859-10 has a pointer 242 
+PASS Not throw: ISO-8859-10 has a pointer 243 
+PASS Not throw: ISO-8859-10 has a pointer 244 
+PASS Not throw: ISO-8859-10 has a pointer 245 
+PASS Not throw: ISO-8859-10 has a pointer 246 
+PASS Not throw: ISO-8859-10 has a pointer 247 
+PASS Not throw: ISO-8859-10 has a pointer 248 
+PASS Not throw: ISO-8859-10 has a pointer 249 
+PASS Not throw: ISO-8859-10 has a pointer 250 
+PASS Not throw: ISO-8859-10 has a pointer 251 
+PASS Not throw: ISO-8859-10 has a pointer 252 
+PASS Not throw: ISO-8859-10 has a pointer 253 
+PASS Not throw: ISO-8859-10 has a pointer 254 
+PASS Not throw: ISO-8859-10 has a pointer 255 
+PASS Not throw: ISO-8859-13 has a pointer 0 
+PASS Not throw: ISO-8859-13 has a pointer 1 
+PASS Not throw: ISO-8859-13 has a pointer 2 
+PASS Not throw: ISO-8859-13 has a pointer 3 
+PASS Not throw: ISO-8859-13 has a pointer 4 
+PASS Not throw: ISO-8859-13 has a pointer 5 
+PASS Not throw: ISO-8859-13 has a pointer 6 
+PASS Not throw: ISO-8859-13 has a pointer 7 
+PASS Not throw: ISO-8859-13 has a pointer 8 
+PASS Not throw: ISO-8859-13 has a pointer 9 
+PASS Not throw: ISO-8859-13 has a pointer 10 
+PASS Not throw: ISO-8859-13 has a pointer 11 
+PASS Not throw: ISO-8859-13 has a pointer 12 
+PASS Not throw: ISO-8859-13 has a pointer 13 
+PASS Not throw: ISO-8859-13 has a pointer 14 
+PASS Not throw: ISO-8859-13 has a pointer 15 
+PASS Not throw: ISO-8859-13 has a pointer 16 
+PASS Not throw: ISO-8859-13 has a pointer 17 
+PASS Not throw: ISO-8859-13 has a pointer 18 
+PASS Not throw: ISO-8859-13 has a pointer 19 
+PASS Not throw: ISO-8859-13 has a pointer 20 
+PASS Not throw: ISO-8859-13 has a pointer 21 
+PASS Not throw: ISO-8859-13 has a pointer 22 
+PASS Not throw: ISO-8859-13 has a pointer 23 
+PASS Not throw: ISO-8859-13 has a pointer 24 
+PASS Not throw: ISO-8859-13 has a pointer 25 
+PASS Not throw: ISO-8859-13 has a pointer 26 
+PASS Not throw: ISO-8859-13 has a pointer 27 
+PASS Not throw: ISO-8859-13 has a pointer 28 
+PASS Not throw: ISO-8859-13 has a pointer 29 
+PASS Not throw: ISO-8859-13 has a pointer 30 
+PASS Not throw: ISO-8859-13 has a pointer 31 
+PASS Not throw: ISO-8859-13 has a pointer 32 
+PASS Not throw: ISO-8859-13 has a pointer 33 
+PASS Not throw: ISO-8859-13 has a pointer 34 
+PASS Not throw: ISO-8859-13 has a pointer 35 
+PASS Not throw: ISO-8859-13 has a pointer 36 
+PASS Not throw: ISO-8859-13 has a pointer 37 
+PASS Not throw: ISO-8859-13 has a pointer 38 
+PASS Not throw: ISO-8859-13 has a pointer 39 
+PASS Not throw: ISO-8859-13 has a pointer 40 
+PASS Not throw: ISO-8859-13 has a pointer 41 
+PASS Not throw: ISO-8859-13 has a pointer 42 
+PASS Not throw: ISO-8859-13 has a pointer 43 
+PASS Not throw: ISO-8859-13 has a pointer 44 
+PASS Not throw: ISO-8859-13 has a pointer 45 
+PASS Not throw: ISO-8859-13 has a pointer 46 
+PASS Not throw: ISO-8859-13 has a pointer 47 
+PASS Not throw: ISO-8859-13 has a pointer 48 
+PASS Not throw: ISO-8859-13 has a pointer 49 
+PASS Not throw: ISO-8859-13 has a pointer 50 
+PASS Not throw: ISO-8859-13 has a pointer 51 
+PASS Not throw: ISO-8859-13 has a pointer 52 
+PASS Not throw: ISO-8859-13 has a pointer 53 
+PASS Not throw: ISO-8859-13 has a pointer 54 
+PASS Not throw: ISO-8859-13 has a pointer 55 
+PASS Not throw: ISO-8859-13 has a pointer 56 
+PASS Not throw: ISO-8859-13 has a pointer 57 
+PASS Not throw: ISO-8859-13 has a pointer 58 
+PASS Not throw: ISO-8859-13 has a pointer 59 
+PASS Not throw: ISO-8859-13 has a pointer 60 
+PASS Not throw: ISO-8859-13 has a pointer 61 
+PASS Not throw: ISO-8859-13 has a pointer 62 
+PASS Not throw: ISO-8859-13 has a pointer 63 
+PASS Not throw: ISO-8859-13 has a pointer 64 
+PASS Not throw: ISO-8859-13 has a pointer 65 
+PASS Not throw: ISO-8859-13 has a pointer 66 
+PASS Not throw: ISO-8859-13 has a pointer 67 
+PASS Not throw: ISO-8859-13 has a pointer 68 
+PASS Not throw: ISO-8859-13 has a pointer 69 
+PASS Not throw: ISO-8859-13 has a pointer 70 
+PASS Not throw: ISO-8859-13 has a pointer 71 
+PASS Not throw: ISO-8859-13 has a pointer 72 
+PASS Not throw: ISO-8859-13 has a pointer 73 
+PASS Not throw: ISO-8859-13 has a pointer 74 
+PASS Not throw: ISO-8859-13 has a pointer 75 
+PASS Not throw: ISO-8859-13 has a pointer 76 
+PASS Not throw: ISO-8859-13 has a pointer 77 
+PASS Not throw: ISO-8859-13 has a pointer 78 
+PASS Not throw: ISO-8859-13 has a pointer 79 
+PASS Not throw: ISO-8859-13 has a pointer 80 
+PASS Not throw: ISO-8859-13 has a pointer 81 
+PASS Not throw: ISO-8859-13 has a pointer 82 
+PASS Not throw: ISO-8859-13 has a pointer 83 
+PASS Not throw: ISO-8859-13 has a pointer 84 
+PASS Not throw: ISO-8859-13 has a pointer 85 
+PASS Not throw: ISO-8859-13 has a pointer 86 
+PASS Not throw: ISO-8859-13 has a pointer 87 
+PASS Not throw: ISO-8859-13 has a pointer 88 
+PASS Not throw: ISO-8859-13 has a pointer 89 
+PASS Not throw: ISO-8859-13 has a pointer 90 
+PASS Not throw: ISO-8859-13 has a pointer 91 
+PASS Not throw: ISO-8859-13 has a pointer 92 
+PASS Not throw: ISO-8859-13 has a pointer 93 
+PASS Not throw: ISO-8859-13 has a pointer 94 
+PASS Not throw: ISO-8859-13 has a pointer 95 
+PASS Not throw: ISO-8859-13 has a pointer 96 
+PASS Not throw: ISO-8859-13 has a pointer 97 
+PASS Not throw: ISO-8859-13 has a pointer 98 
+PASS Not throw: ISO-8859-13 has a pointer 99 
+PASS Not throw: ISO-8859-13 has a pointer 100 
+PASS Not throw: ISO-8859-13 has a pointer 101 
+PASS Not throw: ISO-8859-13 has a pointer 102 
+PASS Not throw: ISO-8859-13 has a pointer 103 
+PASS Not throw: ISO-8859-13 has a pointer 104 
+PASS Not throw: ISO-8859-13 has a pointer 105 
+PASS Not throw: ISO-8859-13 has a pointer 106 
+PASS Not throw: ISO-8859-13 has a pointer 107 
+PASS Not throw: ISO-8859-13 has a pointer 108 
+PASS Not throw: ISO-8859-13 has a pointer 109 
+PASS Not throw: ISO-8859-13 has a pointer 110 
+PASS Not throw: ISO-8859-13 has a pointer 111 
+PASS Not throw: ISO-8859-13 has a pointer 112 
+PASS Not throw: ISO-8859-13 has a pointer 113 
+PASS Not throw: ISO-8859-13 has a pointer 114 
+PASS Not throw: ISO-8859-13 has a pointer 115 
+PASS Not throw: ISO-8859-13 has a pointer 116 
+PASS Not throw: ISO-8859-13 has a pointer 117 
+PASS Not throw: ISO-8859-13 has a pointer 118 
+PASS Not throw: ISO-8859-13 has a pointer 119 
+PASS Not throw: ISO-8859-13 has a pointer 120 
+PASS Not throw: ISO-8859-13 has a pointer 121 
+PASS Not throw: ISO-8859-13 has a pointer 122 
+PASS Not throw: ISO-8859-13 has a pointer 123 
+PASS Not throw: ISO-8859-13 has a pointer 124 
+PASS Not throw: ISO-8859-13 has a pointer 125 
+PASS Not throw: ISO-8859-13 has a pointer 126 
+PASS Not throw: ISO-8859-13 has a pointer 127 
+PASS Not throw: ISO-8859-13 has a pointer 128 
+PASS Not throw: ISO-8859-13 has a pointer 129 
+PASS Not throw: ISO-8859-13 has a pointer 130 
+PASS Not throw: ISO-8859-13 has a pointer 131 
+PASS Not throw: ISO-8859-13 has a pointer 132 
+PASS Not throw: ISO-8859-13 has a pointer 133 
+PASS Not throw: ISO-8859-13 has a pointer 134 
+PASS Not throw: ISO-8859-13 has a pointer 135 
+PASS Not throw: ISO-8859-13 has a pointer 136 
+PASS Not throw: ISO-8859-13 has a pointer 137 
+PASS Not throw: ISO-8859-13 has a pointer 138 
+PASS Not throw: ISO-8859-13 has a pointer 139 
+PASS Not throw: ISO-8859-13 has a pointer 140 
+PASS Not throw: ISO-8859-13 has a pointer 141 
+PASS Not throw: ISO-8859-13 has a pointer 142 
+PASS Not throw: ISO-8859-13 has a pointer 143 
+PASS Not throw: ISO-8859-13 has a pointer 144 
+PASS Not throw: ISO-8859-13 has a pointer 145 
+PASS Not throw: ISO-8859-13 has a pointer 146 
+PASS Not throw: ISO-8859-13 has a pointer 147 
+PASS Not throw: ISO-8859-13 has a pointer 148 
+PASS Not throw: ISO-8859-13 has a pointer 149 
+PASS Not throw: ISO-8859-13 has a pointer 150 
+PASS Not throw: ISO-8859-13 has a pointer 151 
+PASS Not throw: ISO-8859-13 has a pointer 152 
+PASS Not throw: ISO-8859-13 has a pointer 153 
+PASS Not throw: ISO-8859-13 has a pointer 154 
+PASS Not throw: ISO-8859-13 has a pointer 155 
+PASS Not throw: ISO-8859-13 has a pointer 156 
+PASS Not throw: ISO-8859-13 has a pointer 157 
+PASS Not throw: ISO-8859-13 has a pointer 158 
+PASS Not throw: ISO-8859-13 has a pointer 159 
+PASS Not throw: ISO-8859-13 has a pointer 160 
+PASS Not throw: ISO-8859-13 has a pointer 161 
+PASS Not throw: ISO-8859-13 has a pointer 162 
+PASS Not throw: ISO-8859-13 has a pointer 163 
+PASS Not throw: ISO-8859-13 has a pointer 164 
+PASS Not throw: ISO-8859-13 has a pointer 165 
+PASS Not throw: ISO-8859-13 has a pointer 166 
+PASS Not throw: ISO-8859-13 has a pointer 167 
+PASS Not throw: ISO-8859-13 has a pointer 168 
+PASS Not throw: ISO-8859-13 has a pointer 169 
+PASS Not throw: ISO-8859-13 has a pointer 170 
+PASS Not throw: ISO-8859-13 has a pointer 171 
+PASS Not throw: ISO-8859-13 has a pointer 172 
+PASS Not throw: ISO-8859-13 has a pointer 173 
+PASS Not throw: ISO-8859-13 has a pointer 174 
+PASS Not throw: ISO-8859-13 has a pointer 175 
+PASS Not throw: ISO-8859-13 has a pointer 176 
+PASS Not throw: ISO-8859-13 has a pointer 177 
+PASS Not throw: ISO-8859-13 has a pointer 178 
+PASS Not throw: ISO-8859-13 has a pointer 179 
+PASS Not throw: ISO-8859-13 has a pointer 180 
+PASS Not throw: ISO-8859-13 has a pointer 181 
+PASS Not throw: ISO-8859-13 has a pointer 182 
+PASS Not throw: ISO-8859-13 has a pointer 183 
+PASS Not throw: ISO-8859-13 has a pointer 184 
+PASS Not throw: ISO-8859-13 has a pointer 185 
+PASS Not throw: ISO-8859-13 has a pointer 186 
+PASS Not throw: ISO-8859-13 has a pointer 187 
+PASS Not throw: ISO-8859-13 has a pointer 188 
+PASS Not throw: ISO-8859-13 has a pointer 189 
+PASS Not throw: ISO-8859-13 has a pointer 190 
+PASS Not throw: ISO-8859-13 has a pointer 191 
+PASS Not throw: ISO-8859-13 has a pointer 192 
+PASS Not throw: ISO-8859-13 has a pointer 193 
+PASS Not throw: ISO-8859-13 has a pointer 194 
+PASS Not throw: ISO-8859-13 has a pointer 195 
+PASS Not throw: ISO-8859-13 has a pointer 196 
+PASS Not throw: ISO-8859-13 has a pointer 197 
+PASS Not throw: ISO-8859-13 has a pointer 198 
+PASS Not throw: ISO-8859-13 has a pointer 199 
+PASS Not throw: ISO-8859-13 has a pointer 200 
+PASS Not throw: ISO-8859-13 has a pointer 201 
+PASS Not throw: ISO-8859-13 has a pointer 202 
+PASS Not throw: ISO-8859-13 has a pointer 203 
+PASS Not throw: ISO-8859-13 has a pointer 204 
+PASS Not throw: ISO-8859-13 has a pointer 205 
+PASS Not throw: ISO-8859-13 has a pointer 206 
+PASS Not throw: ISO-8859-13 has a pointer 207 
+PASS Not throw: ISO-8859-13 has a pointer 208 
+PASS Not throw: ISO-8859-13 has a pointer 209 
+PASS Not throw: ISO-8859-13 has a pointer 210 
+PASS Not throw: ISO-8859-13 has a pointer 211 
+PASS Not throw: ISO-8859-13 has a pointer 212 
+PASS Not throw: ISO-8859-13 has a pointer 213 
+PASS Not throw: ISO-8859-13 has a pointer 214 
+PASS Not throw: ISO-8859-13 has a pointer 215 
+PASS Not throw: ISO-8859-13 has a pointer 216 
+PASS Not throw: ISO-8859-13 has a pointer 217 
+PASS Not throw: ISO-8859-13 has a pointer 218 
+PASS Not throw: ISO-8859-13 has a pointer 219 
+PASS Not throw: ISO-8859-13 has a pointer 220 
+PASS Not throw: ISO-8859-13 has a pointer 221 
+PASS Not throw: ISO-8859-13 has a pointer 222 
+PASS Not throw: ISO-8859-13 has a pointer 223 
+PASS Not throw: ISO-8859-13 has a pointer 224 
+PASS Not throw: ISO-8859-13 has a pointer 225 
+PASS Not throw: ISO-8859-13 has a pointer 226 
+PASS Not throw: ISO-8859-13 has a pointer 227 
+PASS Not throw: ISO-8859-13 has a pointer 228 
+PASS Not throw: ISO-8859-13 has a pointer 229 
+PASS Not throw: ISO-8859-13 has a pointer 230 
+PASS Not throw: ISO-8859-13 has a pointer 231 
+PASS Not throw: ISO-8859-13 has a pointer 232 
+PASS Not throw: ISO-8859-13 has a pointer 233 
+PASS Not throw: ISO-8859-13 has a pointer 234 
+PASS Not throw: ISO-8859-13 has a pointer 235 
+PASS Not throw: ISO-8859-13 has a pointer 236 
+PASS Not throw: ISO-8859-13 has a pointer 237 
+PASS Not throw: ISO-8859-13 has a pointer 238 
+PASS Not throw: ISO-8859-13 has a pointer 239 
+PASS Not throw: ISO-8859-13 has a pointer 240 
+PASS Not throw: ISO-8859-13 has a pointer 241 
+PASS Not throw: ISO-8859-13 has a pointer 242 
+PASS Not throw: ISO-8859-13 has a pointer 243 
+PASS Not throw: ISO-8859-13 has a pointer 244 
+PASS Not throw: ISO-8859-13 has a pointer 245 
+PASS Not throw: ISO-8859-13 has a pointer 246 
+PASS Not throw: ISO-8859-13 has a pointer 247 
+PASS Not throw: ISO-8859-13 has a pointer 248 
+PASS Not throw: ISO-8859-13 has a pointer 249 
+PASS Not throw: ISO-8859-13 has a pointer 250 
+PASS Not throw: ISO-8859-13 has a pointer 251 
+PASS Not throw: ISO-8859-13 has a pointer 252 
+PASS Not throw: ISO-8859-13 has a pointer 253 
+PASS Not throw: ISO-8859-13 has a pointer 254 
+PASS Not throw: ISO-8859-13 has a pointer 255 
+PASS Not throw: ISO-8859-14 has a pointer 0 
+PASS Not throw: ISO-8859-14 has a pointer 1 
+PASS Not throw: ISO-8859-14 has a pointer 2 
+PASS Not throw: ISO-8859-14 has a pointer 3 
+PASS Not throw: ISO-8859-14 has a pointer 4 
+PASS Not throw: ISO-8859-14 has a pointer 5 
+PASS Not throw: ISO-8859-14 has a pointer 6 
+PASS Not throw: ISO-8859-14 has a pointer 7 
+PASS Not throw: ISO-8859-14 has a pointer 8 
+PASS Not throw: ISO-8859-14 has a pointer 9 
+PASS Not throw: ISO-8859-14 has a pointer 10 
+PASS Not throw: ISO-8859-14 has a pointer 11 
+PASS Not throw: ISO-8859-14 has a pointer 12 
+PASS Not throw: ISO-8859-14 has a pointer 13 
+PASS Not throw: ISO-8859-14 has a pointer 14 
+PASS Not throw: ISO-8859-14 has a pointer 15 
+PASS Not throw: ISO-8859-14 has a pointer 16 
+PASS Not throw: ISO-8859-14 has a pointer 17 
+PASS Not throw: ISO-8859-14 has a pointer 18 
+PASS Not throw: ISO-8859-14 has a pointer 19 
+PASS Not throw: ISO-8859-14 has a pointer 20 
+PASS Not throw: ISO-8859-14 has a pointer 21 
+PASS Not throw: ISO-8859-14 has a pointer 22 
+PASS Not throw: ISO-8859-14 has a pointer 23 
+PASS Not throw: ISO-8859-14 has a pointer 24 
+PASS Not throw: ISO-8859-14 has a pointer 25 
+PASS Not throw: ISO-8859-14 has a pointer 26 
+PASS Not throw: ISO-8859-14 has a pointer 27 
+PASS Not throw: ISO-8859-14 has a pointer 28 
+PASS Not throw: ISO-8859-14 has a pointer 29 
+PASS Not throw: ISO-8859-14 has a pointer 30 
+PASS Not throw: ISO-8859-14 has a pointer 31 
+PASS Not throw: ISO-8859-14 has a pointer 32 
+PASS Not throw: ISO-8859-14 has a pointer 33 
+PASS Not throw: ISO-8859-14 has a pointer 34 
+PASS Not throw: ISO-8859-14 has a pointer 35 
+PASS Not throw: ISO-8859-14 has a pointer 36 
+PASS Not throw: ISO-8859-14 has a pointer 37 
+PASS Not throw: ISO-8859-14 has a pointer 38 
+PASS Not throw: ISO-8859-14 has a pointer 39 
+PASS Not throw: ISO-8859-14 has a pointer 40 
+PASS Not throw: ISO-8859-14 has a pointer 41 
+PASS Not throw: ISO-8859-14 has a pointer 42 
+PASS Not throw: ISO-8859-14 has a pointer 43 
+PASS Not throw: ISO-8859-14 has a pointer 44 
+PASS Not throw: ISO-8859-14 has a pointer 45 
+PASS Not throw: ISO-8859-14 has a pointer 46 
+PASS Not throw: ISO-8859-14 has a pointer 47 
+PASS Not throw: ISO-8859-14 has a pointer 48 
+PASS Not throw: ISO-8859-14 has a pointer 49 
+PASS Not throw: ISO-8859-14 has a pointer 50 
+PASS Not throw: ISO-8859-14 has a pointer 51 
+PASS Not throw: ISO-8859-14 has a pointer 52 
+PASS Not throw: ISO-8859-14 has a pointer 53 
+PASS Not throw: ISO-8859-14 has a pointer 54 
+PASS Not throw: ISO-8859-14 has a pointer 55 
+PASS Not throw: ISO-8859-14 has a pointer 56 
+PASS Not throw: ISO-8859-14 has a pointer 57 
+PASS Not throw: ISO-8859-14 has a pointer 58 
+PASS Not throw: ISO-8859-14 has a pointer 59 
+PASS Not throw: ISO-8859-14 has a pointer 60 
+PASS Not throw: ISO-8859-14 has a pointer 61 
+PASS Not throw: ISO-8859-14 has a pointer 62 
+PASS Not throw: ISO-8859-14 has a pointer 63 
+PASS Not throw: ISO-8859-14 has a pointer 64 
+PASS Not throw: ISO-8859-14 has a pointer 65 
+PASS Not throw: ISO-8859-14 has a pointer 66 
+PASS Not throw: ISO-8859-14 has a pointer 67 
+PASS Not throw: ISO-8859-14 has a pointer 68 
+PASS Not throw: ISO-8859-14 has a pointer 69 
+PASS Not throw: ISO-8859-14 has a pointer 70 
+PASS Not throw: ISO-8859-14 has a pointer 71 
+PASS Not throw: ISO-8859-14 has a pointer 72 
+PASS Not throw: ISO-8859-14 has a pointer 73 
+PASS Not throw: ISO-8859-14 has a pointer 74 
+PASS Not throw: ISO-8859-14 has a pointer 75 
+PASS Not throw: ISO-8859-14 has a pointer 76 
+PASS Not throw: ISO-8859-14 has a pointer 77 
+PASS Not throw: ISO-8859-14 has a pointer 78 
+PASS Not throw: ISO-8859-14 has a pointer 79 
+PASS Not throw: ISO-8859-14 has a pointer 80 
+PASS Not throw: ISO-8859-14 has a pointer 81 
+PASS Not throw: ISO-8859-14 has a pointer 82 
+PASS Not throw: ISO-8859-14 has a pointer 83 
+PASS Not throw: ISO-8859-14 has a pointer 84 
+PASS Not throw: ISO-8859-14 has a pointer 85 
+PASS Not throw: ISO-8859-14 has a pointer 86 
+PASS Not throw: ISO-8859-14 has a pointer 87 
+PASS Not throw: ISO-8859-14 has a pointer 88 
+PASS Not throw: ISO-8859-14 has a pointer 89 
+PASS Not throw: ISO-8859-14 has a pointer 90 
+PASS Not throw: ISO-8859-14 has a pointer 91 
+PASS Not throw: ISO-8859-14 has a pointer 92 
+PASS Not throw: ISO-8859-14 has a pointer 93 
+PASS Not throw: ISO-8859-14 has a pointer 94 
+PASS Not throw: ISO-8859-14 has a pointer 95 
+PASS Not throw: ISO-8859-14 has a pointer 96 
+PASS Not throw: ISO-8859-14 has a pointer 97 
+PASS Not throw: ISO-8859-14 has a pointer 98 
+PASS Not throw: ISO-8859-14 has a pointer 99 
+PASS Not throw: ISO-8859-14 has a pointer 100 
+PASS Not throw: ISO-8859-14 has a pointer 101 
+PASS Not throw: ISO-8859-14 has a pointer 102 
+PASS Not throw: ISO-8859-14 has a pointer 103 
+PASS Not throw: ISO-8859-14 has a pointer 104 
+PASS Not throw: ISO-8859-14 has a pointer 105 
+PASS Not throw: ISO-8859-14 has a pointer 106 
+PASS Not throw: ISO-8859-14 has a pointer 107 
+PASS Not throw: ISO-8859-14 has a pointer 108 
+PASS Not throw: ISO-8859-14 has a pointer 109 
+PASS Not throw: ISO-8859-14 has a pointer 110 
+PASS Not throw: ISO-8859-14 has a pointer 111 
+PASS Not throw: ISO-8859-14 has a pointer 112 
+PASS Not throw: ISO-8859-14 has a pointer 113 
+PASS Not throw: ISO-8859-14 has a pointer 114 
+PASS Not throw: ISO-8859-14 has a pointer 115 
+PASS Not throw: ISO-8859-14 has a pointer 116 
+PASS Not throw: ISO-8859-14 has a pointer 117 
+PASS Not throw: ISO-8859-14 has a pointer 118 
+PASS Not throw: ISO-8859-14 has a pointer 119 
+PASS Not throw: ISO-8859-14 has a pointer 120 
+PASS Not throw: ISO-8859-14 has a pointer 121 
+PASS Not throw: ISO-8859-14 has a pointer 122 
+PASS Not throw: ISO-8859-14 has a pointer 123 
+PASS Not throw: ISO-8859-14 has a pointer 124 
+PASS Not throw: ISO-8859-14 has a pointer 125 
+PASS Not throw: ISO-8859-14 has a pointer 126 
+PASS Not throw: ISO-8859-14 has a pointer 127 
+PASS Not throw: ISO-8859-14 has a pointer 128 
+PASS Not throw: ISO-8859-14 has a pointer 129 
+PASS Not throw: ISO-8859-14 has a pointer 130 
+PASS Not throw: ISO-8859-14 has a pointer 131 
+PASS Not throw: ISO-8859-14 has a pointer 132 
+PASS Not throw: ISO-8859-14 has a pointer 133 
+PASS Not throw: ISO-8859-14 has a pointer 134 
+PASS Not throw: ISO-8859-14 has a pointer 135 
+PASS Not throw: ISO-8859-14 has a pointer 136 
+PASS Not throw: ISO-8859-14 has a pointer 137 
+PASS Not throw: ISO-8859-14 has a pointer 138 
+PASS Not throw: ISO-8859-14 has a pointer 139 
+PASS Not throw: ISO-8859-14 has a pointer 140 
+PASS Not throw: ISO-8859-14 has a pointer 141 
+PASS Not throw: ISO-8859-14 has a pointer 142 
+PASS Not throw: ISO-8859-14 has a pointer 143 
+PASS Not throw: ISO-8859-14 has a pointer 144 
+PASS Not throw: ISO-8859-14 has a pointer 145 
+PASS Not throw: ISO-8859-14 has a pointer 146 
+PASS Not throw: ISO-8859-14 has a pointer 147 
+PASS Not throw: ISO-8859-14 has a pointer 148 
+PASS Not throw: ISO-8859-14 has a pointer 149 
+PASS Not throw: ISO-8859-14 has a pointer 150 
+PASS Not throw: ISO-8859-14 has a pointer 151 
+PASS Not throw: ISO-8859-14 has a pointer 152 
+PASS Not throw: ISO-8859-14 has a pointer 153 
+PASS Not throw: ISO-8859-14 has a pointer 154 
+PASS Not throw: ISO-8859-14 has a pointer 155 
+PASS Not throw: ISO-8859-14 has a pointer 156 
+PASS Not throw: ISO-8859-14 has a pointer 157 
+PASS Not throw: ISO-8859-14 has a pointer 158 
+PASS Not throw: ISO-8859-14 has a pointer 159 
+PASS Not throw: ISO-8859-14 has a pointer 160 
+PASS Not throw: ISO-8859-14 has a pointer 161 
+PASS Not throw: ISO-8859-14 has a pointer 162 
+PASS Not throw: ISO-8859-14 has a pointer 163 
+PASS Not throw: ISO-8859-14 has a pointer 164 
+PASS Not throw: ISO-8859-14 has a pointer 165 
+PASS Not throw: ISO-8859-14 has a pointer 166 
+PASS Not throw: ISO-8859-14 has a pointer 167 
+PASS Not throw: ISO-8859-14 has a pointer 168 
+PASS Not throw: ISO-8859-14 has a pointer 169 
+PASS Not throw: ISO-8859-14 has a pointer 170 
+PASS Not throw: ISO-8859-14 has a pointer 171 
+PASS Not throw: ISO-8859-14 has a pointer 172 
+PASS Not throw: ISO-8859-14 has a pointer 173 
+PASS Not throw: ISO-8859-14 has a pointer 174 
+PASS Not throw: ISO-8859-14 has a pointer 175 
+PASS Not throw: ISO-8859-14 has a pointer 176 
+PASS Not throw: ISO-8859-14 has a pointer 177 
+PASS Not throw: ISO-8859-14 has a pointer 178 
+PASS Not throw: ISO-8859-14 has a pointer 179 
+PASS Not throw: ISO-8859-14 has a pointer 180 
+PASS Not throw: ISO-8859-14 has a pointer 181 
+PASS Not throw: ISO-8859-14 has a pointer 182 
+PASS Not throw: ISO-8859-14 has a pointer 183 
+PASS Not throw: ISO-8859-14 has a pointer 184 
+PASS Not throw: ISO-8859-14 has a pointer 185 
+PASS Not throw: ISO-8859-14 has a pointer 186 
+PASS Not throw: ISO-8859-14 has a pointer 187 
+PASS Not throw: ISO-8859-14 has a pointer 188 
+PASS Not throw: ISO-8859-14 has a pointer 189 
+PASS Not throw: ISO-8859-14 has a pointer 190 
+PASS Not throw: ISO-8859-14 has a pointer 191 
+PASS Not throw: ISO-8859-14 has a pointer 192 
+PASS Not throw: ISO-8859-14 has a pointer 193 
+PASS Not throw: ISO-8859-14 has a pointer 194 
+PASS Not throw: ISO-8859-14 has a pointer 195 
+PASS Not throw: ISO-8859-14 has a pointer 196 
+PASS Not throw: ISO-8859-14 has a pointer 197 
+PASS Not throw: ISO-8859-14 has a pointer 198 
+PASS Not throw: ISO-8859-14 has a pointer 199 
+PASS Not throw: ISO-8859-14 has a pointer 200 
+PASS Not throw: ISO-8859-14 has a pointer 201 
+PASS Not throw: ISO-8859-14 has a pointer 202 
+PASS Not throw: ISO-8859-14 has a pointer 203 
+PASS Not throw: ISO-8859-14 has a pointer 204 
+PASS Not throw: ISO-8859-14 has a pointer 205 
+PASS Not throw: ISO-8859-14 has a pointer 206 
+PASS Not throw: ISO-8859-14 has a pointer 207 
+PASS Not throw: ISO-8859-14 has a pointer 208 
+PASS Not throw: ISO-8859-14 has a pointer 209 
+PASS Not throw: ISO-8859-14 has a pointer 210 
+PASS Not throw: ISO-8859-14 has a pointer 211 
+PASS Not throw: ISO-8859-14 has a pointer 212 
+PASS Not throw: ISO-8859-14 has a pointer 213 
+PASS Not throw: ISO-8859-14 has a pointer 214 
+PASS Not throw: ISO-8859-14 has a pointer 215 
+PASS Not throw: ISO-8859-14 has a pointer 216 
+PASS Not throw: ISO-8859-14 has a pointer 217 
+PASS Not throw: ISO-8859-14 has a pointer 218 
+PASS Not throw: ISO-8859-14 has a pointer 219 
+PASS Not throw: ISO-8859-14 has a pointer 220 
+PASS Not throw: ISO-8859-14 has a pointer 221 
+PASS Not throw: ISO-8859-14 has a pointer 222 
+PASS Not throw: ISO-8859-14 has a pointer 223 
+PASS Not throw: ISO-8859-14 has a pointer 224 
+PASS Not throw: ISO-8859-14 has a pointer 225 
+PASS Not throw: ISO-8859-14 has a pointer 226 
+PASS Not throw: ISO-8859-14 has a pointer 227 
+PASS Not throw: ISO-8859-14 has a pointer 228 
+PASS Not throw: ISO-8859-14 has a pointer 229 
+PASS Not throw: ISO-8859-14 has a pointer 230 
+PASS Not throw: ISO-8859-14 has a pointer 231 
+PASS Not throw: ISO-8859-14 has a pointer 232 
+PASS Not throw: ISO-8859-14 has a pointer 233 
+PASS Not throw: ISO-8859-14 has a pointer 234 
+PASS Not throw: ISO-8859-14 has a pointer 235 
+PASS Not throw: ISO-8859-14 has a pointer 236 
+PASS Not throw: ISO-8859-14 has a pointer 237 
+PASS Not throw: ISO-8859-14 has a pointer 238 
+PASS Not throw: ISO-8859-14 has a pointer 239 
+PASS Not throw: ISO-8859-14 has a pointer 240 
+PASS Not throw: ISO-8859-14 has a pointer 241 
+PASS Not throw: ISO-8859-14 has a pointer 242 
+PASS Not throw: ISO-8859-14 has a pointer 243 
+PASS Not throw: ISO-8859-14 has a pointer 244 
+PASS Not throw: ISO-8859-14 has a pointer 245 
+PASS Not throw: ISO-8859-14 has a pointer 246 
+PASS Not throw: ISO-8859-14 has a pointer 247 
+PASS Not throw: ISO-8859-14 has a pointer 248 
+PASS Not throw: ISO-8859-14 has a pointer 249 
+PASS Not throw: ISO-8859-14 has a pointer 250 
+PASS Not throw: ISO-8859-14 has a pointer 251 
+PASS Not throw: ISO-8859-14 has a pointer 252 
+PASS Not throw: ISO-8859-14 has a pointer 253 
+PASS Not throw: ISO-8859-14 has a pointer 254 
+PASS Not throw: ISO-8859-14 has a pointer 255 
+PASS Not throw: ISO-8859-15 has a pointer 0 
+PASS Not throw: ISO-8859-15 has a pointer 1 
+PASS Not throw: ISO-8859-15 has a pointer 2 
+PASS Not throw: ISO-8859-15 has a pointer 3 
+PASS Not throw: ISO-8859-15 has a pointer 4 
+PASS Not throw: ISO-8859-15 has a pointer 5 
+PASS Not throw: ISO-8859-15 has a pointer 6 
+PASS Not throw: ISO-8859-15 has a pointer 7 
+PASS Not throw: ISO-8859-15 has a pointer 8 
+PASS Not throw: ISO-8859-15 has a pointer 9 
+PASS Not throw: ISO-8859-15 has a pointer 10 
+PASS Not throw: ISO-8859-15 has a pointer 11 
+PASS Not throw: ISO-8859-15 has a pointer 12 
+PASS Not throw: ISO-8859-15 has a pointer 13 
+PASS Not throw: ISO-8859-15 has a pointer 14 
+PASS Not throw: ISO-8859-15 has a pointer 15 
+PASS Not throw: ISO-8859-15 has a pointer 16 
+PASS Not throw: ISO-8859-15 has a pointer 17 
+PASS Not throw: ISO-8859-15 has a pointer 18 
+PASS Not throw: ISO-8859-15 has a pointer 19 
+PASS Not throw: ISO-8859-15 has a pointer 20 
+PASS Not throw: ISO-8859-15 has a pointer 21 
+PASS Not throw: ISO-8859-15 has a pointer 22 
+PASS Not throw: ISO-8859-15 has a pointer 23 
+PASS Not throw: ISO-8859-15 has a pointer 24 
+PASS Not throw: ISO-8859-15 has a pointer 25 
+PASS Not throw: ISO-8859-15 has a pointer 26 
+PASS Not throw: ISO-8859-15 has a pointer 27 
+PASS Not throw: ISO-8859-15 has a pointer 28 
+PASS Not throw: ISO-8859-15 has a pointer 29 
+PASS Not throw: ISO-8859-15 has a pointer 30 
+PASS Not throw: ISO-8859-15 has a pointer 31 
+PASS Not throw: ISO-8859-15 has a pointer 32 
+PASS Not throw: ISO-8859-15 has a pointer 33 
+PASS Not throw: ISO-8859-15 has a pointer 34 
+PASS Not throw: ISO-8859-15 has a pointer 35 
+PASS Not throw: ISO-8859-15 has a pointer 36 
+PASS Not throw: ISO-8859-15 has a pointer 37 
+PASS Not throw: ISO-8859-15 has a pointer 38 
+PASS Not throw: ISO-8859-15 has a pointer 39 
+PASS Not throw: ISO-8859-15 has a pointer 40 
+PASS Not throw: ISO-8859-15 has a pointer 41 
+PASS Not throw: ISO-8859-15 has a pointer 42 
+PASS Not throw: ISO-8859-15 has a pointer 43 
+PASS Not throw: ISO-8859-15 has a pointer 44 
+PASS Not throw: ISO-8859-15 has a pointer 45 
+PASS Not throw: ISO-8859-15 has a pointer 46 
+PASS Not throw: ISO-8859-15 has a pointer 47 
+PASS Not throw: ISO-8859-15 has a pointer 48 
+PASS Not throw: ISO-8859-15 has a pointer 49 
+PASS Not throw: ISO-8859-15 has a pointer 50 
+PASS Not throw: ISO-8859-15 has a pointer 51 
+PASS Not throw: ISO-8859-15 has a pointer 52 
+PASS Not throw: ISO-8859-15 has a pointer 53 
+PASS Not throw: ISO-8859-15 has a pointer 54 
+PASS Not throw: ISO-8859-15 has a pointer 55 
+PASS Not throw: ISO-8859-15 has a pointer 56 
+PASS Not throw: ISO-8859-15 has a pointer 57 
+PASS Not throw: ISO-8859-15 has a pointer 58 
+PASS Not throw: ISO-8859-15 has a pointer 59 
+PASS Not throw: ISO-8859-15 has a pointer 60 
+PASS Not throw: ISO-8859-15 has a pointer 61 
+PASS Not throw: ISO-8859-15 has a pointer 62 
+PASS Not throw: ISO-8859-15 has a pointer 63 
+PASS Not throw: ISO-8859-15 has a pointer 64 
+PASS Not throw: ISO-8859-15 has a pointer 65 
+PASS Not throw: ISO-8859-15 has a pointer 66 
+PASS Not throw: ISO-8859-15 has a pointer 67 
+PASS Not throw: ISO-8859-15 has a pointer 68 
+PASS Not throw: ISO-8859-15 has a pointer 69 
+PASS Not throw: ISO-8859-15 has a pointer 70 
+PASS Not throw: ISO-8859-15 has a pointer 71 
+PASS Not throw: ISO-8859-15 has a pointer 72 
+PASS Not throw: ISO-8859-15 has a pointer 73 
+PASS Not throw: ISO-8859-15 has a pointer 74 
+PASS Not throw: ISO-8859-15 has a pointer 75 
+PASS Not throw: ISO-8859-15 has a pointer 76 
+PASS Not throw: ISO-8859-15 has a pointer 77 
+PASS Not throw: ISO-8859-15 has a pointer 78 
+PASS Not throw: ISO-8859-15 has a pointer 79 
+PASS Not throw: ISO-8859-15 has a pointer 80 
+PASS Not throw: ISO-8859-15 has a pointer 81 
+PASS Not throw: ISO-8859-15 has a pointer 82 
+PASS Not throw: ISO-8859-15 has a pointer 83 
+PASS Not throw: ISO-8859-15 has a pointer 84 
+PASS Not throw: ISO-8859-15 has a pointer 85 
+PASS Not throw: ISO-8859-15 has a pointer 86 
+PASS Not throw: ISO-8859-15 has a pointer 87 
+PASS Not throw: ISO-8859-15 has a pointer 88 
+PASS Not throw: ISO-8859-15 has a pointer 89 
+PASS Not throw: ISO-8859-15 has a pointer 90 
+PASS Not throw: ISO-8859-15 has a pointer 91 
+PASS Not throw: ISO-8859-15 has a pointer 92 
+PASS Not throw: ISO-8859-15 has a pointer 93 
+PASS Not throw: ISO-8859-15 has a pointer 94 
+PASS Not throw: ISO-8859-15 has a pointer 95 
+PASS Not throw: ISO-8859-15 has a pointer 96 
+PASS Not throw: ISO-8859-15 has a pointer 97 
+PASS Not throw: ISO-8859-15 has a pointer 98 
+PASS Not throw: ISO-8859-15 has a pointer 99 
+PASS Not throw: ISO-8859-15 has a pointer 100 
+PASS Not throw: ISO-8859-15 has a pointer 101 
+PASS Not throw: ISO-8859-15 has a pointer 102 
+PASS Not throw: ISO-8859-15 has a pointer 103 
+PASS Not throw: ISO-8859-15 has a pointer 104 
+PASS Not throw: ISO-8859-15 has a pointer 105 
+PASS Not throw: ISO-8859-15 has a pointer 106 
+PASS Not throw: ISO-8859-15 has a pointer 107 
+PASS Not throw: ISO-8859-15 has a pointer 108 
+PASS Not throw: ISO-8859-15 has a pointer 109 
+PASS Not throw: ISO-8859-15 has a pointer 110 
+PASS Not throw: ISO-8859-15 has a pointer 111 
+PASS Not throw: ISO-8859-15 has a pointer 112 
+PASS Not throw: ISO-8859-15 has a pointer 113 
+PASS Not throw: ISO-8859-15 has a pointer 114 
+PASS Not throw: ISO-8859-15 has a pointer 115 
+PASS Not throw: ISO-8859-15 has a pointer 116 
+PASS Not throw: ISO-8859-15 has a pointer 117 
+PASS Not throw: ISO-8859-15 has a pointer 118 
+PASS Not throw: ISO-8859-15 has a pointer 119 
+PASS Not throw: ISO-8859-15 has a pointer 120 
+PASS Not throw: ISO-8859-15 has a pointer 121 
+PASS Not throw: ISO-8859-15 has a pointer 122 
+PASS Not throw: ISO-8859-15 has a pointer 123 
+PASS Not throw: ISO-8859-15 has a pointer 124 
+PASS Not throw: ISO-8859-15 has a pointer 125 
+PASS Not throw: ISO-8859-15 has a pointer 126 
+PASS Not throw: ISO-8859-15 has a pointer 127 
+PASS Not throw: ISO-8859-15 has a pointer 128 
+PASS Not throw: ISO-8859-15 has a pointer 129 
+PASS Not throw: ISO-8859-15 has a pointer 130 
+PASS Not throw: ISO-8859-15 has a pointer 131 
+PASS Not throw: ISO-8859-15 has a pointer 132 
+PASS Not throw: ISO-8859-15 has a pointer 133 
+PASS Not throw: ISO-8859-15 has a pointer 134 
+PASS Not throw: ISO-8859-15 has a pointer 135 
+PASS Not throw: ISO-8859-15 has a pointer 136 
+PASS Not throw: ISO-8859-15 has a pointer 137 
+PASS Not throw: ISO-8859-15 has a pointer 138 
+PASS Not throw: ISO-8859-15 has a pointer 139 
+PASS Not throw: ISO-8859-15 has a pointer 140 
+PASS Not throw: ISO-8859-15 has a pointer 141 
+PASS Not throw: ISO-8859-15 has a pointer 142 
+PASS Not throw: ISO-8859-15 has a pointer 143 
+PASS Not throw: ISO-8859-15 has a pointer 144 
+PASS Not throw: ISO-8859-15 has a pointer 145 
+PASS Not throw: ISO-8859-15 has a pointer 146 
+PASS Not throw: ISO-8859-15 has a pointer 147 
+PASS Not throw: ISO-8859-15 has a pointer 148 
+PASS Not throw: ISO-8859-15 has a pointer 149 
+PASS Not throw: ISO-8859-15 has a pointer 150 
+PASS Not throw: ISO-8859-15 has a pointer 151 
+PASS Not throw: ISO-8859-15 has a pointer 152 
+PASS Not throw: ISO-8859-15 has a pointer 153 
+PASS Not throw: ISO-8859-15 has a pointer 154 
+PASS Not throw: ISO-8859-15 has a pointer 155 
+PASS Not throw: ISO-8859-15 has a pointer 156 
+PASS Not throw: ISO-8859-15 has a pointer 157 
+PASS Not throw: ISO-8859-15 has a pointer 158 
+PASS Not throw: ISO-8859-15 has a pointer 159 
+PASS Not throw: ISO-8859-15 has a pointer 160 
+PASS Not throw: ISO-8859-15 has a pointer 161 
+PASS Not throw: ISO-8859-15 has a pointer 162 
+PASS Not throw: ISO-8859-15 has a pointer 163 
+PASS Not throw: ISO-8859-15 has a pointer 164 
+PASS Not throw: ISO-8859-15 has a pointer 165 
+PASS Not throw: ISO-8859-15 has a pointer 166 
+PASS Not throw: ISO-8859-15 has a pointer 167 
+PASS Not throw: ISO-8859-15 has a pointer 168 
+PASS Not throw: ISO-8859-15 has a pointer 169 
+PASS Not throw: ISO-8859-15 has a pointer 170 
+PASS Not throw: ISO-8859-15 has a pointer 171 
+PASS Not throw: ISO-8859-15 has a pointer 172 
+PASS Not throw: ISO-8859-15 has a pointer 173 
+PASS Not throw: ISO-8859-15 has a pointer 174 
+PASS Not throw: ISO-8859-15 has a pointer 175 
+PASS Not throw: ISO-8859-15 has a pointer 176 
+PASS Not throw: ISO-8859-15 has a pointer 177 
+PASS Not throw: ISO-8859-15 has a pointer 178 
+PASS Not throw: ISO-8859-15 has a pointer 179 
+PASS Not throw: ISO-8859-15 has a pointer 180 
+PASS Not throw: ISO-8859-15 has a pointer 181 
+PASS Not throw: ISO-8859-15 has a pointer 182 
+PASS Not throw: ISO-8859-15 has a pointer 183 
+PASS Not throw: ISO-8859-15 has a pointer 184 
+PASS Not throw: ISO-8859-15 has a pointer 185 
+PASS Not throw: ISO-8859-15 has a pointer 186 
+PASS Not throw: ISO-8859-15 has a pointer 187 
+PASS Not throw: ISO-8859-15 has a pointer 188 
+PASS Not throw: ISO-8859-15 has a pointer 189 
+PASS Not throw: ISO-8859-15 has a pointer 190 
+PASS Not throw: ISO-8859-15 has a pointer 191 
+PASS Not throw: ISO-8859-15 has a pointer 192 
+PASS Not throw: ISO-8859-15 has a pointer 193 
+PASS Not throw: ISO-8859-15 has a pointer 194 
+PASS Not throw: ISO-8859-15 has a pointer 195 
+PASS Not throw: ISO-8859-15 has a pointer 196 
+PASS Not throw: ISO-8859-15 has a pointer 197 
+PASS Not throw: ISO-8859-15 has a pointer 198 
+PASS Not throw: ISO-8859-15 has a pointer 199 
+PASS Not throw: ISO-8859-15 has a pointer 200 
+PASS Not throw: ISO-8859-15 has a pointer 201 
+PASS Not throw: ISO-8859-15 has a pointer 202 
+PASS Not throw: ISO-8859-15 has a pointer 203 
+PASS Not throw: ISO-8859-15 has a pointer 204 
+PASS Not throw: ISO-8859-15 has a pointer 205 
+PASS Not throw: ISO-8859-15 has a pointer 206 
+PASS Not throw: ISO-8859-15 has a pointer 207 
+PASS Not throw: ISO-8859-15 has a pointer 208 
+PASS Not throw: ISO-8859-15 has a pointer 209 
+PASS Not throw: ISO-8859-15 has a pointer 210 
+PASS Not throw: ISO-8859-15 has a pointer 211 
+PASS Not throw: ISO-8859-15 has a pointer 212 
+PASS Not throw: ISO-8859-15 has a pointer 213 
+PASS Not throw: ISO-8859-15 has a pointer 214 
+PASS Not throw: ISO-8859-15 has a pointer 215 
+PASS Not throw: ISO-8859-15 has a pointer 216 
+PASS Not throw: ISO-8859-15 has a pointer 217 
+PASS Not throw: ISO-8859-15 has a pointer 218 
+PASS Not throw: ISO-8859-15 has a pointer 219 
+PASS Not throw: ISO-8859-15 has a pointer 220 
+PASS Not throw: ISO-8859-15 has a pointer 221 
+PASS Not throw: ISO-8859-15 has a pointer 222 
+PASS Not throw: ISO-8859-15 has a pointer 223 
+PASS Not throw: ISO-8859-15 has a pointer 224 
+PASS Not throw: ISO-8859-15 has a pointer 225 
+PASS Not throw: ISO-8859-15 has a pointer 226 
+PASS Not throw: ISO-8859-15 has a pointer 227 
+PASS Not throw: ISO-8859-15 has a pointer 228 
+PASS Not throw: ISO-8859-15 has a pointer 229 
+PASS Not throw: ISO-8859-15 has a pointer 230 
+PASS Not throw: ISO-8859-15 has a pointer 231 
+PASS Not throw: ISO-8859-15 has a pointer 232 
+PASS Not throw: ISO-8859-15 has a pointer 233 
+PASS Not throw: ISO-8859-15 has a pointer 234 
+PASS Not throw: ISO-8859-15 has a pointer 235 
+PASS Not throw: ISO-8859-15 has a pointer 236 
+PASS Not throw: ISO-8859-15 has a pointer 237 
+PASS Not throw: ISO-8859-15 has a pointer 238 
+PASS Not throw: ISO-8859-15 has a pointer 239 
+PASS Not throw: ISO-8859-15 has a pointer 240 
+PASS Not throw: ISO-8859-15 has a pointer 241 
+PASS Not throw: ISO-8859-15 has a pointer 242 
+PASS Not throw: ISO-8859-15 has a pointer 243 
+PASS Not throw: ISO-8859-15 has a pointer 244 
+PASS Not throw: ISO-8859-15 has a pointer 245 
+PASS Not throw: ISO-8859-15 has a pointer 246 
+PASS Not throw: ISO-8859-15 has a pointer 247 
+PASS Not throw: ISO-8859-15 has a pointer 248 
+PASS Not throw: ISO-8859-15 has a pointer 249 
+PASS Not throw: ISO-8859-15 has a pointer 250 
+PASS Not throw: ISO-8859-15 has a pointer 251 
+PASS Not throw: ISO-8859-15 has a pointer 252 
+PASS Not throw: ISO-8859-15 has a pointer 253 
+PASS Not throw: ISO-8859-15 has a pointer 254 
+PASS Not throw: ISO-8859-15 has a pointer 255 
+PASS Not throw: ISO-8859-16 has a pointer 0 
+PASS Not throw: ISO-8859-16 has a pointer 1 
+PASS Not throw: ISO-8859-16 has a pointer 2 
+PASS Not throw: ISO-8859-16 has a pointer 3 
+PASS Not throw: ISO-8859-16 has a pointer 4 
+PASS Not throw: ISO-8859-16 has a pointer 5 
+PASS Not throw: ISO-8859-16 has a pointer 6 
+PASS Not throw: ISO-8859-16 has a pointer 7 
+PASS Not throw: ISO-8859-16 has a pointer 8 
+PASS Not throw: ISO-8859-16 has a pointer 9 
+PASS Not throw: ISO-8859-16 has a pointer 10 
+PASS Not throw: ISO-8859-16 has a pointer 11 
+PASS Not throw: ISO-8859-16 has a pointer 12 
+PASS Not throw: ISO-8859-16 has a pointer 13 
+PASS Not throw: ISO-8859-16 has a pointer 14 
+PASS Not throw: ISO-8859-16 has a pointer 15 
+PASS Not throw: ISO-8859-16 has a pointer 16 
+PASS Not throw: ISO-8859-16 has a pointer 17 
+PASS Not throw: ISO-8859-16 has a pointer 18 
+PASS Not throw: ISO-8859-16 has a pointer 19 
+PASS Not throw: ISO-8859-16 has a pointer 20 
+PASS Not throw: ISO-8859-16 has a pointer 21 
+PASS Not throw: ISO-8859-16 has a pointer 22 
+PASS Not throw: ISO-8859-16 has a pointer 23 
+PASS Not throw: ISO-8859-16 has a pointer 24 
+PASS Not throw: ISO-8859-16 has a pointer 25 
+PASS Not throw: ISO-8859-16 has a pointer 26 
+PASS Not throw: ISO-8859-16 has a pointer 27 
+PASS Not throw: ISO-8859-16 has a pointer 28 
+PASS Not throw: ISO-8859-16 has a pointer 29 
+PASS Not throw: ISO-8859-16 has a pointer 30 
+PASS Not throw: ISO-8859-16 has a pointer 31 
+PASS Not throw: ISO-8859-16 has a pointer 32 
+PASS Not throw: ISO-8859-16 has a pointer 33 
+PASS Not throw: ISO-8859-16 has a pointer 34 
+PASS Not throw: ISO-8859-16 has a pointer 35 
+PASS Not throw: ISO-8859-16 has a pointer 36 
+PASS Not throw: ISO-8859-16 has a pointer 37 
+PASS Not throw: ISO-8859-16 has a pointer 38 
+PASS Not throw: ISO-8859-16 has a pointer 39 
+PASS Not throw: ISO-8859-16 has a pointer 40 
+PASS Not throw: ISO-8859-16 has a pointer 41 
+PASS Not throw: ISO-8859-16 has a pointer 42 
+PASS Not throw: ISO-8859-16 has a pointer 43 
+PASS Not throw: ISO-8859-16 has a pointer 44 
+PASS Not throw: ISO-8859-16 has a pointer 45 
+PASS Not throw: ISO-8859-16 has a pointer 46 
+PASS Not throw: ISO-8859-16 has a pointer 47 
+PASS Not throw: ISO-8859-16 has a pointer 48 
+PASS Not throw: ISO-8859-16 has a pointer 49 
+PASS Not throw: ISO-8859-16 has a pointer 50 
+PASS Not throw: ISO-8859-16 has a pointer 51 
+PASS Not throw: ISO-8859-16 has a pointer 52 
+PASS Not throw: ISO-8859-16 has a pointer 53 
+PASS Not throw: ISO-8859-16 has a pointer 54 
+PASS Not throw: ISO-8859-16 has a pointer 55 
+PASS Not throw: ISO-8859-16 has a pointer 56 
+PASS Not throw: ISO-8859-16 has a pointer 57 
+PASS Not throw: ISO-8859-16 has a pointer 58 
+PASS Not throw: ISO-8859-16 has a pointer 59 
+PASS Not throw: ISO-8859-16 has a pointer 60 
+PASS Not throw: ISO-8859-16 has a pointer 61 
+PASS Not throw: ISO-8859-16 has a pointer 62 
+PASS Not throw: ISO-8859-16 has a pointer 63 
+PASS Not throw: ISO-8859-16 has a pointer 64 
+PASS Not throw: ISO-8859-16 has a pointer 65 
+PASS Not throw: ISO-8859-16 has a pointer 66 
+PASS Not throw: ISO-8859-16 has a pointer 67 
+PASS Not throw: ISO-8859-16 has a pointer 68 
+PASS Not throw: ISO-8859-16 has a pointer 69 
+PASS Not throw: ISO-8859-16 has a pointer 70 
+PASS Not throw: ISO-8859-16 has a pointer 71 
+PASS Not throw: ISO-8859-16 has a pointer 72 
+PASS Not throw: ISO-8859-16 has a pointer 73 
+PASS Not throw: ISO-8859-16 has a pointer 74 
+PASS Not throw: ISO-8859-16 has a pointer 75 
+PASS Not throw: ISO-8859-16 has a pointer 76 
+PASS Not throw: ISO-8859-16 has a pointer 77 
+PASS Not throw: ISO-8859-16 has a pointer 78 
+PASS Not throw: ISO-8859-16 has a pointer 79 
+PASS Not throw: ISO-8859-16 has a pointer 80 
+PASS Not throw: ISO-8859-16 has a pointer 81 
+PASS Not throw: ISO-8859-16 has a pointer 82 
+PASS Not throw: ISO-8859-16 has a pointer 83 
+PASS Not throw: ISO-8859-16 has a pointer 84 
+PASS Not throw: ISO-8859-16 has a pointer 85 
+PASS Not throw: ISO-8859-16 has a pointer 86 
+PASS Not throw: ISO-8859-16 has a pointer 87 
+PASS Not throw: ISO-8859-16 has a pointer 88 
+PASS Not throw: ISO-8859-16 has a pointer 89 
+PASS Not throw: ISO-8859-16 has a pointer 90 
+PASS Not throw: ISO-8859-16 has a pointer 91 
+PASS Not throw: ISO-8859-16 has a pointer 92 
+PASS Not throw: ISO-8859-16 has a pointer 93 
+PASS Not throw: ISO-8859-16 has a pointer 94 
+PASS Not throw: ISO-8859-16 has a pointer 95 
+PASS Not throw: ISO-8859-16 has a pointer 96 
+PASS Not throw: ISO-8859-16 has a pointer 97 
+PASS Not throw: ISO-8859-16 has a pointer 98 
+PASS Not throw: ISO-8859-16 has a pointer 99 
+PASS Not throw: ISO-8859-16 has a pointer 100 
+PASS Not throw: ISO-8859-16 has a pointer 101 
+PASS Not throw: ISO-8859-16 has a pointer 102 
+PASS Not throw: ISO-8859-16 has a pointer 103 
+PASS Not throw: ISO-8859-16 has a pointer 104 
+PASS Not throw: ISO-8859-16 has a pointer 105 
+PASS Not throw: ISO-8859-16 has a pointer 106 
+PASS Not throw: ISO-8859-16 has a pointer 107 
+PASS Not throw: ISO-8859-16 has a pointer 108 
+PASS Not throw: ISO-8859-16 has a pointer 109 
+PASS Not throw: ISO-8859-16 has a pointer 110 
+PASS Not throw: ISO-8859-16 has a pointer 111 
+PASS Not throw: ISO-8859-16 has a pointer 112 
+PASS Not throw: ISO-8859-16 has a pointer 113 
+PASS Not throw: ISO-8859-16 has a pointer 114 
+PASS Not throw: ISO-8859-16 has a pointer 115 
+PASS Not throw: ISO-8859-16 has a pointer 116 
+PASS Not throw: ISO-8859-16 has a pointer 117 
+PASS Not throw: ISO-8859-16 has a pointer 118 
+PASS Not throw: ISO-8859-16 has a pointer 119 
+PASS Not throw: ISO-8859-16 has a pointer 120 
+PASS Not throw: ISO-8859-16 has a pointer 121 
+PASS Not throw: ISO-8859-16 has a pointer 122 
+PASS Not throw: ISO-8859-16 has a pointer 123 
+PASS Not throw: ISO-8859-16 has a pointer 124 
+PASS Not throw: ISO-8859-16 has a pointer 125 
+PASS Not throw: ISO-8859-16 has a pointer 126 
+PASS Not throw: ISO-8859-16 has a pointer 127 
+PASS Not throw: ISO-8859-16 has a pointer 128 
+PASS Not throw: ISO-8859-16 has a pointer 129 
+PASS Not throw: ISO-8859-16 has a pointer 130 
+PASS Not throw: ISO-8859-16 has a pointer 131 
+PASS Not throw: ISO-8859-16 has a pointer 132 
+PASS Not throw: ISO-8859-16 has a pointer 133 
+PASS Not throw: ISO-8859-16 has a pointer 134 
+PASS Not throw: ISO-8859-16 has a pointer 135 
+PASS Not throw: ISO-8859-16 has a pointer 136 
+PASS Not throw: ISO-8859-16 has a pointer 137 
+PASS Not throw: ISO-8859-16 has a pointer 138 
+PASS Not throw: ISO-8859-16 has a pointer 139 
+PASS Not throw: ISO-8859-16 has a pointer 140 
+PASS Not throw: ISO-8859-16 has a pointer 141 
+PASS Not throw: ISO-8859-16 has a pointer 142 
+PASS Not throw: ISO-8859-16 has a pointer 143 
+PASS Not throw: ISO-8859-16 has a pointer 144 
+PASS Not throw: ISO-8859-16 has a pointer 145 
+PASS Not throw: ISO-8859-16 has a pointer 146 
+PASS Not throw: ISO-8859-16 has a pointer 147 
+PASS Not throw: ISO-8859-16 has a pointer 148 
+PASS Not throw: ISO-8859-16 has a pointer 149 
+PASS Not throw: ISO-8859-16 has a pointer 150 
+PASS Not throw: ISO-8859-16 has a pointer 151 
+PASS Not throw: ISO-8859-16 has a pointer 152 
+PASS Not throw: ISO-8859-16 has a pointer 153 
+PASS Not throw: ISO-8859-16 has a pointer 154 
+PASS Not throw: ISO-8859-16 has a pointer 155 
+PASS Not throw: ISO-8859-16 has a pointer 156 
+PASS Not throw: ISO-8859-16 has a pointer 157 
+PASS Not throw: ISO-8859-16 has a pointer 158 
+PASS Not throw: ISO-8859-16 has a pointer 159 
+PASS Not throw: ISO-8859-16 has a pointer 160 
+PASS Not throw: ISO-8859-16 has a pointer 161 
+PASS Not throw: ISO-8859-16 has a pointer 162 
+PASS Not throw: ISO-8859-16 has a pointer 163 
+PASS Not throw: ISO-8859-16 has a pointer 164 
+PASS Not throw: ISO-8859-16 has a pointer 165 
+PASS Not throw: ISO-8859-16 has a pointer 166 
+PASS Not throw: ISO-8859-16 has a pointer 167 
+PASS Not throw: ISO-8859-16 has a pointer 168 
+PASS Not throw: ISO-8859-16 has a pointer 169 
+PASS Not throw: ISO-8859-16 has a pointer 170 
+PASS Not throw: ISO-8859-16 has a pointer 171 
+PASS Not throw: ISO-8859-16 has a pointer 172 
+PASS Not throw: ISO-8859-16 has a pointer 173 
+PASS Not throw: ISO-8859-16 has a pointer 174 
+PASS Not throw: ISO-8859-16 has a pointer 175 
+PASS Not throw: ISO-8859-16 has a pointer 176 
+PASS Not throw: ISO-8859-16 has a pointer 177 
+PASS Not throw: ISO-8859-16 has a pointer 178 
+PASS Not throw: ISO-8859-16 has a pointer 179 
+PASS Not throw: ISO-8859-16 has a pointer 180 
+PASS Not throw: ISO-8859-16 has a pointer 181 
+PASS Not throw: ISO-8859-16 has a pointer 182 
+PASS Not throw: ISO-8859-16 has a pointer 183 
+PASS Not throw: ISO-8859-16 has a pointer 184 
+PASS Not throw: ISO-8859-16 has a pointer 185 
+PASS Not throw: ISO-8859-16 has a pointer 186 
+PASS Not throw: ISO-8859-16 has a pointer 187 
+PASS Not throw: ISO-8859-16 has a pointer 188 
+PASS Not throw: ISO-8859-16 has a pointer 189 
+PASS Not throw: ISO-8859-16 has a pointer 190 
+PASS Not throw: ISO-8859-16 has a pointer 191 
+PASS Not throw: ISO-8859-16 has a pointer 192 
+PASS Not throw: ISO-8859-16 has a pointer 193 
+PASS Not throw: ISO-8859-16 has a pointer 194 
+PASS Not throw: ISO-8859-16 has a pointer 195 
+PASS Not throw: ISO-8859-16 has a pointer 196 
+PASS Not throw: ISO-8859-16 has a pointer 197 
+PASS Not throw: ISO-8859-16 has a pointer 198 
+PASS Not throw: ISO-8859-16 has a pointer 199 
+PASS Not throw: ISO-8859-16 has a pointer 200 
+PASS Not throw: ISO-8859-16 has a pointer 201 
+PASS Not throw: ISO-8859-16 has a pointer 202 
+PASS Not throw: ISO-8859-16 has a pointer 203 
+PASS Not throw: ISO-8859-16 has a pointer 204 
+PASS Not throw: ISO-8859-16 has a pointer 205 
+PASS Not throw: ISO-8859-16 has a pointer 206 
+PASS Not throw: ISO-8859-16 has a pointer 207 
+PASS Not throw: ISO-8859-16 has a pointer 208 
+PASS Not throw: ISO-8859-16 has a pointer 209 
+PASS Not throw: ISO-8859-16 has a pointer 210 
+PASS Not throw: ISO-8859-16 has a pointer 211 
+PASS Not throw: ISO-8859-16 has a pointer 212 
+PASS Not throw: ISO-8859-16 has a pointer 213 
+PASS Not throw: ISO-8859-16 has a pointer 214 
+PASS Not throw: ISO-8859-16 has a pointer 215 
+PASS Not throw: ISO-8859-16 has a pointer 216 
+PASS Not throw: ISO-8859-16 has a pointer 217 
+PASS Not throw: ISO-8859-16 has a pointer 218 
+PASS Not throw: ISO-8859-16 has a pointer 219 
+PASS Not throw: ISO-8859-16 has a pointer 220 
+PASS Not throw: ISO-8859-16 has a pointer 221 
+PASS Not throw: ISO-8859-16 has a pointer 222 
+PASS Not throw: ISO-8859-16 has a pointer 223 
+PASS Not throw: ISO-8859-16 has a pointer 224 
+PASS Not throw: ISO-8859-16 has a pointer 225 
+PASS Not throw: ISO-8859-16 has a pointer 226 
+PASS Not throw: ISO-8859-16 has a pointer 227 
+PASS Not throw: ISO-8859-16 has a pointer 228 
+PASS Not throw: ISO-8859-16 has a pointer 229 
+PASS Not throw: ISO-8859-16 has a pointer 230 
+PASS Not throw: ISO-8859-16 has a pointer 231 
+PASS Not throw: ISO-8859-16 has a pointer 232 
+PASS Not throw: ISO-8859-16 has a pointer 233 
+PASS Not throw: ISO-8859-16 has a pointer 234 
+PASS Not throw: ISO-8859-16 has a pointer 235 
+PASS Not throw: ISO-8859-16 has a pointer 236 
+PASS Not throw: ISO-8859-16 has a pointer 237 
+PASS Not throw: ISO-8859-16 has a pointer 238 
+PASS Not throw: ISO-8859-16 has a pointer 239 
+PASS Not throw: ISO-8859-16 has a pointer 240 
+PASS Not throw: ISO-8859-16 has a pointer 241 
+PASS Not throw: ISO-8859-16 has a pointer 242 
+PASS Not throw: ISO-8859-16 has a pointer 243 
+PASS Not throw: ISO-8859-16 has a pointer 244 
+PASS Not throw: ISO-8859-16 has a pointer 245 
+PASS Not throw: ISO-8859-16 has a pointer 246 
+PASS Not throw: ISO-8859-16 has a pointer 247 
+PASS Not throw: ISO-8859-16 has a pointer 248 
+PASS Not throw: ISO-8859-16 has a pointer 249 
+PASS Not throw: ISO-8859-16 has a pointer 250 
+PASS Not throw: ISO-8859-16 has a pointer 251 
+PASS Not throw: ISO-8859-16 has a pointer 252 
+PASS Not throw: ISO-8859-16 has a pointer 253 
+PASS Not throw: ISO-8859-16 has a pointer 254 
+PASS Not throw: ISO-8859-16 has a pointer 255 
+PASS Not throw: KOI8-R has a pointer 0 
+PASS Not throw: KOI8-R has a pointer 1 
+PASS Not throw: KOI8-R has a pointer 2 
+PASS Not throw: KOI8-R has a pointer 3 
+PASS Not throw: KOI8-R has a pointer 4 
+PASS Not throw: KOI8-R has a pointer 5 
+PASS Not throw: KOI8-R has a pointer 6 
+PASS Not throw: KOI8-R has a pointer 7 
+PASS Not throw: KOI8-R has a pointer 8 
+PASS Not throw: KOI8-R has a pointer 9 
+PASS Not throw: KOI8-R has a pointer 10 
+PASS Not throw: KOI8-R has a pointer 11 
+PASS Not throw: KOI8-R has a pointer 12 
+PASS Not throw: KOI8-R has a pointer 13 
+PASS Not throw: KOI8-R has a pointer 14 
+PASS Not throw: KOI8-R has a pointer 15 
+PASS Not throw: KOI8-R has a pointer 16 
+PASS Not throw: KOI8-R has a pointer 17 
+PASS Not throw: KOI8-R has a pointer 18 
+PASS Not throw: KOI8-R has a pointer 19 
+PASS Not throw: KOI8-R has a pointer 20 
+PASS Not throw: KOI8-R has a pointer 21 
+PASS Not throw: KOI8-R has a pointer 22 
+PASS Not throw: KOI8-R has a pointer 23 
+PASS Not throw: KOI8-R has a pointer 24 
+PASS Not throw: KOI8-R has a pointer 25 
+PASS Not throw: KOI8-R has a pointer 26 
+PASS Not throw: KOI8-R has a pointer 27 
+PASS Not throw: KOI8-R has a pointer 28 
+PASS Not throw: KOI8-R has a pointer 29 
+PASS Not throw: KOI8-R has a pointer 30 
+PASS Not throw: KOI8-R has a pointer 31 
+PASS Not throw: KOI8-R has a pointer 32 
+PASS Not throw: KOI8-R has a pointer 33 
+PASS Not throw: KOI8-R has a pointer 34 
+PASS Not throw: KOI8-R has a pointer 35 
+PASS Not throw: KOI8-R has a pointer 36 
+PASS Not throw: KOI8-R has a pointer 37 
+PASS Not throw: KOI8-R has a pointer 38 
+PASS Not throw: KOI8-R has a pointer 39 
+PASS Not throw: KOI8-R has a pointer 40 
+PASS Not throw: KOI8-R has a pointer 41 
+PASS Not throw: KOI8-R has a pointer 42 
+PASS Not throw: KOI8-R has a pointer 43 
+PASS Not throw: KOI8-R has a pointer 44 
+PASS Not throw: KOI8-R has a pointer 45 
+PASS Not throw: KOI8-R has a pointer 46 
+PASS Not throw: KOI8-R has a pointer 47 
+PASS Not throw: KOI8-R has a pointer 48 
+PASS Not throw: KOI8-R has a pointer 49 
+PASS Not throw: KOI8-R has a pointer 50 
+PASS Not throw: KOI8-R has a pointer 51 
+PASS Not throw: KOI8-R has a pointer 52 
+PASS Not throw: KOI8-R has a pointer 53 
+PASS Not throw: KOI8-R has a pointer 54 
+PASS Not throw: KOI8-R has a pointer 55 
+PASS Not throw: KOI8-R has a pointer 56 
+PASS Not throw: KOI8-R has a pointer 57 
+PASS Not throw: KOI8-R has a pointer 58 
+PASS Not throw: KOI8-R has a pointer 59 
+PASS Not throw: KOI8-R has a pointer 60 
+PASS Not throw: KOI8-R has a pointer 61 
+PASS Not throw: KOI8-R has a pointer 62 
+PASS Not throw: KOI8-R has a pointer 63 
+PASS Not throw: KOI8-R has a pointer 64 
+PASS Not throw: KOI8-R has a pointer 65 
+PASS Not throw: KOI8-R has a pointer 66 
+PASS Not throw: KOI8-R has a pointer 67 
+PASS Not throw: KOI8-R has a pointer 68 
+PASS Not throw: KOI8-R has a pointer 69 
+PASS Not throw: KOI8-R has a pointer 70 
+PASS Not throw: KOI8-R has a pointer 71 
+PASS Not throw: KOI8-R has a pointer 72 
+PASS Not throw: KOI8-R has a pointer 73 
+PASS Not throw: KOI8-R has a pointer 74 
+PASS Not throw: KOI8-R has a pointer 75 
+PASS Not throw: KOI8-R has a pointer 76 
+PASS Not throw: KOI8-R has a pointer 77 
+PASS Not throw: KOI8-R has a pointer 78 
+PASS Not throw: KOI8-R has a pointer 79 
+PASS Not throw: KOI8-R has a pointer 80 
+PASS Not throw: KOI8-R has a pointer 81 
+PASS Not throw: KOI8-R has a pointer 82 
+PASS Not throw: KOI8-R has a pointer 83 
+PASS Not throw: KOI8-R has a pointer 84 
+PASS Not throw: KOI8-R has a pointer 85 
+PASS Not throw: KOI8-R has a pointer 86 
+PASS Not throw: KOI8-R has a pointer 87 
+PASS Not throw: KOI8-R has a pointer 88 
+PASS Not throw: KOI8-R has a pointer 89 
+PASS Not throw: KOI8-R has a pointer 90 
+PASS Not throw: KOI8-R has a pointer 91 
+PASS Not throw: KOI8-R has a pointer 92 
+PASS Not throw: KOI8-R has a pointer 93 
+PASS Not throw: KOI8-R has a pointer 94 
+PASS Not throw: KOI8-R has a pointer 95 
+PASS Not throw: KOI8-R has a pointer 96 
+PASS Not throw: KOI8-R has a pointer 97 
+PASS Not throw: KOI8-R has a pointer 98 
+PASS Not throw: KOI8-R has a pointer 99 
+PASS Not throw: KOI8-R has a pointer 100 
+PASS Not throw: KOI8-R has a pointer 101 
+PASS Not throw: KOI8-R has a pointer 102 
+PASS Not throw: KOI8-R has a pointer 103 
+PASS Not throw: KOI8-R has a pointer 104 
+PASS Not throw: KOI8-R has a pointer 105 
+PASS Not throw: KOI8-R has a pointer 106 
+PASS Not throw: KOI8-R has a pointer 107 
+PASS Not throw: KOI8-R has a pointer 108 
+PASS Not throw: KOI8-R has a pointer 109 
+PASS Not throw: KOI8-R has a pointer 110 
+PASS Not throw: KOI8-R has a pointer 111 
+PASS Not throw: KOI8-R has a pointer 112 
+PASS Not throw: KOI8-R has a pointer 113 
+PASS Not throw: KOI8-R has a pointer 114 
+PASS Not throw: KOI8-R has a pointer 115 
+PASS Not throw: KOI8-R has a pointer 116 
+PASS Not throw: KOI8-R has a pointer 117 
+PASS Not throw: KOI8-R has a pointer 118 
+PASS Not throw: KOI8-R has a pointer 119 
+PASS Not throw: KOI8-R has a pointer 120 
+PASS Not throw: KOI8-R has a pointer 121 
+PASS Not throw: KOI8-R has a pointer 122 
+PASS Not throw: KOI8-R has a pointer 123 
+PASS Not throw: KOI8-R has a pointer 124 
+PASS Not throw: KOI8-R has a pointer 125 
+PASS Not throw: KOI8-R has a pointer 126 
+PASS Not throw: KOI8-R has a pointer 127 
+PASS Not throw: KOI8-R has a pointer 128 
+PASS Not throw: KOI8-R has a pointer 129 
+PASS Not throw: KOI8-R has a pointer 130 
+PASS Not throw: KOI8-R has a pointer 131 
+PASS Not throw: KOI8-R has a pointer 132 
+PASS Not throw: KOI8-R has a pointer 133 
+PASS Not throw: KOI8-R has a pointer 134 
+PASS Not throw: KOI8-R has a pointer 135 
+PASS Not throw: KOI8-R has a pointer 136 
+PASS Not throw: KOI8-R has a pointer 137 
+PASS Not throw: KOI8-R has a pointer 138 
+PASS Not throw: KOI8-R has a pointer 139 
+PASS Not throw: KOI8-R has a pointer 140 
+PASS Not throw: KOI8-R has a pointer 141 
+PASS Not throw: KOI8-R has a pointer 142 
+PASS Not throw: KOI8-R has a pointer 143 
+PASS Not throw: KOI8-R has a pointer 144 
+PASS Not throw: KOI8-R has a pointer 145 
+PASS Not throw: KOI8-R has a pointer 146 
+PASS Not throw: KOI8-R has a pointer 147 
+PASS Not throw: KOI8-R has a pointer 148 
+PASS Not throw: KOI8-R has a pointer 149 
+PASS Not throw: KOI8-R has a pointer 150 
+PASS Not throw: KOI8-R has a pointer 151 
+PASS Not throw: KOI8-R has a pointer 152 
+PASS Not throw: KOI8-R has a pointer 153 
+PASS Not throw: KOI8-R has a pointer 154 
+PASS Not throw: KOI8-R has a pointer 155 
+PASS Not throw: KOI8-R has a pointer 156 
+PASS Not throw: KOI8-R has a pointer 157 
+PASS Not throw: KOI8-R has a pointer 158 
+PASS Not throw: KOI8-R has a pointer 159 
+PASS Not throw: KOI8-R has a pointer 160 
+PASS Not throw: KOI8-R has a pointer 161 
+PASS Not throw: KOI8-R has a pointer 162 
+PASS Not throw: KOI8-R has a pointer 163 
+PASS Not throw: KOI8-R has a pointer 164 
+PASS Not throw: KOI8-R has a pointer 165 
+PASS Not throw: KOI8-R has a pointer 166 
+PASS Not throw: KOI8-R has a pointer 167 
+PASS Not throw: KOI8-R has a pointer 168 
+PASS Not throw: KOI8-R has a pointer 169 
+PASS Not throw: KOI8-R has a pointer 170 
+PASS Not throw: KOI8-R has a pointer 171 
+PASS Not throw: KOI8-R has a pointer 172 
+PASS Not throw: KOI8-R has a pointer 173 
+PASS Not throw: KOI8-R has a pointer 174 
+PASS Not throw: KOI8-R has a pointer 175 
+PASS Not throw: KOI8-R has a pointer 176 
+PASS Not throw: KOI8-R has a pointer 177 
+PASS Not throw: KOI8-R has a pointer 178 
+PASS Not throw: KOI8-R has a pointer 179 
+PASS Not throw: KOI8-R has a pointer 180 
+PASS Not throw: KOI8-R has a pointer 181 
+PASS Not throw: KOI8-R has a pointer 182 
+PASS Not throw: KOI8-R has a pointer 183 
+PASS Not throw: KOI8-R has a pointer 184 
+PASS Not throw: KOI8-R has a pointer 185 
+PASS Not throw: KOI8-R has a pointer 186 
+PASS Not throw: KOI8-R has a pointer 187 
+PASS Not throw: KOI8-R has a pointer 188 
+PASS Not throw: KOI8-R has a pointer 189 
+PASS Not throw: KOI8-R has a pointer 190 
+PASS Not throw: KOI8-R has a pointer 191 
+PASS Not throw: KOI8-R has a pointer 192 
+PASS Not throw: KOI8-R has a pointer 193 
+PASS Not throw: KOI8-R has a pointer 194 
+PASS Not throw: KOI8-R has a pointer 195 
+PASS Not throw: KOI8-R has a pointer 196 
+PASS Not throw: KOI8-R has a pointer 197 
+PASS Not throw: KOI8-R has a pointer 198 
+PASS Not throw: KOI8-R has a pointer 199 
+PASS Not throw: KOI8-R has a pointer 200 
+PASS Not throw: KOI8-R has a pointer 201 
+PASS Not throw: KOI8-R has a pointer 202 
+PASS Not throw: KOI8-R has a pointer 203 
+PASS Not throw: KOI8-R has a pointer 204 
+PASS Not throw: KOI8-R has a pointer 205 
+PASS Not throw: KOI8-R has a pointer 206 
+PASS Not throw: KOI8-R has a pointer 207 
+PASS Not throw: KOI8-R has a pointer 208 
+PASS Not throw: KOI8-R has a pointer 209 
+PASS Not throw: KOI8-R has a pointer 210 
+PASS Not throw: KOI8-R has a pointer 211 
+PASS Not throw: KOI8-R has a pointer 212 
+PASS Not throw: KOI8-R has a pointer 213 
+PASS Not throw: KOI8-R has a pointer 214 
+PASS Not throw: KOI8-R has a pointer 215 
+PASS Not throw: KOI8-R has a pointer 216 
+PASS Not throw: KOI8-R has a pointer 217 
+PASS Not throw: KOI8-R has a pointer 218 
+PASS Not throw: KOI8-R has a pointer 219 
+PASS Not throw: KOI8-R has a pointer 220 
+PASS Not throw: KOI8-R has a pointer 221 
+PASS Not throw: KOI8-R has a pointer 222 
+PASS Not throw: KOI8-R has a pointer 223 
+PASS Not throw: KOI8-R has a pointer 224 
+PASS Not throw: KOI8-R has a pointer 225 
+PASS Not throw: KOI8-R has a pointer 226 
+PASS Not throw: KOI8-R has a pointer 227 
+PASS Not throw: KOI8-R has a pointer 228 
+PASS Not throw: KOI8-R has a pointer 229 
+PASS Not throw: KOI8-R has a pointer 230 
+PASS Not throw: KOI8-R has a pointer 231 
+PASS Not throw: KOI8-R has a pointer 232 
+PASS Not throw: KOI8-R has a pointer 233 
+PASS Not throw: KOI8-R has a pointer 234 
+PASS Not throw: KOI8-R has a pointer 235 
+PASS Not throw: KOI8-R has a pointer 236 
+PASS Not throw: KOI8-R has a pointer 237 
+PASS Not throw: KOI8-R has a pointer 238 
+PASS Not throw: KOI8-R has a pointer 239 
+PASS Not throw: KOI8-R has a pointer 240 
+PASS Not throw: KOI8-R has a pointer 241 
+PASS Not throw: KOI8-R has a pointer 242 
+PASS Not throw: KOI8-R has a pointer 243 
+PASS Not throw: KOI8-R has a pointer 244 
+PASS Not throw: KOI8-R has a pointer 245 
+PASS Not throw: KOI8-R has a pointer 246 
+PASS Not throw: KOI8-R has a pointer 247 
+PASS Not throw: KOI8-R has a pointer 248 
+PASS Not throw: KOI8-R has a pointer 249 
+PASS Not throw: KOI8-R has a pointer 250 
+PASS Not throw: KOI8-R has a pointer 251 
+PASS Not throw: KOI8-R has a pointer 252 
+PASS Not throw: KOI8-R has a pointer 253 
+PASS Not throw: KOI8-R has a pointer 254 
+PASS Not throw: KOI8-R has a pointer 255 
+PASS Not throw: KOI8-U has a pointer 0 
+PASS Not throw: KOI8-U has a pointer 1 
+PASS Not throw: KOI8-U has a pointer 2 
+PASS Not throw: KOI8-U has a pointer 3 
+PASS Not throw: KOI8-U has a pointer 4 
+PASS Not throw: KOI8-U has a pointer 5 
+PASS Not throw: KOI8-U has a pointer 6 
+PASS Not throw: KOI8-U has a pointer 7 
+PASS Not throw: KOI8-U has a pointer 8 
+PASS Not throw: KOI8-U has a pointer 9 
+PASS Not throw: KOI8-U has a pointer 10 
+PASS Not throw: KOI8-U has a pointer 11 
+PASS Not throw: KOI8-U has a pointer 12 
+PASS Not throw: KOI8-U has a pointer 13 
+PASS Not throw: KOI8-U has a pointer 14 
+PASS Not throw: KOI8-U has a pointer 15 
+PASS Not throw: KOI8-U has a pointer 16 
+PASS Not throw: KOI8-U has a pointer 17 
+PASS Not throw: KOI8-U has a pointer 18 
+PASS Not throw: KOI8-U has a pointer 19 
+PASS Not throw: KOI8-U has a pointer 20 
+PASS Not throw: KOI8-U has a pointer 21 
+PASS Not throw: KOI8-U has a pointer 22 
+PASS Not throw: KOI8-U has a pointer 23 
+PASS Not throw: KOI8-U has a pointer 24 
+PASS Not throw: KOI8-U has a pointer 25 
+PASS Not throw: KOI8-U has a pointer 26 
+PASS Not throw: KOI8-U has a pointer 27 
+PASS Not throw: KOI8-U has a pointer 28 
+PASS Not throw: KOI8-U has a pointer 29 
+PASS Not throw: KOI8-U has a pointer 30 
+PASS Not throw: KOI8-U has a pointer 31 
+PASS Not throw: KOI8-U has a pointer 32 
+PASS Not throw: KOI8-U has a pointer 33 
+PASS Not throw: KOI8-U has a pointer 34 
+PASS Not throw: KOI8-U has a pointer 35 
+PASS Not throw: KOI8-U has a pointer 36 
+PASS Not throw: KOI8-U has a pointer 37 
+PASS Not throw: KOI8-U has a pointer 38 
+PASS Not throw: KOI8-U has a pointer 39 
+PASS Not throw: KOI8-U has a pointer 40 
+PASS Not throw: KOI8-U has a pointer 41 
+PASS Not throw: KOI8-U has a pointer 42 
+PASS Not throw: KOI8-U has a pointer 43 
+PASS Not throw: KOI8-U has a pointer 44 
+PASS Not throw: KOI8-U has a pointer 45 
+PASS Not throw: KOI8-U has a pointer 46 
+PASS Not throw: KOI8-U has a pointer 47 
+PASS Not throw: KOI8-U has a pointer 48 
+PASS Not throw: KOI8-U has a pointer 49 
+PASS Not throw: KOI8-U has a pointer 50 
+PASS Not throw: KOI8-U has a pointer 51 
+PASS Not throw: KOI8-U has a pointer 52 
+PASS Not throw: KOI8-U has a pointer 53 
+PASS Not throw: KOI8-U has a pointer 54 
+PASS Not throw: KOI8-U has a pointer 55 
+PASS Not throw: KOI8-U has a pointer 56 
+PASS Not throw: KOI8-U has a pointer 57 
+PASS Not throw: KOI8-U has a pointer 58 
+PASS Not throw: KOI8-U has a pointer 59 
+PASS Not throw: KOI8-U has a pointer 60 
+PASS Not throw: KOI8-U has a pointer 61 
+PASS Not throw: KOI8-U has a pointer 62 
+PASS Not throw: KOI8-U has a pointer 63 
+PASS Not throw: KOI8-U has a pointer 64 
+PASS Not throw: KOI8-U has a pointer 65 
+PASS Not throw: KOI8-U has a pointer 66 
+PASS Not throw: KOI8-U has a pointer 67 
+PASS Not throw: KOI8-U has a pointer 68 
+PASS Not throw: KOI8-U has a pointer 69 
+PASS Not throw: KOI8-U has a pointer 70 
+PASS Not throw: KOI8-U has a pointer 71 
+PASS Not throw: KOI8-U has a pointer 72 
+PASS Not throw: KOI8-U has a pointer 73 
+PASS Not throw: KOI8-U has a pointer 74 
+PASS Not throw: KOI8-U has a pointer 75 
+PASS Not throw: KOI8-U has a pointer 76 
+PASS Not throw: KOI8-U has a pointer 77 
+PASS Not throw: KOI8-U has a pointer 78 
+PASS Not throw: KOI8-U has a pointer 79 
+PASS Not throw: KOI8-U has a pointer 80 
+PASS Not throw: KOI8-U has a pointer 81 
+PASS Not throw: KOI8-U has a pointer 82 
+PASS Not throw: KOI8-U has a pointer 83 
+PASS Not throw: KOI8-U has a pointer 84 
+PASS Not throw: KOI8-U has a pointer 85 
+PASS Not throw: KOI8-U has a pointer 86 
+PASS Not throw: KOI8-U has a pointer 87 
+PASS Not throw: KOI8-U has a pointer 88 
+PASS Not throw: KOI8-U has a pointer 89 
+PASS Not throw: KOI8-U has a pointer 90 
+PASS Not throw: KOI8-U has a pointer 91 
+PASS Not throw: KOI8-U has a pointer 92 
+PASS Not throw: KOI8-U has a pointer 93 
+PASS Not throw: KOI8-U has a pointer 94 
+PASS Not throw: KOI8-U has a pointer 95 
+PASS Not throw: KOI8-U has a pointer 96 
+PASS Not throw: KOI8-U has a pointer 97 
+PASS Not throw: KOI8-U has a pointer 98 
+PASS Not throw: KOI8-U has a pointer 99 
+PASS Not throw: KOI8-U has a pointer 100 
+PASS Not throw: KOI8-U has a pointer 101 
+PASS Not throw: KOI8-U has a pointer 102 
+PASS Not throw: KOI8-U has a pointer 103 
+PASS Not throw: KOI8-U has a pointer 104 
+PASS Not throw: KOI8-U has a pointer 105 
+PASS Not throw: KOI8-U has a pointer 106 
+PASS Not throw: KOI8-U has a pointer 107 
+PASS Not throw: KOI8-U has a pointer 108 
+PASS Not throw: KOI8-U has a pointer 109 
+PASS Not throw: KOI8-U has a pointer 110 
+PASS Not throw: KOI8-U has a pointer 111 
+PASS Not throw: KOI8-U has a pointer 112 
+PASS Not throw: KOI8-U has a pointer 113 
+PASS Not throw: KOI8-U has a pointer 114 
+PASS Not throw: KOI8-U has a pointer 115 
+PASS Not throw: KOI8-U has a pointer 116 
+PASS Not throw: KOI8-U has a pointer 117 
+PASS Not throw: KOI8-U has a pointer 118 
+PASS Not throw: KOI8-U has a pointer 119 
+PASS Not throw: KOI8-U has a pointer 120 
+PASS Not throw: KOI8-U has a pointer 121 
+PASS Not throw: KOI8-U has a pointer 122 
+PASS Not throw: KOI8-U has a pointer 123 
+PASS Not throw: KOI8-U has a pointer 124 
+PASS Not throw: KOI8-U has a pointer 125 
+PASS Not throw: KOI8-U has a pointer 126 
+PASS Not throw: KOI8-U has a pointer 127 
+PASS Not throw: KOI8-U has a pointer 128 
+PASS Not throw: KOI8-U has a pointer 129 
+PASS Not throw: KOI8-U has a pointer 130 
+PASS Not throw: KOI8-U has a pointer 131 
+PASS Not throw: KOI8-U has a pointer 132 
+PASS Not throw: KOI8-U has a pointer 133 
+PASS Not throw: KOI8-U has a pointer 134 
+PASS Not throw: KOI8-U has a pointer 135 
+PASS Not throw: KOI8-U has a pointer 136 
+PASS Not throw: KOI8-U has a pointer 137 
+PASS Not throw: KOI8-U has a pointer 138 
+PASS Not throw: KOI8-U has a pointer 139 
+PASS Not throw: KOI8-U has a pointer 140 
+PASS Not throw: KOI8-U has a pointer 141 
+PASS Not throw: KOI8-U has a pointer 142 
+PASS Not throw: KOI8-U has a pointer 143 
+PASS Not throw: KOI8-U has a pointer 144 
+PASS Not throw: KOI8-U has a pointer 145 
+PASS Not throw: KOI8-U has a pointer 146 
+PASS Not throw: KOI8-U has a pointer 147 
+PASS Not throw: KOI8-U has a pointer 148 
+PASS Not throw: KOI8-U has a pointer 149 
+PASS Not throw: KOI8-U has a pointer 150 
+PASS Not throw: KOI8-U has a pointer 151 
+PASS Not throw: KOI8-U has a pointer 152 
+PASS Not throw: KOI8-U has a pointer 153 
+PASS Not throw: KOI8-U has a pointer 154 
+PASS Not throw: KOI8-U has a pointer 155 
+PASS Not throw: KOI8-U has a pointer 156 
+PASS Not throw: KOI8-U has a pointer 157 
+PASS Not throw: KOI8-U has a pointer 158 
+PASS Not throw: KOI8-U has a pointer 159 
+PASS Not throw: KOI8-U has a pointer 160 
+PASS Not throw: KOI8-U has a pointer 161 
+PASS Not throw: KOI8-U has a pointer 162 
+PASS Not throw: KOI8-U has a pointer 163 
+PASS Not throw: KOI8-U has a pointer 164 
+PASS Not throw: KOI8-U has a pointer 165 
+PASS Not throw: KOI8-U has a pointer 166 
+PASS Not throw: KOI8-U has a pointer 167 
+PASS Not throw: KOI8-U has a pointer 168 
+PASS Not throw: KOI8-U has a pointer 169 
+PASS Not throw: KOI8-U has a pointer 170 
+PASS Not throw: KOI8-U has a pointer 171 
+PASS Not throw: KOI8-U has a pointer 172 
+PASS Not throw: KOI8-U has a pointer 173 
+PASS Not throw: KOI8-U has a pointer 174 
+PASS Not throw: KOI8-U has a pointer 175 
+PASS Not throw: KOI8-U has a pointer 176 
+PASS Not throw: KOI8-U has a pointer 177 
+PASS Not throw: KOI8-U has a pointer 178 
+PASS Not throw: KOI8-U has a pointer 179 
+PASS Not throw: KOI8-U has a pointer 180 
+PASS Not throw: KOI8-U has a pointer 181 
+PASS Not throw: KOI8-U has a pointer 182 
+PASS Not throw: KOI8-U has a pointer 183 
+PASS Not throw: KOI8-U has a pointer 184 
+PASS Not throw: KOI8-U has a pointer 185 
+PASS Not throw: KOI8-U has a pointer 186 
+PASS Not throw: KOI8-U has a pointer 187 
+PASS Not throw: KOI8-U has a pointer 188 
+PASS Not throw: KOI8-U has a pointer 189 
+PASS Not throw: KOI8-U has a pointer 190 
+PASS Not throw: KOI8-U has a pointer 191 
+PASS Not throw: KOI8-U has a pointer 192 
+PASS Not throw: KOI8-U has a pointer 193 
+PASS Not throw: KOI8-U has a pointer 194 
+PASS Not throw: KOI8-U has a pointer 195 
+PASS Not throw: KOI8-U has a pointer 196 
+PASS Not throw: KOI8-U has a pointer 197 
+PASS Not throw: KOI8-U has a pointer 198 
+PASS Not throw: KOI8-U has a pointer 199 
+PASS Not throw: KOI8-U has a pointer 200 
+PASS Not throw: KOI8-U has a pointer 201 
+PASS Not throw: KOI8-U has a pointer 202 
+PASS Not throw: KOI8-U has a pointer 203 
+PASS Not throw: KOI8-U has a pointer 204 
+PASS Not throw: KOI8-U has a pointer 205 
+PASS Not throw: KOI8-U has a pointer 206 
+PASS Not throw: KOI8-U has a pointer 207 
+PASS Not throw: KOI8-U has a pointer 208 
+PASS Not throw: KOI8-U has a pointer 209 
+PASS Not throw: KOI8-U has a pointer 210 
+PASS Not throw: KOI8-U has a pointer 211 
+PASS Not throw: KOI8-U has a pointer 212 
+PASS Not throw: KOI8-U has a pointer 213 
+PASS Not throw: KOI8-U has a pointer 214 
+PASS Not throw: KOI8-U has a pointer 215 
+PASS Not throw: KOI8-U has a pointer 216 
+PASS Not throw: KOI8-U has a pointer 217 
+PASS Not throw: KOI8-U has a pointer 218 
+PASS Not throw: KOI8-U has a pointer 219 
+PASS Not throw: KOI8-U has a pointer 220 
+PASS Not throw: KOI8-U has a pointer 221 
+PASS Not throw: KOI8-U has a pointer 222 
+PASS Not throw: KOI8-U has a pointer 223 
+PASS Not throw: KOI8-U has a pointer 224 
+PASS Not throw: KOI8-U has a pointer 225 
+PASS Not throw: KOI8-U has a pointer 226 
+PASS Not throw: KOI8-U has a pointer 227 
+PASS Not throw: KOI8-U has a pointer 228 
+PASS Not throw: KOI8-U has a pointer 229 
+PASS Not throw: KOI8-U has a pointer 230 
+PASS Not throw: KOI8-U has a pointer 231 
+PASS Not throw: KOI8-U has a pointer 232 
+PASS Not throw: KOI8-U has a pointer 233 
+PASS Not throw: KOI8-U has a pointer 234 
+PASS Not throw: KOI8-U has a pointer 235 
+PASS Not throw: KOI8-U has a pointer 236 
+PASS Not throw: KOI8-U has a pointer 237 
+PASS Not throw: KOI8-U has a pointer 238 
+PASS Not throw: KOI8-U has a pointer 239 
+PASS Not throw: KOI8-U has a pointer 240 
+PASS Not throw: KOI8-U has a pointer 241 
+PASS Not throw: KOI8-U has a pointer 242 
+PASS Not throw: KOI8-U has a pointer 243 
+PASS Not throw: KOI8-U has a pointer 244 
+PASS Not throw: KOI8-U has a pointer 245 
+PASS Not throw: KOI8-U has a pointer 246 
+PASS Not throw: KOI8-U has a pointer 247 
+PASS Not throw: KOI8-U has a pointer 248 
+PASS Not throw: KOI8-U has a pointer 249 
+PASS Not throw: KOI8-U has a pointer 250 
+PASS Not throw: KOI8-U has a pointer 251 
+PASS Not throw: KOI8-U has a pointer 252 
+PASS Not throw: KOI8-U has a pointer 253 
+PASS Not throw: KOI8-U has a pointer 254 
+PASS Not throw: KOI8-U has a pointer 255 
+PASS Not throw: macintosh has a pointer 0 
+PASS Not throw: macintosh has a pointer 1 
+PASS Not throw: macintosh has a pointer 2 
+PASS Not throw: macintosh has a pointer 3 
+PASS Not throw: macintosh has a pointer 4 
+PASS Not throw: macintosh has a pointer 5 
+PASS Not throw: macintosh has a pointer 6 
+PASS Not throw: macintosh has a pointer 7 
+PASS Not throw: macintosh has a pointer 8 
+PASS Not throw: macintosh has a pointer 9 
+PASS Not throw: macintosh has a pointer 10 
+PASS Not throw: macintosh has a pointer 11 
+PASS Not throw: macintosh has a pointer 12 
+PASS Not throw: macintosh has a pointer 13 
+PASS Not throw: macintosh has a pointer 14 
+PASS Not throw: macintosh has a pointer 15 
+PASS Not throw: macintosh has a pointer 16 
+PASS Not throw: macintosh has a pointer 17 
+PASS Not throw: macintosh has a pointer 18 
+PASS Not throw: macintosh has a pointer 19 
+PASS Not throw: macintosh has a pointer 20 
+PASS Not throw: macintosh has a pointer 21 
+PASS Not throw: macintosh has a pointer 22 
+PASS Not throw: macintosh has a pointer 23 
+PASS Not throw: macintosh has a pointer 24 
+PASS Not throw: macintosh has a pointer 25 
+PASS Not throw: macintosh has a pointer 26 
+PASS Not throw: macintosh has a pointer 27 
+PASS Not throw: macintosh has a pointer 28 
+PASS Not throw: macintosh has a pointer 29 
+PASS Not throw: macintosh has a pointer 30 
+PASS Not throw: macintosh has a pointer 31 
+PASS Not throw: macintosh has a pointer 32 
+PASS Not throw: macintosh has a pointer 33 
+PASS Not throw: macintosh has a pointer 34 
+PASS Not throw: macintosh has a pointer 35 
+PASS Not throw: macintosh has a pointer 36 
+PASS Not throw: macintosh has a pointer 37 
+PASS Not throw: macintosh has a pointer 38 
+PASS Not throw: macintosh has a pointer 39 
+PASS Not throw: macintosh has a pointer 40 
+PASS Not throw: macintosh has a pointer 41 
+PASS Not throw: macintosh has a pointer 42 
+PASS Not throw: macintosh has a pointer 43 
+PASS Not throw: macintosh has a pointer 44 
+PASS Not throw: macintosh has a pointer 45 
+PASS Not throw: macintosh has a pointer 46 
+PASS Not throw: macintosh has a pointer 47 
+PASS Not throw: macintosh has a pointer 48 
+PASS Not throw: macintosh has a pointer 49 
+PASS Not throw: macintosh has a pointer 50 
+PASS Not throw: macintosh has a pointer 51 
+PASS Not throw: macintosh has a pointer 52 
+PASS Not throw: macintosh has a pointer 53 
+PASS Not throw: macintosh has a pointer 54 
+PASS Not throw: macintosh has a pointer 55 
+PASS Not throw: macintosh has a pointer 56 
+PASS Not throw: macintosh has a pointer 57 
+PASS Not throw: macintosh has a pointer 58 
+PASS Not throw: macintosh has a pointer 59 
+PASS Not throw: macintosh has a pointer 60 
+PASS Not throw: macintosh has a pointer 61 
+PASS Not throw: macintosh has a pointer 62 
+PASS Not throw: macintosh has a pointer 63 
+PASS Not throw: macintosh has a pointer 64 
+PASS Not throw: macintosh has a pointer 65 
+PASS Not throw: macintosh has a pointer 66 
+PASS Not throw: macintosh has a pointer 67 
+PASS Not throw: macintosh has a pointer 68 
+PASS Not throw: macintosh has a pointer 69 
+PASS Not throw: macintosh has a pointer 70 
+PASS Not throw: macintosh has a pointer 71 
+PASS Not throw: macintosh has a pointer 72 
+PASS Not throw: macintosh has a pointer 73 
+PASS Not throw: macintosh has a pointer 74 
+PASS Not throw: macintosh has a pointer 75 
+PASS Not throw: macintosh has a pointer 76 
+PASS Not throw: macintosh has a pointer 77 
+PASS Not throw: macintosh has a pointer 78 
+PASS Not throw: macintosh has a pointer 79 
+PASS Not throw: macintosh has a pointer 80 
+PASS Not throw: macintosh has a pointer 81 
+PASS Not throw: macintosh has a pointer 82 
+PASS Not throw: macintosh has a pointer 83 
+PASS Not throw: macintosh has a pointer 84 
+PASS Not throw: macintosh has a pointer 85 
+PASS Not throw: macintosh has a pointer 86 
+PASS Not throw: macintosh has a pointer 87 
+PASS Not throw: macintosh has a pointer 88 
+PASS Not throw: macintosh has a pointer 89 
+PASS Not throw: macintosh has a pointer 90 
+PASS Not throw: macintosh has a pointer 91 
+PASS Not throw: macintosh has a pointer 92 
+PASS Not throw: macintosh has a pointer 93 
+PASS Not throw: macintosh has a pointer 94 
+PASS Not throw: macintosh has a pointer 95 
+PASS Not throw: macintosh has a pointer 96 
+PASS Not throw: macintosh has a pointer 97 
+PASS Not throw: macintosh has a pointer 98 
+PASS Not throw: macintosh has a pointer 99 
+PASS Not throw: macintosh has a pointer 100 
+PASS Not throw: macintosh has a pointer 101 
+PASS Not throw: macintosh has a pointer 102 
+PASS Not throw: macintosh has a pointer 103 
+PASS Not throw: macintosh has a pointer 104 
+PASS Not throw: macintosh has a pointer 105 
+PASS Not throw: macintosh has a pointer 106 
+PASS Not throw: macintosh has a pointer 107 
+PASS Not throw: macintosh has a pointer 108 
+PASS Not throw: macintosh has a pointer 109 
+PASS Not throw: macintosh has a pointer 110 
+PASS Not throw: macintosh has a pointer 111 
+PASS Not throw: macintosh has a pointer 112 
+PASS Not throw: macintosh has a pointer 113 
+PASS Not throw: macintosh has a pointer 114 
+PASS Not throw: macintosh has a pointer 115 
+PASS Not throw: macintosh has a pointer 116 
+PASS Not throw: macintosh has a pointer 117 
+PASS Not throw: macintosh has a pointer 118 
+PASS Not throw: macintosh has a pointer 119 
+PASS Not throw: macintosh has a pointer 120 
+PASS Not throw: macintosh has a pointer 121 
+PASS Not throw: macintosh has a pointer 122 
+PASS Not throw: macintosh has a pointer 123 
+PASS Not throw: macintosh has a pointer 124 
+PASS Not throw: macintosh has a pointer 125 
+PASS Not throw: macintosh has a pointer 126 
+PASS Not throw: macintosh has a pointer 127 
+PASS Not throw: macintosh has a pointer 128 
+PASS Not throw: macintosh has a pointer 129 
+PASS Not throw: macintosh has a pointer 130 
+PASS Not throw: macintosh has a pointer 131 
+PASS Not throw: macintosh has a pointer 132 
+PASS Not throw: macintosh has a pointer 133 
+PASS Not throw: macintosh has a pointer 134 
+PASS Not throw: macintosh has a pointer 135 
+PASS Not throw: macintosh has a pointer 136 
+PASS Not throw: macintosh has a pointer 137 
+PASS Not throw: macintosh has a pointer 138 
+PASS Not throw: macintosh has a pointer 139 
+PASS Not throw: macintosh has a pointer 140 
+PASS Not throw: macintosh has a pointer 141 
+PASS Not throw: macintosh has a pointer 142 
+PASS Not throw: macintosh has a pointer 143 
+PASS Not throw: macintosh has a pointer 144 
+PASS Not throw: macintosh has a pointer 145 
+PASS Not throw: macintosh has a pointer 146 
+PASS Not throw: macintosh has a pointer 147 
+PASS Not throw: macintosh has a pointer 148 
+PASS Not throw: macintosh has a pointer 149 
+PASS Not throw: macintosh has a pointer 150 
+PASS Not throw: macintosh has a pointer 151 
+PASS Not throw: macintosh has a pointer 152 
+PASS Not throw: macintosh has a pointer 153 
+PASS Not throw: macintosh has a pointer 154 
+PASS Not throw: macintosh has a pointer 155 
+PASS Not throw: macintosh has a pointer 156 
+PASS Not throw: macintosh has a pointer 157 
+PASS Not throw: macintosh has a pointer 158 
+PASS Not throw: macintosh has a pointer 159 
+PASS Not throw: macintosh has a pointer 160 
+PASS Not throw: macintosh has a pointer 161 
+PASS Not throw: macintosh has a pointer 162 
+PASS Not throw: macintosh has a pointer 163 
+PASS Not throw: macintosh has a pointer 164 
+PASS Not throw: macintosh has a pointer 165 
+PASS Not throw: macintosh has a pointer 166 
+PASS Not throw: macintosh has a pointer 167 
+PASS Not throw: macintosh has a pointer 168 
+PASS Not throw: macintosh has a pointer 169 
+PASS Not throw: macintosh has a pointer 170 
+PASS Not throw: macintosh has a pointer 171 
+PASS Not throw: macintosh has a pointer 172 
+PASS Not throw: macintosh has a pointer 173 
+PASS Not throw: macintosh has a pointer 174 
+PASS Not throw: macintosh has a pointer 175 
+PASS Not throw: macintosh has a pointer 176 
+PASS Not throw: macintosh has a pointer 177 
+PASS Not throw: macintosh has a pointer 178 
+PASS Not throw: macintosh has a pointer 179 
+PASS Not throw: macintosh has a pointer 180 
+PASS Not throw: macintosh has a pointer 181 
+PASS Not throw: macintosh has a pointer 182 
+PASS Not throw: macintosh has a pointer 183 
+PASS Not throw: macintosh has a pointer 184 
+PASS Not throw: macintosh has a pointer 185 
+PASS Not throw: macintosh has a pointer 186 
+PASS Not throw: macintosh has a pointer 187 
+PASS Not throw: macintosh has a pointer 188 
+PASS Not throw: macintosh has a pointer 189 
+PASS Not throw: macintosh has a pointer 190 
+PASS Not throw: macintosh has a pointer 191 
+PASS Not throw: macintosh has a pointer 192 
+PASS Not throw: macintosh has a pointer 193 
+PASS Not throw: macintosh has a pointer 194 
+PASS Not throw: macintosh has a pointer 195 
+PASS Not throw: macintosh has a pointer 196 
+PASS Not throw: macintosh has a pointer 197 
+PASS Not throw: macintosh has a pointer 198 
+PASS Not throw: macintosh has a pointer 199 
+PASS Not throw: macintosh has a pointer 200 
+PASS Not throw: macintosh has a pointer 201 
+PASS Not throw: macintosh has a pointer 202 
+PASS Not throw: macintosh has a pointer 203 
+PASS Not throw: macintosh has a pointer 204 
+PASS Not throw: macintosh has a pointer 205 
+PASS Not throw: macintosh has a pointer 206 
+PASS Not throw: macintosh has a pointer 207 
+PASS Not throw: macintosh has a pointer 208 
+PASS Not throw: macintosh has a pointer 209 
+PASS Not throw: macintosh has a pointer 210 
+PASS Not throw: macintosh has a pointer 211 
+PASS Not throw: macintosh has a pointer 212 
+PASS Not throw: macintosh has a pointer 213 
+PASS Not throw: macintosh has a pointer 214 
+PASS Not throw: macintosh has a pointer 215 
+PASS Not throw: macintosh has a pointer 216 
+PASS Not throw: macintosh has a pointer 217 
+PASS Not throw: macintosh has a pointer 218 
+PASS Not throw: macintosh has a pointer 219 
+PASS Not throw: macintosh has a pointer 220 
+PASS Not throw: macintosh has a pointer 221 
+PASS Not throw: macintosh has a pointer 222 
+PASS Not throw: macintosh has a pointer 223 
+PASS Not throw: macintosh has a pointer 224 
+PASS Not throw: macintosh has a pointer 225 
+PASS Not throw: macintosh has a pointer 226 
+PASS Not throw: macintosh has a pointer 227 
+PASS Not throw: macintosh has a pointer 228 
+PASS Not throw: macintosh has a pointer 229 
+PASS Not throw: macintosh has a pointer 230 
+PASS Not throw: macintosh has a pointer 231 
+PASS Not throw: macintosh has a pointer 232 
+PASS Not throw: macintosh has a pointer 233 
+PASS Not throw: macintosh has a pointer 234 
+PASS Not throw: macintosh has a pointer 235 
+PASS Not throw: macintosh has a pointer 236 
+PASS Not throw: macintosh has a pointer 237 
+PASS Not throw: macintosh has a pointer 238 
+PASS Not throw: macintosh has a pointer 239 
+PASS Not throw: macintosh has a pointer 240 
+PASS Not throw: macintosh has a pointer 241 
+PASS Not throw: macintosh has a pointer 242 
+PASS Not throw: macintosh has a pointer 243 
+PASS Not throw: macintosh has a pointer 244 
+PASS Not throw: macintosh has a pointer 245 
+PASS Not throw: macintosh has a pointer 246 
+PASS Not throw: macintosh has a pointer 247 
+PASS Not throw: macintosh has a pointer 248 
+PASS Not throw: macintosh has a pointer 249 
+PASS Not throw: macintosh has a pointer 250 
+PASS Not throw: macintosh has a pointer 251 
+PASS Not throw: macintosh has a pointer 252 
+PASS Not throw: macintosh has a pointer 253 
+PASS Not throw: macintosh has a pointer 254 
+PASS Not throw: macintosh has a pointer 255 
+PASS Not throw: windows-874 has a pointer 0 
+PASS Not throw: windows-874 has a pointer 1 
+PASS Not throw: windows-874 has a pointer 2 
+PASS Not throw: windows-874 has a pointer 3 
+PASS Not throw: windows-874 has a pointer 4 
+PASS Not throw: windows-874 has a pointer 5 
+PASS Not throw: windows-874 has a pointer 6 
+PASS Not throw: windows-874 has a pointer 7 
+PASS Not throw: windows-874 has a pointer 8 
+PASS Not throw: windows-874 has a pointer 9 
+PASS Not throw: windows-874 has a pointer 10 
+PASS Not throw: windows-874 has a pointer 11 
+PASS Not throw: windows-874 has a pointer 12 
+PASS Not throw: windows-874 has a pointer 13 
+PASS Not throw: windows-874 has a pointer 14 
+PASS Not throw: windows-874 has a pointer 15 
+PASS Not throw: windows-874 has a pointer 16 
+PASS Not throw: windows-874 has a pointer 17 
+PASS Not throw: windows-874 has a pointer 18 
+PASS Not throw: windows-874 has a pointer 19 
+PASS Not throw: windows-874 has a pointer 20 
+PASS Not throw: windows-874 has a pointer 21 
+PASS Not throw: windows-874 has a pointer 22 
+PASS Not throw: windows-874 has a pointer 23 
+PASS Not throw: windows-874 has a pointer 24 
+PASS Not throw: windows-874 has a pointer 25 
+PASS Not throw: windows-874 has a pointer 26 
+PASS Not throw: windows-874 has a pointer 27 
+PASS Not throw: windows-874 has a pointer 28 
+PASS Not throw: windows-874 has a pointer 29 
+PASS Not throw: windows-874 has a pointer 30 
+PASS Not throw: windows-874 has a pointer 31 
+PASS Not throw: windows-874 has a pointer 32 
+PASS Not throw: windows-874 has a pointer 33 
+PASS Not throw: windows-874 has a pointer 34 
+PASS Not throw: windows-874 has a pointer 35 
+PASS Not throw: windows-874 has a pointer 36 
+PASS Not throw: windows-874 has a pointer 37 
+PASS Not throw: windows-874 has a pointer 38 
+PASS Not throw: windows-874 has a pointer 39 
+PASS Not throw: windows-874 has a pointer 40 
+PASS Not throw: windows-874 has a pointer 41 
+PASS Not throw: windows-874 has a pointer 42 
+PASS Not throw: windows-874 has a pointer 43 
+PASS Not throw: windows-874 has a pointer 44 
+PASS Not throw: windows-874 has a pointer 45 
+PASS Not throw: windows-874 has a pointer 46 
+PASS Not throw: windows-874 has a pointer 47 
+PASS Not throw: windows-874 has a pointer 48 
+PASS Not throw: windows-874 has a pointer 49 
+PASS Not throw: windows-874 has a pointer 50 
+PASS Not throw: windows-874 has a pointer 51 
+PASS Not throw: windows-874 has a pointer 52 
+PASS Not throw: windows-874 has a pointer 53 
+PASS Not throw: windows-874 has a pointer 54 
+PASS Not throw: windows-874 has a pointer 55 
+PASS Not throw: windows-874 has a pointer 56 
+PASS Not throw: windows-874 has a pointer 57 
+PASS Not throw: windows-874 has a pointer 58 
+PASS Not throw: windows-874 has a pointer 59 
+PASS Not throw: windows-874 has a pointer 60 
+PASS Not throw: windows-874 has a pointer 61 
+PASS Not throw: windows-874 has a pointer 62 
+PASS Not throw: windows-874 has a pointer 63 
+PASS Not throw: windows-874 has a pointer 64 
+PASS Not throw: windows-874 has a pointer 65 
+PASS Not throw: windows-874 has a pointer 66 
+PASS Not throw: windows-874 has a pointer 67 
+PASS Not throw: windows-874 has a pointer 68 
+PASS Not throw: windows-874 has a pointer 69 
+PASS Not throw: windows-874 has a pointer 70 
+PASS Not throw: windows-874 has a pointer 71 
+PASS Not throw: windows-874 has a pointer 72 
+PASS Not throw: windows-874 has a pointer 73 
+PASS Not throw: windows-874 has a pointer 74 
+PASS Not throw: windows-874 has a pointer 75 
+PASS Not throw: windows-874 has a pointer 76 
+PASS Not throw: windows-874 has a pointer 77 
+PASS Not throw: windows-874 has a pointer 78 
+PASS Not throw: windows-874 has a pointer 79 
+PASS Not throw: windows-874 has a pointer 80 
+PASS Not throw: windows-874 has a pointer 81 
+PASS Not throw: windows-874 has a pointer 82 
+PASS Not throw: windows-874 has a pointer 83 
+PASS Not throw: windows-874 has a pointer 84 
+PASS Not throw: windows-874 has a pointer 85 
+PASS Not throw: windows-874 has a pointer 86 
+PASS Not throw: windows-874 has a pointer 87 
+PASS Not throw: windows-874 has a pointer 88 
+PASS Not throw: windows-874 has a pointer 89 
+PASS Not throw: windows-874 has a pointer 90 
+PASS Not throw: windows-874 has a pointer 91 
+PASS Not throw: windows-874 has a pointer 92 
+PASS Not throw: windows-874 has a pointer 93 
+PASS Not throw: windows-874 has a pointer 94 
+PASS Not throw: windows-874 has a pointer 95 
+PASS Not throw: windows-874 has a pointer 96 
+PASS Not throw: windows-874 has a pointer 97 
+PASS Not throw: windows-874 has a pointer 98 
+PASS Not throw: windows-874 has a pointer 99 
+PASS Not throw: windows-874 has a pointer 100 
+PASS Not throw: windows-874 has a pointer 101 
+PASS Not throw: windows-874 has a pointer 102 
+PASS Not throw: windows-874 has a pointer 103 
+PASS Not throw: windows-874 has a pointer 104 
+PASS Not throw: windows-874 has a pointer 105 
+PASS Not throw: windows-874 has a pointer 106 
+PASS Not throw: windows-874 has a pointer 107 
+PASS Not throw: windows-874 has a pointer 108 
+PASS Not throw: windows-874 has a pointer 109 
+PASS Not throw: windows-874 has a pointer 110 
+PASS Not throw: windows-874 has a pointer 111 
+PASS Not throw: windows-874 has a pointer 112 
+PASS Not throw: windows-874 has a pointer 113 
+PASS Not throw: windows-874 has a pointer 114 
+PASS Not throw: windows-874 has a pointer 115 
+PASS Not throw: windows-874 has a pointer 116 
+PASS Not throw: windows-874 has a pointer 117 
+PASS Not throw: windows-874 has a pointer 118 
+PASS Not throw: windows-874 has a pointer 119 
+PASS Not throw: windows-874 has a pointer 120 
+PASS Not throw: windows-874 has a pointer 121 
+PASS Not throw: windows-874 has a pointer 122 
+PASS Not throw: windows-874 has a pointer 123 
+PASS Not throw: windows-874 has a pointer 124 
+PASS Not throw: windows-874 has a pointer 125 
+PASS Not throw: windows-874 has a pointer 126 
+PASS Not throw: windows-874 has a pointer 127 
+PASS Not throw: windows-874 has a pointer 128 
+PASS Not throw: windows-874 has a pointer 129 
+PASS Not throw: windows-874 has a pointer 130 
+PASS Not throw: windows-874 has a pointer 131 
+PASS Not throw: windows-874 has a pointer 132 
+PASS Not throw: windows-874 has a pointer 133 
+PASS Not throw: windows-874 has a pointer 134 
+PASS Not throw: windows-874 has a pointer 135 
+PASS Not throw: windows-874 has a pointer 136 
+PASS Not throw: windows-874 has a pointer 137 
+PASS Not throw: windows-874 has a pointer 138 
+PASS Not throw: windows-874 has a pointer 139 
+PASS Not throw: windows-874 has a pointer 140 
+PASS Not throw: windows-874 has a pointer 141 
+PASS Not throw: windows-874 has a pointer 142 
+PASS Not throw: windows-874 has a pointer 143 
+PASS Not throw: windows-874 has a pointer 144 
+PASS Not throw: windows-874 has a pointer 145 
+PASS Not throw: windows-874 has a pointer 146 
+PASS Not throw: windows-874 has a pointer 147 
+PASS Not throw: windows-874 has a pointer 148 
+PASS Not throw: windows-874 has a pointer 149 
+PASS Not throw: windows-874 has a pointer 150 
+PASS Not throw: windows-874 has a pointer 151 
+PASS Not throw: windows-874 has a pointer 152 
+PASS Not throw: windows-874 has a pointer 153 
+PASS Not throw: windows-874 has a pointer 154 
+PASS Not throw: windows-874 has a pointer 155 
+PASS Not throw: windows-874 has a pointer 156 
+PASS Not throw: windows-874 has a pointer 157 
+PASS Not throw: windows-874 has a pointer 158 
+PASS Not throw: windows-874 has a pointer 159 
+PASS Not throw: windows-874 has a pointer 160 
+PASS Not throw: windows-874 has a pointer 161 
+PASS Not throw: windows-874 has a pointer 162 
+PASS Not throw: windows-874 has a pointer 163 
+PASS Not throw: windows-874 has a pointer 164 
+PASS Not throw: windows-874 has a pointer 165 
+PASS Not throw: windows-874 has a pointer 166 
+PASS Not throw: windows-874 has a pointer 167 
+PASS Not throw: windows-874 has a pointer 168 
+PASS Not throw: windows-874 has a pointer 169 
+PASS Not throw: windows-874 has a pointer 170 
+PASS Not throw: windows-874 has a pointer 171 
+PASS Not throw: windows-874 has a pointer 172 
+PASS Not throw: windows-874 has a pointer 173 
+PASS Not throw: windows-874 has a pointer 174 
+PASS Not throw: windows-874 has a pointer 175 
+PASS Not throw: windows-874 has a pointer 176 
+PASS Not throw: windows-874 has a pointer 177 
+PASS Not throw: windows-874 has a pointer 178 
+PASS Not throw: windows-874 has a pointer 179 
+PASS Not throw: windows-874 has a pointer 180 
+PASS Not throw: windows-874 has a pointer 181 
+PASS Not throw: windows-874 has a pointer 182 
+PASS Not throw: windows-874 has a pointer 183 
+PASS Not throw: windows-874 has a pointer 184 
+PASS Not throw: windows-874 has a pointer 185 
+PASS Not throw: windows-874 has a pointer 186 
+PASS Not throw: windows-874 has a pointer 187 
+PASS Not throw: windows-874 has a pointer 188 
+PASS Not throw: windows-874 has a pointer 189 
+PASS Not throw: windows-874 has a pointer 190 
+PASS Not throw: windows-874 has a pointer 191 
+PASS Not throw: windows-874 has a pointer 192 
+PASS Not throw: windows-874 has a pointer 193 
+PASS Not throw: windows-874 has a pointer 194 
+PASS Not throw: windows-874 has a pointer 195 
+PASS Not throw: windows-874 has a pointer 196 
+PASS Not throw: windows-874 has a pointer 197 
+PASS Not throw: windows-874 has a pointer 198 
+PASS Not throw: windows-874 has a pointer 199 
+PASS Not throw: windows-874 has a pointer 200 
+PASS Not throw: windows-874 has a pointer 201 
+PASS Not throw: windows-874 has a pointer 202 
+PASS Not throw: windows-874 has a pointer 203 
+PASS Not throw: windows-874 has a pointer 204 
+PASS Not throw: windows-874 has a pointer 205 
+PASS Not throw: windows-874 has a pointer 206 
+PASS Not throw: windows-874 has a pointer 207 
+PASS Not throw: windows-874 has a pointer 208 
+PASS Not throw: windows-874 has a pointer 209 
+PASS Not throw: windows-874 has a pointer 210 
+PASS Not throw: windows-874 has a pointer 211 
+PASS Not throw: windows-874 has a pointer 212 
+PASS Not throw: windows-874 has a pointer 213 
+PASS Not throw: windows-874 has a pointer 214 
+PASS Not throw: windows-874 has a pointer 215 
+PASS Not throw: windows-874 has a pointer 216 
+PASS Not throw: windows-874 has a pointer 217 
+PASS Not throw: windows-874 has a pointer 218 
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 219 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 220 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 221 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 222 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-874 has a pointer 223 
+PASS Not throw: windows-874 has a pointer 224 
+PASS Not throw: windows-874 has a pointer 225 
+PASS Not throw: windows-874 has a pointer 226 
+PASS Not throw: windows-874 has a pointer 227 
+PASS Not throw: windows-874 has a pointer 228 
+PASS Not throw: windows-874 has a pointer 229 
+PASS Not throw: windows-874 has a pointer 230 
+PASS Not throw: windows-874 has a pointer 231 
+PASS Not throw: windows-874 has a pointer 232 
+PASS Not throw: windows-874 has a pointer 233 
+PASS Not throw: windows-874 has a pointer 234 
+PASS Not throw: windows-874 has a pointer 235 
+PASS Not throw: windows-874 has a pointer 236 
+PASS Not throw: windows-874 has a pointer 237 
+PASS Not throw: windows-874 has a pointer 238 
+PASS Not throw: windows-874 has a pointer 239 
+PASS Not throw: windows-874 has a pointer 240 
+PASS Not throw: windows-874 has a pointer 241 
+PASS Not throw: windows-874 has a pointer 242 
+PASS Not throw: windows-874 has a pointer 243 
+PASS Not throw: windows-874 has a pointer 244 
+PASS Not throw: windows-874 has a pointer 245 
+PASS Not throw: windows-874 has a pointer 246 
+PASS Not throw: windows-874 has a pointer 247 
+PASS Not throw: windows-874 has a pointer 248 
+PASS Not throw: windows-874 has a pointer 249 
+PASS Not throw: windows-874 has a pointer 250 
+PASS Not throw: windows-874 has a pointer 251 
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 252 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 253 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 254 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-874 doesn't have a pointer 255 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1250 has a pointer 0 
+PASS Not throw: windows-1250 has a pointer 1 
+PASS Not throw: windows-1250 has a pointer 2 
+PASS Not throw: windows-1250 has a pointer 3 
+PASS Not throw: windows-1250 has a pointer 4 
+PASS Not throw: windows-1250 has a pointer 5 
+PASS Not throw: windows-1250 has a pointer 6 
+PASS Not throw: windows-1250 has a pointer 7 
+PASS Not throw: windows-1250 has a pointer 8 
+PASS Not throw: windows-1250 has a pointer 9 
+PASS Not throw: windows-1250 has a pointer 10 
+PASS Not throw: windows-1250 has a pointer 11 
+PASS Not throw: windows-1250 has a pointer 12 
+PASS Not throw: windows-1250 has a pointer 13 
+PASS Not throw: windows-1250 has a pointer 14 
+PASS Not throw: windows-1250 has a pointer 15 
+PASS Not throw: windows-1250 has a pointer 16 
+PASS Not throw: windows-1250 has a pointer 17 
+PASS Not throw: windows-1250 has a pointer 18 
+PASS Not throw: windows-1250 has a pointer 19 
+PASS Not throw: windows-1250 has a pointer 20 
+PASS Not throw: windows-1250 has a pointer 21 
+PASS Not throw: windows-1250 has a pointer 22 
+PASS Not throw: windows-1250 has a pointer 23 
+PASS Not throw: windows-1250 has a pointer 24 
+PASS Not throw: windows-1250 has a pointer 25 
+PASS Not throw: windows-1250 has a pointer 26 
+PASS Not throw: windows-1250 has a pointer 27 
+PASS Not throw: windows-1250 has a pointer 28 
+PASS Not throw: windows-1250 has a pointer 29 
+PASS Not throw: windows-1250 has a pointer 30 
+PASS Not throw: windows-1250 has a pointer 31 
+PASS Not throw: windows-1250 has a pointer 32 
+PASS Not throw: windows-1250 has a pointer 33 
+PASS Not throw: windows-1250 has a pointer 34 
+PASS Not throw: windows-1250 has a pointer 35 
+PASS Not throw: windows-1250 has a pointer 36 
+PASS Not throw: windows-1250 has a pointer 37 
+PASS Not throw: windows-1250 has a pointer 38 
+PASS Not throw: windows-1250 has a pointer 39 
+PASS Not throw: windows-1250 has a pointer 40 
+PASS Not throw: windows-1250 has a pointer 41 
+PASS Not throw: windows-1250 has a pointer 42 
+PASS Not throw: windows-1250 has a pointer 43 
+PASS Not throw: windows-1250 has a pointer 44 
+PASS Not throw: windows-1250 has a pointer 45 
+PASS Not throw: windows-1250 has a pointer 46 
+PASS Not throw: windows-1250 has a pointer 47 
+PASS Not throw: windows-1250 has a pointer 48 
+PASS Not throw: windows-1250 has a pointer 49 
+PASS Not throw: windows-1250 has a pointer 50 
+PASS Not throw: windows-1250 has a pointer 51 
+PASS Not throw: windows-1250 has a pointer 52 
+PASS Not throw: windows-1250 has a pointer 53 
+PASS Not throw: windows-1250 has a pointer 54 
+PASS Not throw: windows-1250 has a pointer 55 
+PASS Not throw: windows-1250 has a pointer 56 
+PASS Not throw: windows-1250 has a pointer 57 
+PASS Not throw: windows-1250 has a pointer 58 
+PASS Not throw: windows-1250 has a pointer 59 
+PASS Not throw: windows-1250 has a pointer 60 
+PASS Not throw: windows-1250 has a pointer 61 
+PASS Not throw: windows-1250 has a pointer 62 
+PASS Not throw: windows-1250 has a pointer 63 
+PASS Not throw: windows-1250 has a pointer 64 
+PASS Not throw: windows-1250 has a pointer 65 
+PASS Not throw: windows-1250 has a pointer 66 
+PASS Not throw: windows-1250 has a pointer 67 
+PASS Not throw: windows-1250 has a pointer 68 
+PASS Not throw: windows-1250 has a pointer 69 
+PASS Not throw: windows-1250 has a pointer 70 
+PASS Not throw: windows-1250 has a pointer 71 
+PASS Not throw: windows-1250 has a pointer 72 
+PASS Not throw: windows-1250 has a pointer 73 
+PASS Not throw: windows-1250 has a pointer 74 
+PASS Not throw: windows-1250 has a pointer 75 
+PASS Not throw: windows-1250 has a pointer 76 
+PASS Not throw: windows-1250 has a pointer 77 
+PASS Not throw: windows-1250 has a pointer 78 
+PASS Not throw: windows-1250 has a pointer 79 
+PASS Not throw: windows-1250 has a pointer 80 
+PASS Not throw: windows-1250 has a pointer 81 
+PASS Not throw: windows-1250 has a pointer 82 
+PASS Not throw: windows-1250 has a pointer 83 
+PASS Not throw: windows-1250 has a pointer 84 
+PASS Not throw: windows-1250 has a pointer 85 
+PASS Not throw: windows-1250 has a pointer 86 
+PASS Not throw: windows-1250 has a pointer 87 
+PASS Not throw: windows-1250 has a pointer 88 
+PASS Not throw: windows-1250 has a pointer 89 
+PASS Not throw: windows-1250 has a pointer 90 
+PASS Not throw: windows-1250 has a pointer 91 
+PASS Not throw: windows-1250 has a pointer 92 
+PASS Not throw: windows-1250 has a pointer 93 
+PASS Not throw: windows-1250 has a pointer 94 
+PASS Not throw: windows-1250 has a pointer 95 
+PASS Not throw: windows-1250 has a pointer 96 
+PASS Not throw: windows-1250 has a pointer 97 
+PASS Not throw: windows-1250 has a pointer 98 
+PASS Not throw: windows-1250 has a pointer 99 
+PASS Not throw: windows-1250 has a pointer 100 
+PASS Not throw: windows-1250 has a pointer 101 
+PASS Not throw: windows-1250 has a pointer 102 
+PASS Not throw: windows-1250 has a pointer 103 
+PASS Not throw: windows-1250 has a pointer 104 
+PASS Not throw: windows-1250 has a pointer 105 
+PASS Not throw: windows-1250 has a pointer 106 
+PASS Not throw: windows-1250 has a pointer 107 
+PASS Not throw: windows-1250 has a pointer 108 
+PASS Not throw: windows-1250 has a pointer 109 
+PASS Not throw: windows-1250 has a pointer 110 
+PASS Not throw: windows-1250 has a pointer 111 
+PASS Not throw: windows-1250 has a pointer 112 
+PASS Not throw: windows-1250 has a pointer 113 
+PASS Not throw: windows-1250 has a pointer 114 
+PASS Not throw: windows-1250 has a pointer 115 
+PASS Not throw: windows-1250 has a pointer 116 
+PASS Not throw: windows-1250 has a pointer 117 
+PASS Not throw: windows-1250 has a pointer 118 
+PASS Not throw: windows-1250 has a pointer 119 
+PASS Not throw: windows-1250 has a pointer 120 
+PASS Not throw: windows-1250 has a pointer 121 
+PASS Not throw: windows-1250 has a pointer 122 
+PASS Not throw: windows-1250 has a pointer 123 
+PASS Not throw: windows-1250 has a pointer 124 
+PASS Not throw: windows-1250 has a pointer 125 
+PASS Not throw: windows-1250 has a pointer 126 
+PASS Not throw: windows-1250 has a pointer 127 
+PASS Not throw: windows-1250 has a pointer 128 
+PASS Not throw: windows-1250 has a pointer 129 
+PASS Not throw: windows-1250 has a pointer 130 
+PASS Not throw: windows-1250 has a pointer 131 
+PASS Not throw: windows-1250 has a pointer 132 
+PASS Not throw: windows-1250 has a pointer 133 
+PASS Not throw: windows-1250 has a pointer 134 
+PASS Not throw: windows-1250 has a pointer 135 
+PASS Not throw: windows-1250 has a pointer 136 
+PASS Not throw: windows-1250 has a pointer 137 
+PASS Not throw: windows-1250 has a pointer 138 
+PASS Not throw: windows-1250 has a pointer 139 
+PASS Not throw: windows-1250 has a pointer 140 
+PASS Not throw: windows-1250 has a pointer 141 
+PASS Not throw: windows-1250 has a pointer 142 
+PASS Not throw: windows-1250 has a pointer 143 
+PASS Not throw: windows-1250 has a pointer 144 
+PASS Not throw: windows-1250 has a pointer 145 
+PASS Not throw: windows-1250 has a pointer 146 
+PASS Not throw: windows-1250 has a pointer 147 
+PASS Not throw: windows-1250 has a pointer 148 
+PASS Not throw: windows-1250 has a pointer 149 
+PASS Not throw: windows-1250 has a pointer 150 
+PASS Not throw: windows-1250 has a pointer 151 
+PASS Not throw: windows-1250 has a pointer 152 
+PASS Not throw: windows-1250 has a pointer 153 
+PASS Not throw: windows-1250 has a pointer 154 
+PASS Not throw: windows-1250 has a pointer 155 
+PASS Not throw: windows-1250 has a pointer 156 
+PASS Not throw: windows-1250 has a pointer 157 
+PASS Not throw: windows-1250 has a pointer 158 
+PASS Not throw: windows-1250 has a pointer 159 
+PASS Not throw: windows-1250 has a pointer 160 
+PASS Not throw: windows-1250 has a pointer 161 
+PASS Not throw: windows-1250 has a pointer 162 
+PASS Not throw: windows-1250 has a pointer 163 
+PASS Not throw: windows-1250 has a pointer 164 
+PASS Not throw: windows-1250 has a pointer 165 
+PASS Not throw: windows-1250 has a pointer 166 
+PASS Not throw: windows-1250 has a pointer 167 
+PASS Not throw: windows-1250 has a pointer 168 
+PASS Not throw: windows-1250 has a pointer 169 
+PASS Not throw: windows-1250 has a pointer 170 
+PASS Not throw: windows-1250 has a pointer 171 
+PASS Not throw: windows-1250 has a pointer 172 
+PASS Not throw: windows-1250 has a pointer 173 
+PASS Not throw: windows-1250 has a pointer 174 
+PASS Not throw: windows-1250 has a pointer 175 
+PASS Not throw: windows-1250 has a pointer 176 
+PASS Not throw: windows-1250 has a pointer 177 
+PASS Not throw: windows-1250 has a pointer 178 
+PASS Not throw: windows-1250 has a pointer 179 
+PASS Not throw: windows-1250 has a pointer 180 
+PASS Not throw: windows-1250 has a pointer 181 
+PASS Not throw: windows-1250 has a pointer 182 
+PASS Not throw: windows-1250 has a pointer 183 
+PASS Not throw: windows-1250 has a pointer 184 
+PASS Not throw: windows-1250 has a pointer 185 
+PASS Not throw: windows-1250 has a pointer 186 
+PASS Not throw: windows-1250 has a pointer 187 
+PASS Not throw: windows-1250 has a pointer 188 
+PASS Not throw: windows-1250 has a pointer 189 
+PASS Not throw: windows-1250 has a pointer 190 
+PASS Not throw: windows-1250 has a pointer 191 
+PASS Not throw: windows-1250 has a pointer 192 
+PASS Not throw: windows-1250 has a pointer 193 
+PASS Not throw: windows-1250 has a pointer 194 
+PASS Not throw: windows-1250 has a pointer 195 
+PASS Not throw: windows-1250 has a pointer 196 
+PASS Not throw: windows-1250 has a pointer 197 
+PASS Not throw: windows-1250 has a pointer 198 
+PASS Not throw: windows-1250 has a pointer 199 
+PASS Not throw: windows-1250 has a pointer 200 
+PASS Not throw: windows-1250 has a pointer 201 
+PASS Not throw: windows-1250 has a pointer 202 
+PASS Not throw: windows-1250 has a pointer 203 
+PASS Not throw: windows-1250 has a pointer 204 
+PASS Not throw: windows-1250 has a pointer 205 
+PASS Not throw: windows-1250 has a pointer 206 
+PASS Not throw: windows-1250 has a pointer 207 
+PASS Not throw: windows-1250 has a pointer 208 
+PASS Not throw: windows-1250 has a pointer 209 
+PASS Not throw: windows-1250 has a pointer 210 
+PASS Not throw: windows-1250 has a pointer 211 
+PASS Not throw: windows-1250 has a pointer 212 
+PASS Not throw: windows-1250 has a pointer 213 
+PASS Not throw: windows-1250 has a pointer 214 
+PASS Not throw: windows-1250 has a pointer 215 
+PASS Not throw: windows-1250 has a pointer 216 
+PASS Not throw: windows-1250 has a pointer 217 
+PASS Not throw: windows-1250 has a pointer 218 
+PASS Not throw: windows-1250 has a pointer 219 
+PASS Not throw: windows-1250 has a pointer 220 
+PASS Not throw: windows-1250 has a pointer 221 
+PASS Not throw: windows-1250 has a pointer 222 
+PASS Not throw: windows-1250 has a pointer 223 
+PASS Not throw: windows-1250 has a pointer 224 
+PASS Not throw: windows-1250 has a pointer 225 
+PASS Not throw: windows-1250 has a pointer 226 
+PASS Not throw: windows-1250 has a pointer 227 
+PASS Not throw: windows-1250 has a pointer 228 
+PASS Not throw: windows-1250 has a pointer 229 
+PASS Not throw: windows-1250 has a pointer 230 
+PASS Not throw: windows-1250 has a pointer 231 
+PASS Not throw: windows-1250 has a pointer 232 
+PASS Not throw: windows-1250 has a pointer 233 
+PASS Not throw: windows-1250 has a pointer 234 
+PASS Not throw: windows-1250 has a pointer 235 
+PASS Not throw: windows-1250 has a pointer 236 
+PASS Not throw: windows-1250 has a pointer 237 
+PASS Not throw: windows-1250 has a pointer 238 
+PASS Not throw: windows-1250 has a pointer 239 
+PASS Not throw: windows-1250 has a pointer 240 
+PASS Not throw: windows-1250 has a pointer 241 
+PASS Not throw: windows-1250 has a pointer 242 
+PASS Not throw: windows-1250 has a pointer 243 
+PASS Not throw: windows-1250 has a pointer 244 
+PASS Not throw: windows-1250 has a pointer 245 
+PASS Not throw: windows-1250 has a pointer 246 
+PASS Not throw: windows-1250 has a pointer 247 
+PASS Not throw: windows-1250 has a pointer 248 
+PASS Not throw: windows-1250 has a pointer 249 
+PASS Not throw: windows-1250 has a pointer 250 
+PASS Not throw: windows-1250 has a pointer 251 
+PASS Not throw: windows-1250 has a pointer 252 
+PASS Not throw: windows-1250 has a pointer 253 
+PASS Not throw: windows-1250 has a pointer 254 
+PASS Not throw: windows-1250 has a pointer 255 
+PASS Not throw: windows-1251 has a pointer 0 
+PASS Not throw: windows-1251 has a pointer 1 
+PASS Not throw: windows-1251 has a pointer 2 
+PASS Not throw: windows-1251 has a pointer 3 
+PASS Not throw: windows-1251 has a pointer 4 
+PASS Not throw: windows-1251 has a pointer 5 
+PASS Not throw: windows-1251 has a pointer 6 
+PASS Not throw: windows-1251 has a pointer 7 
+PASS Not throw: windows-1251 has a pointer 8 
+PASS Not throw: windows-1251 has a pointer 9 
+PASS Not throw: windows-1251 has a pointer 10 
+PASS Not throw: windows-1251 has a pointer 11 
+PASS Not throw: windows-1251 has a pointer 12 
+PASS Not throw: windows-1251 has a pointer 13 
+PASS Not throw: windows-1251 has a pointer 14 
+PASS Not throw: windows-1251 has a pointer 15 
+PASS Not throw: windows-1251 has a pointer 16 
+PASS Not throw: windows-1251 has a pointer 17 
+PASS Not throw: windows-1251 has a pointer 18 
+PASS Not throw: windows-1251 has a pointer 19 
+PASS Not throw: windows-1251 has a pointer 20 
+PASS Not throw: windows-1251 has a pointer 21 
+PASS Not throw: windows-1251 has a pointer 22 
+PASS Not throw: windows-1251 has a pointer 23 
+PASS Not throw: windows-1251 has a pointer 24 
+PASS Not throw: windows-1251 has a pointer 25 
+PASS Not throw: windows-1251 has a pointer 26 
+PASS Not throw: windows-1251 has a pointer 27 
+PASS Not throw: windows-1251 has a pointer 28 
+PASS Not throw: windows-1251 has a pointer 29 
+PASS Not throw: windows-1251 has a pointer 30 
+PASS Not throw: windows-1251 has a pointer 31 
+PASS Not throw: windows-1251 has a pointer 32 
+PASS Not throw: windows-1251 has a pointer 33 
+PASS Not throw: windows-1251 has a pointer 34 
+PASS Not throw: windows-1251 has a pointer 35 
+PASS Not throw: windows-1251 has a pointer 36 
+PASS Not throw: windows-1251 has a pointer 37 
+PASS Not throw: windows-1251 has a pointer 38 
+PASS Not throw: windows-1251 has a pointer 39 
+PASS Not throw: windows-1251 has a pointer 40 
+PASS Not throw: windows-1251 has a pointer 41 
+PASS Not throw: windows-1251 has a pointer 42 
+PASS Not throw: windows-1251 has a pointer 43 
+PASS Not throw: windows-1251 has a pointer 44 
+PASS Not throw: windows-1251 has a pointer 45 
+PASS Not throw: windows-1251 has a pointer 46 
+PASS Not throw: windows-1251 has a pointer 47 
+PASS Not throw: windows-1251 has a pointer 48 
+PASS Not throw: windows-1251 has a pointer 49 
+PASS Not throw: windows-1251 has a pointer 50 
+PASS Not throw: windows-1251 has a pointer 51 
+PASS Not throw: windows-1251 has a pointer 52 
+PASS Not throw: windows-1251 has a pointer 53 
+PASS Not throw: windows-1251 has a pointer 54 
+PASS Not throw: windows-1251 has a pointer 55 
+PASS Not throw: windows-1251 has a pointer 56 
+PASS Not throw: windows-1251 has a pointer 57 
+PASS Not throw: windows-1251 has a pointer 58 
+PASS Not throw: windows-1251 has a pointer 59 
+PASS Not throw: windows-1251 has a pointer 60 
+PASS Not throw: windows-1251 has a pointer 61 
+PASS Not throw: windows-1251 has a pointer 62 
+PASS Not throw: windows-1251 has a pointer 63 
+PASS Not throw: windows-1251 has a pointer 64 
+PASS Not throw: windows-1251 has a pointer 65 
+PASS Not throw: windows-1251 has a pointer 66 
+PASS Not throw: windows-1251 has a pointer 67 
+PASS Not throw: windows-1251 has a pointer 68 
+PASS Not throw: windows-1251 has a pointer 69 
+PASS Not throw: windows-1251 has a pointer 70 
+PASS Not throw: windows-1251 has a pointer 71 
+PASS Not throw: windows-1251 has a pointer 72 
+PASS Not throw: windows-1251 has a pointer 73 
+PASS Not throw: windows-1251 has a pointer 74 
+PASS Not throw: windows-1251 has a pointer 75 
+PASS Not throw: windows-1251 has a pointer 76 
+PASS Not throw: windows-1251 has a pointer 77 
+PASS Not throw: windows-1251 has a pointer 78 
+PASS Not throw: windows-1251 has a pointer 79 
+PASS Not throw: windows-1251 has a pointer 80 
+PASS Not throw: windows-1251 has a pointer 81 
+PASS Not throw: windows-1251 has a pointer 82 
+PASS Not throw: windows-1251 has a pointer 83 
+PASS Not throw: windows-1251 has a pointer 84 
+PASS Not throw: windows-1251 has a pointer 85 
+PASS Not throw: windows-1251 has a pointer 86 
+PASS Not throw: windows-1251 has a pointer 87 
+PASS Not throw: windows-1251 has a pointer 88 
+PASS Not throw: windows-1251 has a pointer 89 
+PASS Not throw: windows-1251 has a pointer 90 
+PASS Not throw: windows-1251 has a pointer 91 
+PASS Not throw: windows-1251 has a pointer 92 
+PASS Not throw: windows-1251 has a pointer 93 
+PASS Not throw: windows-1251 has a pointer 94 
+PASS Not throw: windows-1251 has a pointer 95 
+PASS Not throw: windows-1251 has a pointer 96 
+PASS Not throw: windows-1251 has a pointer 97 
+PASS Not throw: windows-1251 has a pointer 98 
+PASS Not throw: windows-1251 has a pointer 99 
+PASS Not throw: windows-1251 has a pointer 100 
+PASS Not throw: windows-1251 has a pointer 101 
+PASS Not throw: windows-1251 has a pointer 102 
+PASS Not throw: windows-1251 has a pointer 103 
+PASS Not throw: windows-1251 has a pointer 104 
+PASS Not throw: windows-1251 has a pointer 105 
+PASS Not throw: windows-1251 has a pointer 106 
+PASS Not throw: windows-1251 has a pointer 107 
+PASS Not throw: windows-1251 has a pointer 108 
+PASS Not throw: windows-1251 has a pointer 109 
+PASS Not throw: windows-1251 has a pointer 110 
+PASS Not throw: windows-1251 has a pointer 111 
+PASS Not throw: windows-1251 has a pointer 112 
+PASS Not throw: windows-1251 has a pointer 113 
+PASS Not throw: windows-1251 has a pointer 114 
+PASS Not throw: windows-1251 has a pointer 115 
+PASS Not throw: windows-1251 has a pointer 116 
+PASS Not throw: windows-1251 has a pointer 117 
+PASS Not throw: windows-1251 has a pointer 118 
+PASS Not throw: windows-1251 has a pointer 119 
+PASS Not throw: windows-1251 has a pointer 120 
+PASS Not throw: windows-1251 has a pointer 121 
+PASS Not throw: windows-1251 has a pointer 122 
+PASS Not throw: windows-1251 has a pointer 123 
+PASS Not throw: windows-1251 has a pointer 124 
+PASS Not throw: windows-1251 has a pointer 125 
+PASS Not throw: windows-1251 has a pointer 126 
+PASS Not throw: windows-1251 has a pointer 127 
+PASS Not throw: windows-1251 has a pointer 128 
+PASS Not throw: windows-1251 has a pointer 129 
+PASS Not throw: windows-1251 has a pointer 130 
+PASS Not throw: windows-1251 has a pointer 131 
+PASS Not throw: windows-1251 has a pointer 132 
+PASS Not throw: windows-1251 has a pointer 133 
+PASS Not throw: windows-1251 has a pointer 134 
+PASS Not throw: windows-1251 has a pointer 135 
+PASS Not throw: windows-1251 has a pointer 136 
+PASS Not throw: windows-1251 has a pointer 137 
+PASS Not throw: windows-1251 has a pointer 138 
+PASS Not throw: windows-1251 has a pointer 139 
+PASS Not throw: windows-1251 has a pointer 140 
+PASS Not throw: windows-1251 has a pointer 141 
+PASS Not throw: windows-1251 has a pointer 142 
+PASS Not throw: windows-1251 has a pointer 143 
+PASS Not throw: windows-1251 has a pointer 144 
+PASS Not throw: windows-1251 has a pointer 145 
+PASS Not throw: windows-1251 has a pointer 146 
+PASS Not throw: windows-1251 has a pointer 147 
+PASS Not throw: windows-1251 has a pointer 148 
+PASS Not throw: windows-1251 has a pointer 149 
+PASS Not throw: windows-1251 has a pointer 150 
+PASS Not throw: windows-1251 has a pointer 151 
+PASS Not throw: windows-1251 has a pointer 152 
+PASS Not throw: windows-1251 has a pointer 153 
+PASS Not throw: windows-1251 has a pointer 154 
+PASS Not throw: windows-1251 has a pointer 155 
+PASS Not throw: windows-1251 has a pointer 156 
+PASS Not throw: windows-1251 has a pointer 157 
+PASS Not throw: windows-1251 has a pointer 158 
+PASS Not throw: windows-1251 has a pointer 159 
+PASS Not throw: windows-1251 has a pointer 160 
+PASS Not throw: windows-1251 has a pointer 161 
+PASS Not throw: windows-1251 has a pointer 162 
+PASS Not throw: windows-1251 has a pointer 163 
+PASS Not throw: windows-1251 has a pointer 164 
+PASS Not throw: windows-1251 has a pointer 165 
+PASS Not throw: windows-1251 has a pointer 166 
+PASS Not throw: windows-1251 has a pointer 167 
+PASS Not throw: windows-1251 has a pointer 168 
+PASS Not throw: windows-1251 has a pointer 169 
+PASS Not throw: windows-1251 has a pointer 170 
+PASS Not throw: windows-1251 has a pointer 171 
+PASS Not throw: windows-1251 has a pointer 172 
+PASS Not throw: windows-1251 has a pointer 173 
+PASS Not throw: windows-1251 has a pointer 174 
+PASS Not throw: windows-1251 has a pointer 175 
+PASS Not throw: windows-1251 has a pointer 176 
+PASS Not throw: windows-1251 has a pointer 177 
+PASS Not throw: windows-1251 has a pointer 178 
+PASS Not throw: windows-1251 has a pointer 179 
+PASS Not throw: windows-1251 has a pointer 180 
+PASS Not throw: windows-1251 has a pointer 181 
+PASS Not throw: windows-1251 has a pointer 182 
+PASS Not throw: windows-1251 has a pointer 183 
+PASS Not throw: windows-1251 has a pointer 184 
+PASS Not throw: windows-1251 has a pointer 185 
+PASS Not throw: windows-1251 has a pointer 186 
+PASS Not throw: windows-1251 has a pointer 187 
+PASS Not throw: windows-1251 has a pointer 188 
+PASS Not throw: windows-1251 has a pointer 189 
+PASS Not throw: windows-1251 has a pointer 190 
+PASS Not throw: windows-1251 has a pointer 191 
+PASS Not throw: windows-1251 has a pointer 192 
+PASS Not throw: windows-1251 has a pointer 193 
+PASS Not throw: windows-1251 has a pointer 194 
+PASS Not throw: windows-1251 has a pointer 195 
+PASS Not throw: windows-1251 has a pointer 196 
+PASS Not throw: windows-1251 has a pointer 197 
+PASS Not throw: windows-1251 has a pointer 198 
+PASS Not throw: windows-1251 has a pointer 199 
+PASS Not throw: windows-1251 has a pointer 200 
+PASS Not throw: windows-1251 has a pointer 201 
+PASS Not throw: windows-1251 has a pointer 202 
+PASS Not throw: windows-1251 has a pointer 203 
+PASS Not throw: windows-1251 has a pointer 204 
+PASS Not throw: windows-1251 has a pointer 205 
+PASS Not throw: windows-1251 has a pointer 206 
+PASS Not throw: windows-1251 has a pointer 207 
+PASS Not throw: windows-1251 has a pointer 208 
+PASS Not throw: windows-1251 has a pointer 209 
+PASS Not throw: windows-1251 has a pointer 210 
+PASS Not throw: windows-1251 has a pointer 211 
+PASS Not throw: windows-1251 has a pointer 212 
+PASS Not throw: windows-1251 has a pointer 213 
+PASS Not throw: windows-1251 has a pointer 214 
+PASS Not throw: windows-1251 has a pointer 215 
+PASS Not throw: windows-1251 has a pointer 216 
+PASS Not throw: windows-1251 has a pointer 217 
+PASS Not throw: windows-1251 has a pointer 218 
+PASS Not throw: windows-1251 has a pointer 219 
+PASS Not throw: windows-1251 has a pointer 220 
+PASS Not throw: windows-1251 has a pointer 221 
+PASS Not throw: windows-1251 has a pointer 222 
+PASS Not throw: windows-1251 has a pointer 223 
+PASS Not throw: windows-1251 has a pointer 224 
+PASS Not throw: windows-1251 has a pointer 225 
+PASS Not throw: windows-1251 has a pointer 226 
+PASS Not throw: windows-1251 has a pointer 227 
+PASS Not throw: windows-1251 has a pointer 228 
+PASS Not throw: windows-1251 has a pointer 229 
+PASS Not throw: windows-1251 has a pointer 230 
+PASS Not throw: windows-1251 has a pointer 231 
+PASS Not throw: windows-1251 has a pointer 232 
+PASS Not throw: windows-1251 has a pointer 233 
+PASS Not throw: windows-1251 has a pointer 234 
+PASS Not throw: windows-1251 has a pointer 235 
+PASS Not throw: windows-1251 has a pointer 236 
+PASS Not throw: windows-1251 has a pointer 237 
+PASS Not throw: windows-1251 has a pointer 238 
+PASS Not throw: windows-1251 has a pointer 239 
+PASS Not throw: windows-1251 has a pointer 240 
+PASS Not throw: windows-1251 has a pointer 241 
+PASS Not throw: windows-1251 has a pointer 242 
+PASS Not throw: windows-1251 has a pointer 243 
+PASS Not throw: windows-1251 has a pointer 244 
+PASS Not throw: windows-1251 has a pointer 245 
+PASS Not throw: windows-1251 has a pointer 246 
+PASS Not throw: windows-1251 has a pointer 247 
+PASS Not throw: windows-1251 has a pointer 248 
+PASS Not throw: windows-1251 has a pointer 249 
+PASS Not throw: windows-1251 has a pointer 250 
+PASS Not throw: windows-1251 has a pointer 251 
+PASS Not throw: windows-1251 has a pointer 252 
+PASS Not throw: windows-1251 has a pointer 253 
+PASS Not throw: windows-1251 has a pointer 254 
+PASS Not throw: windows-1251 has a pointer 255 
+PASS Not throw: windows-1252 has a pointer 0 
+PASS Not throw: windows-1252 has a pointer 1 
+PASS Not throw: windows-1252 has a pointer 2 
+PASS Not throw: windows-1252 has a pointer 3 
+PASS Not throw: windows-1252 has a pointer 4 
+PASS Not throw: windows-1252 has a pointer 5 
+PASS Not throw: windows-1252 has a pointer 6 
+PASS Not throw: windows-1252 has a pointer 7 
+PASS Not throw: windows-1252 has a pointer 8 
+PASS Not throw: windows-1252 has a pointer 9 
+PASS Not throw: windows-1252 has a pointer 10 
+PASS Not throw: windows-1252 has a pointer 11 
+PASS Not throw: windows-1252 has a pointer 12 
+PASS Not throw: windows-1252 has a pointer 13 
+PASS Not throw: windows-1252 has a pointer 14 
+PASS Not throw: windows-1252 has a pointer 15 
+PASS Not throw: windows-1252 has a pointer 16 
+PASS Not throw: windows-1252 has a pointer 17 
+PASS Not throw: windows-1252 has a pointer 18 
+PASS Not throw: windows-1252 has a pointer 19 
+PASS Not throw: windows-1252 has a pointer 20 
+PASS Not throw: windows-1252 has a pointer 21 
+PASS Not throw: windows-1252 has a pointer 22 
+PASS Not throw: windows-1252 has a pointer 23 
+PASS Not throw: windows-1252 has a pointer 24 
+PASS Not throw: windows-1252 has a pointer 25 
+PASS Not throw: windows-1252 has a pointer 26 
+PASS Not throw: windows-1252 has a pointer 27 
+PASS Not throw: windows-1252 has a pointer 28 
+PASS Not throw: windows-1252 has a pointer 29 
+PASS Not throw: windows-1252 has a pointer 30 
+PASS Not throw: windows-1252 has a pointer 31 
+PASS Not throw: windows-1252 has a pointer 32 
+PASS Not throw: windows-1252 has a pointer 33 
+PASS Not throw: windows-1252 has a pointer 34 
+PASS Not throw: windows-1252 has a pointer 35 
+PASS Not throw: windows-1252 has a pointer 36 
+PASS Not throw: windows-1252 has a pointer 37 
+PASS Not throw: windows-1252 has a pointer 38 
+PASS Not throw: windows-1252 has a pointer 39 
+PASS Not throw: windows-1252 has a pointer 40 
+PASS Not throw: windows-1252 has a pointer 41 
+PASS Not throw: windows-1252 has a pointer 42 
+PASS Not throw: windows-1252 has a pointer 43 
+PASS Not throw: windows-1252 has a pointer 44 
+PASS Not throw: windows-1252 has a pointer 45 
+PASS Not throw: windows-1252 has a pointer 46 
+PASS Not throw: windows-1252 has a pointer 47 
+PASS Not throw: windows-1252 has a pointer 48 
+PASS Not throw: windows-1252 has a pointer 49 
+PASS Not throw: windows-1252 has a pointer 50 
+PASS Not throw: windows-1252 has a pointer 51 
+PASS Not throw: windows-1252 has a pointer 52 
+PASS Not throw: windows-1252 has a pointer 53 
+PASS Not throw: windows-1252 has a pointer 54 
+PASS Not throw: windows-1252 has a pointer 55 
+PASS Not throw: windows-1252 has a pointer 56 
+PASS Not throw: windows-1252 has a pointer 57 
+PASS Not throw: windows-1252 has a pointer 58 
+PASS Not throw: windows-1252 has a pointer 59 
+PASS Not throw: windows-1252 has a pointer 60 
+PASS Not throw: windows-1252 has a pointer 61 
+PASS Not throw: windows-1252 has a pointer 62 
+PASS Not throw: windows-1252 has a pointer 63 
+PASS Not throw: windows-1252 has a pointer 64 
+PASS Not throw: windows-1252 has a pointer 65 
+PASS Not throw: windows-1252 has a pointer 66 
+PASS Not throw: windows-1252 has a pointer 67 
+PASS Not throw: windows-1252 has a pointer 68 
+PASS Not throw: windows-1252 has a pointer 69 
+PASS Not throw: windows-1252 has a pointer 70 
+PASS Not throw: windows-1252 has a pointer 71 
+PASS Not throw: windows-1252 has a pointer 72 
+PASS Not throw: windows-1252 has a pointer 73 
+PASS Not throw: windows-1252 has a pointer 74 
+PASS Not throw: windows-1252 has a pointer 75 
+PASS Not throw: windows-1252 has a pointer 76 
+PASS Not throw: windows-1252 has a pointer 77 
+PASS Not throw: windows-1252 has a pointer 78 
+PASS Not throw: windows-1252 has a pointer 79 
+PASS Not throw: windows-1252 has a pointer 80 
+PASS Not throw: windows-1252 has a pointer 81 
+PASS Not throw: windows-1252 has a pointer 82 
+PASS Not throw: windows-1252 has a pointer 83 
+PASS Not throw: windows-1252 has a pointer 84 
+PASS Not throw: windows-1252 has a pointer 85 
+PASS Not throw: windows-1252 has a pointer 86 
+PASS Not throw: windows-1252 has a pointer 87 
+PASS Not throw: windows-1252 has a pointer 88 
+PASS Not throw: windows-1252 has a pointer 89 
+PASS Not throw: windows-1252 has a pointer 90 
+PASS Not throw: windows-1252 has a pointer 91 
+PASS Not throw: windows-1252 has a pointer 92 
+PASS Not throw: windows-1252 has a pointer 93 
+PASS Not throw: windows-1252 has a pointer 94 
+PASS Not throw: windows-1252 has a pointer 95 
+PASS Not throw: windows-1252 has a pointer 96 
+PASS Not throw: windows-1252 has a pointer 97 
+PASS Not throw: windows-1252 has a pointer 98 
+PASS Not throw: windows-1252 has a pointer 99 
+PASS Not throw: windows-1252 has a pointer 100 
+PASS Not throw: windows-1252 has a pointer 101 
+PASS Not throw: windows-1252 has a pointer 102 
+PASS Not throw: windows-1252 has a pointer 103 
+PASS Not throw: windows-1252 has a pointer 104 
+PASS Not throw: windows-1252 has a pointer 105 
+PASS Not throw: windows-1252 has a pointer 106 
+PASS Not throw: windows-1252 has a pointer 107 
+PASS Not throw: windows-1252 has a pointer 108 
+PASS Not throw: windows-1252 has a pointer 109 
+PASS Not throw: windows-1252 has a pointer 110 
+PASS Not throw: windows-1252 has a pointer 111 
+PASS Not throw: windows-1252 has a pointer 112 
+PASS Not throw: windows-1252 has a pointer 113 
+PASS Not throw: windows-1252 has a pointer 114 
+PASS Not throw: windows-1252 has a pointer 115 
+PASS Not throw: windows-1252 has a pointer 116 
+PASS Not throw: windows-1252 has a pointer 117 
+PASS Not throw: windows-1252 has a pointer 118 
+PASS Not throw: windows-1252 has a pointer 119 
+PASS Not throw: windows-1252 has a pointer 120 
+PASS Not throw: windows-1252 has a pointer 121 
+PASS Not throw: windows-1252 has a pointer 122 
+PASS Not throw: windows-1252 has a pointer 123 
+PASS Not throw: windows-1252 has a pointer 124 
+PASS Not throw: windows-1252 has a pointer 125 
+PASS Not throw: windows-1252 has a pointer 126 
+PASS Not throw: windows-1252 has a pointer 127 
+PASS Not throw: windows-1252 has a pointer 128 
+PASS Not throw: windows-1252 has a pointer 129 
+PASS Not throw: windows-1252 has a pointer 130 
+PASS Not throw: windows-1252 has a pointer 131 
+PASS Not throw: windows-1252 has a pointer 132 
+PASS Not throw: windows-1252 has a pointer 133 
+PASS Not throw: windows-1252 has a pointer 134 
+PASS Not throw: windows-1252 has a pointer 135 
+PASS Not throw: windows-1252 has a pointer 136 
+PASS Not throw: windows-1252 has a pointer 137 
+PASS Not throw: windows-1252 has a pointer 138 
+PASS Not throw: windows-1252 has a pointer 139 
+PASS Not throw: windows-1252 has a pointer 140 
+PASS Not throw: windows-1252 has a pointer 141 
+PASS Not throw: windows-1252 has a pointer 142 
+PASS Not throw: windows-1252 has a pointer 143 
+PASS Not throw: windows-1252 has a pointer 144 
+PASS Not throw: windows-1252 has a pointer 145 
+PASS Not throw: windows-1252 has a pointer 146 
+PASS Not throw: windows-1252 has a pointer 147 
+PASS Not throw: windows-1252 has a pointer 148 
+PASS Not throw: windows-1252 has a pointer 149 
+PASS Not throw: windows-1252 has a pointer 150 
+PASS Not throw: windows-1252 has a pointer 151 
+PASS Not throw: windows-1252 has a pointer 152 
+PASS Not throw: windows-1252 has a pointer 153 
+PASS Not throw: windows-1252 has a pointer 154 
+PASS Not throw: windows-1252 has a pointer 155 
+PASS Not throw: windows-1252 has a pointer 156 
+PASS Not throw: windows-1252 has a pointer 157 
+PASS Not throw: windows-1252 has a pointer 158 
+PASS Not throw: windows-1252 has a pointer 159 
+PASS Not throw: windows-1252 has a pointer 160 
+PASS Not throw: windows-1252 has a pointer 161 
+PASS Not throw: windows-1252 has a pointer 162 
+PASS Not throw: windows-1252 has a pointer 163 
+PASS Not throw: windows-1252 has a pointer 164 
+PASS Not throw: windows-1252 has a pointer 165 
+PASS Not throw: windows-1252 has a pointer 166 
+PASS Not throw: windows-1252 has a pointer 167 
+PASS Not throw: windows-1252 has a pointer 168 
+PASS Not throw: windows-1252 has a pointer 169 
+PASS Not throw: windows-1252 has a pointer 170 
+PASS Not throw: windows-1252 has a pointer 171 
+PASS Not throw: windows-1252 has a pointer 172 
+PASS Not throw: windows-1252 has a pointer 173 
+PASS Not throw: windows-1252 has a pointer 174 
+PASS Not throw: windows-1252 has a pointer 175 
+PASS Not throw: windows-1252 has a pointer 176 
+PASS Not throw: windows-1252 has a pointer 177 
+PASS Not throw: windows-1252 has a pointer 178 
+PASS Not throw: windows-1252 has a pointer 179 
+PASS Not throw: windows-1252 has a pointer 180 
+PASS Not throw: windows-1252 has a pointer 181 
+PASS Not throw: windows-1252 has a pointer 182 
+PASS Not throw: windows-1252 has a pointer 183 
+PASS Not throw: windows-1252 has a pointer 184 
+PASS Not throw: windows-1252 has a pointer 185 
+PASS Not throw: windows-1252 has a pointer 186 
+PASS Not throw: windows-1252 has a pointer 187 
+PASS Not throw: windows-1252 has a pointer 188 
+PASS Not throw: windows-1252 has a pointer 189 
+PASS Not throw: windows-1252 has a pointer 190 
+PASS Not throw: windows-1252 has a pointer 191 
+PASS Not throw: windows-1252 has a pointer 192 
+PASS Not throw: windows-1252 has a pointer 193 
+PASS Not throw: windows-1252 has a pointer 194 
+PASS Not throw: windows-1252 has a pointer 195 
+PASS Not throw: windows-1252 has a pointer 196 
+PASS Not throw: windows-1252 has a pointer 197 
+PASS Not throw: windows-1252 has a pointer 198 
+PASS Not throw: windows-1252 has a pointer 199 
+PASS Not throw: windows-1252 has a pointer 200 
+PASS Not throw: windows-1252 has a pointer 201 
+PASS Not throw: windows-1252 has a pointer 202 
+PASS Not throw: windows-1252 has a pointer 203 
+PASS Not throw: windows-1252 has a pointer 204 
+PASS Not throw: windows-1252 has a pointer 205 
+PASS Not throw: windows-1252 has a pointer 206 
+PASS Not throw: windows-1252 has a pointer 207 
+PASS Not throw: windows-1252 has a pointer 208 
+PASS Not throw: windows-1252 has a pointer 209 
+PASS Not throw: windows-1252 has a pointer 210 
+PASS Not throw: windows-1252 has a pointer 211 
+PASS Not throw: windows-1252 has a pointer 212 
+PASS Not throw: windows-1252 has a pointer 213 
+PASS Not throw: windows-1252 has a pointer 214 
+PASS Not throw: windows-1252 has a pointer 215 
+PASS Not throw: windows-1252 has a pointer 216 
+PASS Not throw: windows-1252 has a pointer 217 
+PASS Not throw: windows-1252 has a pointer 218 
+PASS Not throw: windows-1252 has a pointer 219 
+PASS Not throw: windows-1252 has a pointer 220 
+PASS Not throw: windows-1252 has a pointer 221 
+PASS Not throw: windows-1252 has a pointer 222 
+PASS Not throw: windows-1252 has a pointer 223 
+PASS Not throw: windows-1252 has a pointer 224 
+PASS Not throw: windows-1252 has a pointer 225 
+PASS Not throw: windows-1252 has a pointer 226 
+PASS Not throw: windows-1252 has a pointer 227 
+PASS Not throw: windows-1252 has a pointer 228 
+PASS Not throw: windows-1252 has a pointer 229 
+PASS Not throw: windows-1252 has a pointer 230 
+PASS Not throw: windows-1252 has a pointer 231 
+PASS Not throw: windows-1252 has a pointer 232 
+PASS Not throw: windows-1252 has a pointer 233 
+PASS Not throw: windows-1252 has a pointer 234 
+PASS Not throw: windows-1252 has a pointer 235 
+PASS Not throw: windows-1252 has a pointer 236 
+PASS Not throw: windows-1252 has a pointer 237 
+PASS Not throw: windows-1252 has a pointer 238 
+PASS Not throw: windows-1252 has a pointer 239 
+PASS Not throw: windows-1252 has a pointer 240 
+PASS Not throw: windows-1252 has a pointer 241 
+PASS Not throw: windows-1252 has a pointer 242 
+PASS Not throw: windows-1252 has a pointer 243 
+PASS Not throw: windows-1252 has a pointer 244 
+PASS Not throw: windows-1252 has a pointer 245 
+PASS Not throw: windows-1252 has a pointer 246 
+PASS Not throw: windows-1252 has a pointer 247 
+PASS Not throw: windows-1252 has a pointer 248 
+PASS Not throw: windows-1252 has a pointer 249 
+PASS Not throw: windows-1252 has a pointer 250 
+PASS Not throw: windows-1252 has a pointer 251 
+PASS Not throw: windows-1252 has a pointer 252 
+PASS Not throw: windows-1252 has a pointer 253 
+PASS Not throw: windows-1252 has a pointer 254 
+PASS Not throw: windows-1252 has a pointer 255 
+PASS Not throw: windows-1253 has a pointer 0 
+PASS Not throw: windows-1253 has a pointer 1 
+PASS Not throw: windows-1253 has a pointer 2 
+PASS Not throw: windows-1253 has a pointer 3 
+PASS Not throw: windows-1253 has a pointer 4 
+PASS Not throw: windows-1253 has a pointer 5 
+PASS Not throw: windows-1253 has a pointer 6 
+PASS Not throw: windows-1253 has a pointer 7 
+PASS Not throw: windows-1253 has a pointer 8 
+PASS Not throw: windows-1253 has a pointer 9 
+PASS Not throw: windows-1253 has a pointer 10 
+PASS Not throw: windows-1253 has a pointer 11 
+PASS Not throw: windows-1253 has a pointer 12 
+PASS Not throw: windows-1253 has a pointer 13 
+PASS Not throw: windows-1253 has a pointer 14 
+PASS Not throw: windows-1253 has a pointer 15 
+PASS Not throw: windows-1253 has a pointer 16 
+PASS Not throw: windows-1253 has a pointer 17 
+PASS Not throw: windows-1253 has a pointer 18 
+PASS Not throw: windows-1253 has a pointer 19 
+PASS Not throw: windows-1253 has a pointer 20 
+PASS Not throw: windows-1253 has a pointer 21 
+PASS Not throw: windows-1253 has a pointer 22 
+PASS Not throw: windows-1253 has a pointer 23 
+PASS Not throw: windows-1253 has a pointer 24 
+PASS Not throw: windows-1253 has a pointer 25 
+PASS Not throw: windows-1253 has a pointer 26 
+PASS Not throw: windows-1253 has a pointer 27 
+PASS Not throw: windows-1253 has a pointer 28 
+PASS Not throw: windows-1253 has a pointer 29 
+PASS Not throw: windows-1253 has a pointer 30 
+PASS Not throw: windows-1253 has a pointer 31 
+PASS Not throw: windows-1253 has a pointer 32 
+PASS Not throw: windows-1253 has a pointer 33 
+PASS Not throw: windows-1253 has a pointer 34 
+PASS Not throw: windows-1253 has a pointer 35 
+PASS Not throw: windows-1253 has a pointer 36 
+PASS Not throw: windows-1253 has a pointer 37 
+PASS Not throw: windows-1253 has a pointer 38 
+PASS Not throw: windows-1253 has a pointer 39 
+PASS Not throw: windows-1253 has a pointer 40 
+PASS Not throw: windows-1253 has a pointer 41 
+PASS Not throw: windows-1253 has a pointer 42 
+PASS Not throw: windows-1253 has a pointer 43 
+PASS Not throw: windows-1253 has a pointer 44 
+PASS Not throw: windows-1253 has a pointer 45 
+PASS Not throw: windows-1253 has a pointer 46 
+PASS Not throw: windows-1253 has a pointer 47 
+PASS Not throw: windows-1253 has a pointer 48 
+PASS Not throw: windows-1253 has a pointer 49 
+PASS Not throw: windows-1253 has a pointer 50 
+PASS Not throw: windows-1253 has a pointer 51 
+PASS Not throw: windows-1253 has a pointer 52 
+PASS Not throw: windows-1253 has a pointer 53 
+PASS Not throw: windows-1253 has a pointer 54 
+PASS Not throw: windows-1253 has a pointer 55 
+PASS Not throw: windows-1253 has a pointer 56 
+PASS Not throw: windows-1253 has a pointer 57 
+PASS Not throw: windows-1253 has a pointer 58 
+PASS Not throw: windows-1253 has a pointer 59 
+PASS Not throw: windows-1253 has a pointer 60 
+PASS Not throw: windows-1253 has a pointer 61 
+PASS Not throw: windows-1253 has a pointer 62 
+PASS Not throw: windows-1253 has a pointer 63 
+PASS Not throw: windows-1253 has a pointer 64 
+PASS Not throw: windows-1253 has a pointer 65 
+PASS Not throw: windows-1253 has a pointer 66 
+PASS Not throw: windows-1253 has a pointer 67 
+PASS Not throw: windows-1253 has a pointer 68 
+PASS Not throw: windows-1253 has a pointer 69 
+PASS Not throw: windows-1253 has a pointer 70 
+PASS Not throw: windows-1253 has a pointer 71 
+PASS Not throw: windows-1253 has a pointer 72 
+PASS Not throw: windows-1253 has a pointer 73 
+PASS Not throw: windows-1253 has a pointer 74 
+PASS Not throw: windows-1253 has a pointer 75 
+PASS Not throw: windows-1253 has a pointer 76 
+PASS Not throw: windows-1253 has a pointer 77 
+PASS Not throw: windows-1253 has a pointer 78 
+PASS Not throw: windows-1253 has a pointer 79 
+PASS Not throw: windows-1253 has a pointer 80 
+PASS Not throw: windows-1253 has a pointer 81 
+PASS Not throw: windows-1253 has a pointer 82 
+PASS Not throw: windows-1253 has a pointer 83 
+PASS Not throw: windows-1253 has a pointer 84 
+PASS Not throw: windows-1253 has a pointer 85 
+PASS Not throw: windows-1253 has a pointer 86 
+PASS Not throw: windows-1253 has a pointer 87 
+PASS Not throw: windows-1253 has a pointer 88 
+PASS Not throw: windows-1253 has a pointer 89 
+PASS Not throw: windows-1253 has a pointer 90 
+PASS Not throw: windows-1253 has a pointer 91 
+PASS Not throw: windows-1253 has a pointer 92 
+PASS Not throw: windows-1253 has a pointer 93 
+PASS Not throw: windows-1253 has a pointer 94 
+PASS Not throw: windows-1253 has a pointer 95 
+PASS Not throw: windows-1253 has a pointer 96 
+PASS Not throw: windows-1253 has a pointer 97 
+PASS Not throw: windows-1253 has a pointer 98 
+PASS Not throw: windows-1253 has a pointer 99 
+PASS Not throw: windows-1253 has a pointer 100 
+PASS Not throw: windows-1253 has a pointer 101 
+PASS Not throw: windows-1253 has a pointer 102 
+PASS Not throw: windows-1253 has a pointer 103 
+PASS Not throw: windows-1253 has a pointer 104 
+PASS Not throw: windows-1253 has a pointer 105 
+PASS Not throw: windows-1253 has a pointer 106 
+PASS Not throw: windows-1253 has a pointer 107 
+PASS Not throw: windows-1253 has a pointer 108 
+PASS Not throw: windows-1253 has a pointer 109 
+PASS Not throw: windows-1253 has a pointer 110 
+PASS Not throw: windows-1253 has a pointer 111 
+PASS Not throw: windows-1253 has a pointer 112 
+PASS Not throw: windows-1253 has a pointer 113 
+PASS Not throw: windows-1253 has a pointer 114 
+PASS Not throw: windows-1253 has a pointer 115 
+PASS Not throw: windows-1253 has a pointer 116 
+PASS Not throw: windows-1253 has a pointer 117 
+PASS Not throw: windows-1253 has a pointer 118 
+PASS Not throw: windows-1253 has a pointer 119 
+PASS Not throw: windows-1253 has a pointer 120 
+PASS Not throw: windows-1253 has a pointer 121 
+PASS Not throw: windows-1253 has a pointer 122 
+PASS Not throw: windows-1253 has a pointer 123 
+PASS Not throw: windows-1253 has a pointer 124 
+PASS Not throw: windows-1253 has a pointer 125 
+PASS Not throw: windows-1253 has a pointer 126 
+PASS Not throw: windows-1253 has a pointer 127 
+PASS Not throw: windows-1253 has a pointer 128 
+PASS Not throw: windows-1253 has a pointer 129 
+PASS Not throw: windows-1253 has a pointer 130 
+PASS Not throw: windows-1253 has a pointer 131 
+PASS Not throw: windows-1253 has a pointer 132 
+PASS Not throw: windows-1253 has a pointer 133 
+PASS Not throw: windows-1253 has a pointer 134 
+PASS Not throw: windows-1253 has a pointer 135 
+PASS Not throw: windows-1253 has a pointer 136 
+PASS Not throw: windows-1253 has a pointer 137 
+PASS Not throw: windows-1253 has a pointer 138 
+PASS Not throw: windows-1253 has a pointer 139 
+PASS Not throw: windows-1253 has a pointer 140 
+PASS Not throw: windows-1253 has a pointer 141 
+PASS Not throw: windows-1253 has a pointer 142 
+PASS Not throw: windows-1253 has a pointer 143 
+PASS Not throw: windows-1253 has a pointer 144 
+PASS Not throw: windows-1253 has a pointer 145 
+PASS Not throw: windows-1253 has a pointer 146 
+PASS Not throw: windows-1253 has a pointer 147 
+PASS Not throw: windows-1253 has a pointer 148 
+PASS Not throw: windows-1253 has a pointer 149 
+PASS Not throw: windows-1253 has a pointer 150 
+PASS Not throw: windows-1253 has a pointer 151 
+PASS Not throw: windows-1253 has a pointer 152 
+PASS Not throw: windows-1253 has a pointer 153 
+PASS Not throw: windows-1253 has a pointer 154 
+PASS Not throw: windows-1253 has a pointer 155 
+PASS Not throw: windows-1253 has a pointer 156 
+PASS Not throw: windows-1253 has a pointer 157 
+PASS Not throw: windows-1253 has a pointer 158 
+PASS Not throw: windows-1253 has a pointer 159 
+PASS Not throw: windows-1253 has a pointer 160 
+PASS Not throw: windows-1253 has a pointer 161 
+PASS Not throw: windows-1253 has a pointer 162 
+PASS Not throw: windows-1253 has a pointer 163 
+PASS Not throw: windows-1253 has a pointer 164 
+PASS Not throw: windows-1253 has a pointer 165 
+PASS Not throw: windows-1253 has a pointer 166 
+PASS Not throw: windows-1253 has a pointer 167 
+PASS Not throw: windows-1253 has a pointer 168 
+PASS Not throw: windows-1253 has a pointer 169 
+FAIL Throw due to fatal flag: windows-1253 doesn't have a pointer 170 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1253 has a pointer 171 
+PASS Not throw: windows-1253 has a pointer 172 
+PASS Not throw: windows-1253 has a pointer 173 
+PASS Not throw: windows-1253 has a pointer 174 
+PASS Not throw: windows-1253 has a pointer 175 
+PASS Not throw: windows-1253 has a pointer 176 
+PASS Not throw: windows-1253 has a pointer 177 
+PASS Not throw: windows-1253 has a pointer 178 
+PASS Not throw: windows-1253 has a pointer 179 
+PASS Not throw: windows-1253 has a pointer 180 
+PASS Not throw: windows-1253 has a pointer 181 
+PASS Not throw: windows-1253 has a pointer 182 
+PASS Not throw: windows-1253 has a pointer 183 
+PASS Not throw: windows-1253 has a pointer 184 
+PASS Not throw: windows-1253 has a pointer 185 
+PASS Not throw: windows-1253 has a pointer 186 
+PASS Not throw: windows-1253 has a pointer 187 
+PASS Not throw: windows-1253 has a pointer 188 
+PASS Not throw: windows-1253 has a pointer 189 
+PASS Not throw: windows-1253 has a pointer 190 
+PASS Not throw: windows-1253 has a pointer 191 
+PASS Not throw: windows-1253 has a pointer 192 
+PASS Not throw: windows-1253 has a pointer 193 
+PASS Not throw: windows-1253 has a pointer 194 
+PASS Not throw: windows-1253 has a pointer 195 
+PASS Not throw: windows-1253 has a pointer 196 
+PASS Not throw: windows-1253 has a pointer 197 
+PASS Not throw: windows-1253 has a pointer 198 
+PASS Not throw: windows-1253 has a pointer 199 
+PASS Not throw: windows-1253 has a pointer 200 
+PASS Not throw: windows-1253 has a pointer 201 
+PASS Not throw: windows-1253 has a pointer 202 
+PASS Not throw: windows-1253 has a pointer 203 
+PASS Not throw: windows-1253 has a pointer 204 
+PASS Not throw: windows-1253 has a pointer 205 
+PASS Not throw: windows-1253 has a pointer 206 
+PASS Not throw: windows-1253 has a pointer 207 
+PASS Not throw: windows-1253 has a pointer 208 
+PASS Not throw: windows-1253 has a pointer 209 
+FAIL Throw due to fatal flag: windows-1253 doesn't have a pointer 210 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1253 has a pointer 211 
+PASS Not throw: windows-1253 has a pointer 212 
+PASS Not throw: windows-1253 has a pointer 213 
+PASS Not throw: windows-1253 has a pointer 214 
+PASS Not throw: windows-1253 has a pointer 215 
+PASS Not throw: windows-1253 has a pointer 216 
+PASS Not throw: windows-1253 has a pointer 217 
+PASS Not throw: windows-1253 has a pointer 218 
+PASS Not throw: windows-1253 has a pointer 219 
+PASS Not throw: windows-1253 has a pointer 220 
+PASS Not throw: windows-1253 has a pointer 221 
+PASS Not throw: windows-1253 has a pointer 222 
+PASS Not throw: windows-1253 has a pointer 223 
+PASS Not throw: windows-1253 has a pointer 224 
+PASS Not throw: windows-1253 has a pointer 225 
+PASS Not throw: windows-1253 has a pointer 226 
+PASS Not throw: windows-1253 has a pointer 227 
+PASS Not throw: windows-1253 has a pointer 228 
+PASS Not throw: windows-1253 has a pointer 229 
+PASS Not throw: windows-1253 has a pointer 230 
+PASS Not throw: windows-1253 has a pointer 231 
+PASS Not throw: windows-1253 has a pointer 232 
+PASS Not throw: windows-1253 has a pointer 233 
+PASS Not throw: windows-1253 has a pointer 234 
+PASS Not throw: windows-1253 has a pointer 235 
+PASS Not throw: windows-1253 has a pointer 236 
+PASS Not throw: windows-1253 has a pointer 237 
+PASS Not throw: windows-1253 has a pointer 238 
+PASS Not throw: windows-1253 has a pointer 239 
+PASS Not throw: windows-1253 has a pointer 240 
+PASS Not throw: windows-1253 has a pointer 241 
+PASS Not throw: windows-1253 has a pointer 242 
+PASS Not throw: windows-1253 has a pointer 243 
+PASS Not throw: windows-1253 has a pointer 244 
+PASS Not throw: windows-1253 has a pointer 245 
+PASS Not throw: windows-1253 has a pointer 246 
+PASS Not throw: windows-1253 has a pointer 247 
+PASS Not throw: windows-1253 has a pointer 248 
+PASS Not throw: windows-1253 has a pointer 249 
+PASS Not throw: windows-1253 has a pointer 250 
+PASS Not throw: windows-1253 has a pointer 251 
+PASS Not throw: windows-1253 has a pointer 252 
+PASS Not throw: windows-1253 has a pointer 253 
+PASS Not throw: windows-1253 has a pointer 254 
+FAIL Throw due to fatal flag: windows-1253 doesn't have a pointer 255 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1254 has a pointer 0 
+PASS Not throw: windows-1254 has a pointer 1 
+PASS Not throw: windows-1254 has a pointer 2 
+PASS Not throw: windows-1254 has a pointer 3 
+PASS Not throw: windows-1254 has a pointer 4 
+PASS Not throw: windows-1254 has a pointer 5 
+PASS Not throw: windows-1254 has a pointer 6 
+PASS Not throw: windows-1254 has a pointer 7 
+PASS Not throw: windows-1254 has a pointer 8 
+PASS Not throw: windows-1254 has a pointer 9 
+PASS Not throw: windows-1254 has a pointer 10 
+PASS Not throw: windows-1254 has a pointer 11 
+PASS Not throw: windows-1254 has a pointer 12 
+PASS Not throw: windows-1254 has a pointer 13 
+PASS Not throw: windows-1254 has a pointer 14 
+PASS Not throw: windows-1254 has a pointer 15 
+PASS Not throw: windows-1254 has a pointer 16 
+PASS Not throw: windows-1254 has a pointer 17 
+PASS Not throw: windows-1254 has a pointer 18 
+PASS Not throw: windows-1254 has a pointer 19 
+PASS Not throw: windows-1254 has a pointer 20 
+PASS Not throw: windows-1254 has a pointer 21 
+PASS Not throw: windows-1254 has a pointer 22 
+PASS Not throw: windows-1254 has a pointer 23 
+PASS Not throw: windows-1254 has a pointer 24 
+PASS Not throw: windows-1254 has a pointer 25 
+PASS Not throw: windows-1254 has a pointer 26 
+PASS Not throw: windows-1254 has a pointer 27 
+PASS Not throw: windows-1254 has a pointer 28 
+PASS Not throw: windows-1254 has a pointer 29 
+PASS Not throw: windows-1254 has a pointer 30 
+PASS Not throw: windows-1254 has a pointer 31 
+PASS Not throw: windows-1254 has a pointer 32 
+PASS Not throw: windows-1254 has a pointer 33 
+PASS Not throw: windows-1254 has a pointer 34 
+PASS Not throw: windows-1254 has a pointer 35 
+PASS Not throw: windows-1254 has a pointer 36 
+PASS Not throw: windows-1254 has a pointer 37 
+PASS Not throw: windows-1254 has a pointer 38 
+PASS Not throw: windows-1254 has a pointer 39 
+PASS Not throw: windows-1254 has a pointer 40 
+PASS Not throw: windows-1254 has a pointer 41 
+PASS Not throw: windows-1254 has a pointer 42 
+PASS Not throw: windows-1254 has a pointer 43 
+PASS Not throw: windows-1254 has a pointer 44 
+PASS Not throw: windows-1254 has a pointer 45 
+PASS Not throw: windows-1254 has a pointer 46 
+PASS Not throw: windows-1254 has a pointer 47 
+PASS Not throw: windows-1254 has a pointer 48 
+PASS Not throw: windows-1254 has a pointer 49 
+PASS Not throw: windows-1254 has a pointer 50 
+PASS Not throw: windows-1254 has a pointer 51 
+PASS Not throw: windows-1254 has a pointer 52 
+PASS Not throw: windows-1254 has a pointer 53 
+PASS Not throw: windows-1254 has a pointer 54 
+PASS Not throw: windows-1254 has a pointer 55 
+PASS Not throw: windows-1254 has a pointer 56 
+PASS Not throw: windows-1254 has a pointer 57 
+PASS Not throw: windows-1254 has a pointer 58 
+PASS Not throw: windows-1254 has a pointer 59 
+PASS Not throw: windows-1254 has a pointer 60 
+PASS Not throw: windows-1254 has a pointer 61 
+PASS Not throw: windows-1254 has a pointer 62 
+PASS Not throw: windows-1254 has a pointer 63 
+PASS Not throw: windows-1254 has a pointer 64 
+PASS Not throw: windows-1254 has a pointer 65 
+PASS Not throw: windows-1254 has a pointer 66 
+PASS Not throw: windows-1254 has a pointer 67 
+PASS Not throw: windows-1254 has a pointer 68 
+PASS Not throw: windows-1254 has a pointer 69 
+PASS Not throw: windows-1254 has a pointer 70 
+PASS Not throw: windows-1254 has a pointer 71 
+PASS Not throw: windows-1254 has a pointer 72 
+PASS Not throw: windows-1254 has a pointer 73 
+PASS Not throw: windows-1254 has a pointer 74 
+PASS Not throw: windows-1254 has a pointer 75 
+PASS Not throw: windows-1254 has a pointer 76 
+PASS Not throw: windows-1254 has a pointer 77 
+PASS Not throw: windows-1254 has a pointer 78 
+PASS Not throw: windows-1254 has a pointer 79 
+PASS Not throw: windows-1254 has a pointer 80 
+PASS Not throw: windows-1254 has a pointer 81 
+PASS Not throw: windows-1254 has a pointer 82 
+PASS Not throw: windows-1254 has a pointer 83 
+PASS Not throw: windows-1254 has a pointer 84 
+PASS Not throw: windows-1254 has a pointer 85 
+PASS Not throw: windows-1254 has a pointer 86 
+PASS Not throw: windows-1254 has a pointer 87 
+PASS Not throw: windows-1254 has a pointer 88 
+PASS Not throw: windows-1254 has a pointer 89 
+PASS Not throw: windows-1254 has a pointer 90 
+PASS Not throw: windows-1254 has a pointer 91 
+PASS Not throw: windows-1254 has a pointer 92 
+PASS Not throw: windows-1254 has a pointer 93 
+PASS Not throw: windows-1254 has a pointer 94 
+PASS Not throw: windows-1254 has a pointer 95 
+PASS Not throw: windows-1254 has a pointer 96 
+PASS Not throw: windows-1254 has a pointer 97 
+PASS Not throw: windows-1254 has a pointer 98 
+PASS Not throw: windows-1254 has a pointer 99 
+PASS Not throw: windows-1254 has a pointer 100 
+PASS Not throw: windows-1254 has a pointer 101 
+PASS Not throw: windows-1254 has a pointer 102 
+PASS Not throw: windows-1254 has a pointer 103 
+PASS Not throw: windows-1254 has a pointer 104 
+PASS Not throw: windows-1254 has a pointer 105 
+PASS Not throw: windows-1254 has a pointer 106 
+PASS Not throw: windows-1254 has a pointer 107 
+PASS Not throw: windows-1254 has a pointer 108 
+PASS Not throw: windows-1254 has a pointer 109 
+PASS Not throw: windows-1254 has a pointer 110 
+PASS Not throw: windows-1254 has a pointer 111 
+PASS Not throw: windows-1254 has a pointer 112 
+PASS Not throw: windows-1254 has a pointer 113 
+PASS Not throw: windows-1254 has a pointer 114 
+PASS Not throw: windows-1254 has a pointer 115 
+PASS Not throw: windows-1254 has a pointer 116 
+PASS Not throw: windows-1254 has a pointer 117 
+PASS Not throw: windows-1254 has a pointer 118 
+PASS Not throw: windows-1254 has a pointer 119 
+PASS Not throw: windows-1254 has a pointer 120 
+PASS Not throw: windows-1254 has a pointer 121 
+PASS Not throw: windows-1254 has a pointer 122 
+PASS Not throw: windows-1254 has a pointer 123 
+PASS Not throw: windows-1254 has a pointer 124 
+PASS Not throw: windows-1254 has a pointer 125 
+PASS Not throw: windows-1254 has a pointer 126 
+PASS Not throw: windows-1254 has a pointer 127 
+PASS Not throw: windows-1254 has a pointer 128 
+PASS Not throw: windows-1254 has a pointer 129 
+PASS Not throw: windows-1254 has a pointer 130 
+PASS Not throw: windows-1254 has a pointer 131 
+PASS Not throw: windows-1254 has a pointer 132 
+PASS Not throw: windows-1254 has a pointer 133 
+PASS Not throw: windows-1254 has a pointer 134 
+PASS Not throw: windows-1254 has a pointer 135 
+PASS Not throw: windows-1254 has a pointer 136 
+PASS Not throw: windows-1254 has a pointer 137 
+PASS Not throw: windows-1254 has a pointer 138 
+PASS Not throw: windows-1254 has a pointer 139 
+PASS Not throw: windows-1254 has a pointer 140 
+PASS Not throw: windows-1254 has a pointer 141 
+PASS Not throw: windows-1254 has a pointer 142 
+PASS Not throw: windows-1254 has a pointer 143 
+PASS Not throw: windows-1254 has a pointer 144 
+PASS Not throw: windows-1254 has a pointer 145 
+PASS Not throw: windows-1254 has a pointer 146 
+PASS Not throw: windows-1254 has a pointer 147 
+PASS Not throw: windows-1254 has a pointer 148 
+PASS Not throw: windows-1254 has a pointer 149 
+PASS Not throw: windows-1254 has a pointer 150 
+PASS Not throw: windows-1254 has a pointer 151 
+PASS Not throw: windows-1254 has a pointer 152 
+PASS Not throw: windows-1254 has a pointer 153 
+PASS Not throw: windows-1254 has a pointer 154 
+PASS Not throw: windows-1254 has a pointer 155 
+PASS Not throw: windows-1254 has a pointer 156 
+PASS Not throw: windows-1254 has a pointer 157 
+PASS Not throw: windows-1254 has a pointer 158 
+PASS Not throw: windows-1254 has a pointer 159 
+PASS Not throw: windows-1254 has a pointer 160 
+PASS Not throw: windows-1254 has a pointer 161 
+PASS Not throw: windows-1254 has a pointer 162 
+PASS Not throw: windows-1254 has a pointer 163 
+PASS Not throw: windows-1254 has a pointer 164 
+PASS Not throw: windows-1254 has a pointer 165 
+PASS Not throw: windows-1254 has a pointer 166 
+PASS Not throw: windows-1254 has a pointer 167 
+PASS Not throw: windows-1254 has a pointer 168 
+PASS Not throw: windows-1254 has a pointer 169 
+PASS Not throw: windows-1254 has a pointer 170 
+PASS Not throw: windows-1254 has a pointer 171 
+PASS Not throw: windows-1254 has a pointer 172 
+PASS Not throw: windows-1254 has a pointer 173 
+PASS Not throw: windows-1254 has a pointer 174 
+PASS Not throw: windows-1254 has a pointer 175 
+PASS Not throw: windows-1254 has a pointer 176 
+PASS Not throw: windows-1254 has a pointer 177 
+PASS Not throw: windows-1254 has a pointer 178 
+PASS Not throw: windows-1254 has a pointer 179 
+PASS Not throw: windows-1254 has a pointer 180 
+PASS Not throw: windows-1254 has a pointer 181 
+PASS Not throw: windows-1254 has a pointer 182 
+PASS Not throw: windows-1254 has a pointer 183 
+PASS Not throw: windows-1254 has a pointer 184 
+PASS Not throw: windows-1254 has a pointer 185 
+PASS Not throw: windows-1254 has a pointer 186 
+PASS Not throw: windows-1254 has a pointer 187 
+PASS Not throw: windows-1254 has a pointer 188 
+PASS Not throw: windows-1254 has a pointer 189 
+PASS Not throw: windows-1254 has a pointer 190 
+PASS Not throw: windows-1254 has a pointer 191 
+PASS Not throw: windows-1254 has a pointer 192 
+PASS Not throw: windows-1254 has a pointer 193 
+PASS Not throw: windows-1254 has a pointer 194 
+PASS Not throw: windows-1254 has a pointer 195 
+PASS Not throw: windows-1254 has a pointer 196 
+PASS Not throw: windows-1254 has a pointer 197 
+PASS Not throw: windows-1254 has a pointer 198 
+PASS Not throw: windows-1254 has a pointer 199 
+PASS Not throw: windows-1254 has a pointer 200 
+PASS Not throw: windows-1254 has a pointer 201 
+PASS Not throw: windows-1254 has a pointer 202 
+PASS Not throw: windows-1254 has a pointer 203 
+PASS Not throw: windows-1254 has a pointer 204 
+PASS Not throw: windows-1254 has a pointer 205 
+PASS Not throw: windows-1254 has a pointer 206 
+PASS Not throw: windows-1254 has a pointer 207 
+PASS Not throw: windows-1254 has a pointer 208 
+PASS Not throw: windows-1254 has a pointer 209 
+PASS Not throw: windows-1254 has a pointer 210 
+PASS Not throw: windows-1254 has a pointer 211 
+PASS Not throw: windows-1254 has a pointer 212 
+PASS Not throw: windows-1254 has a pointer 213 
+PASS Not throw: windows-1254 has a pointer 214 
+PASS Not throw: windows-1254 has a pointer 215 
+PASS Not throw: windows-1254 has a pointer 216 
+PASS Not throw: windows-1254 has a pointer 217 
+PASS Not throw: windows-1254 has a pointer 218 
+PASS Not throw: windows-1254 has a pointer 219 
+PASS Not throw: windows-1254 has a pointer 220 
+PASS Not throw: windows-1254 has a pointer 221 
+PASS Not throw: windows-1254 has a pointer 222 
+PASS Not throw: windows-1254 has a pointer 223 
+PASS Not throw: windows-1254 has a pointer 224 
+PASS Not throw: windows-1254 has a pointer 225 
+PASS Not throw: windows-1254 has a pointer 226 
+PASS Not throw: windows-1254 has a pointer 227 
+PASS Not throw: windows-1254 has a pointer 228 
+PASS Not throw: windows-1254 has a pointer 229 
+PASS Not throw: windows-1254 has a pointer 230 
+PASS Not throw: windows-1254 has a pointer 231 
+PASS Not throw: windows-1254 has a pointer 232 
+PASS Not throw: windows-1254 has a pointer 233 
+PASS Not throw: windows-1254 has a pointer 234 
+PASS Not throw: windows-1254 has a pointer 235 
+PASS Not throw: windows-1254 has a pointer 236 
+PASS Not throw: windows-1254 has a pointer 237 
+PASS Not throw: windows-1254 has a pointer 238 
+PASS Not throw: windows-1254 has a pointer 239 
+PASS Not throw: windows-1254 has a pointer 240 
+PASS Not throw: windows-1254 has a pointer 241 
+PASS Not throw: windows-1254 has a pointer 242 
+PASS Not throw: windows-1254 has a pointer 243 
+PASS Not throw: windows-1254 has a pointer 244 
+PASS Not throw: windows-1254 has a pointer 245 
+PASS Not throw: windows-1254 has a pointer 246 
+PASS Not throw: windows-1254 has a pointer 247 
+PASS Not throw: windows-1254 has a pointer 248 
+PASS Not throw: windows-1254 has a pointer 249 
+PASS Not throw: windows-1254 has a pointer 250 
+PASS Not throw: windows-1254 has a pointer 251 
+PASS Not throw: windows-1254 has a pointer 252 
+PASS Not throw: windows-1254 has a pointer 253 
+PASS Not throw: windows-1254 has a pointer 254 
+PASS Not throw: windows-1254 has a pointer 255 
+PASS Not throw: windows-1255 has a pointer 0 
+PASS Not throw: windows-1255 has a pointer 1 
+PASS Not throw: windows-1255 has a pointer 2 
+PASS Not throw: windows-1255 has a pointer 3 
+PASS Not throw: windows-1255 has a pointer 4 
+PASS Not throw: windows-1255 has a pointer 5 
+PASS Not throw: windows-1255 has a pointer 6 
+PASS Not throw: windows-1255 has a pointer 7 
+PASS Not throw: windows-1255 has a pointer 8 
+PASS Not throw: windows-1255 has a pointer 9 
+PASS Not throw: windows-1255 has a pointer 10 
+PASS Not throw: windows-1255 has a pointer 11 
+PASS Not throw: windows-1255 has a pointer 12 
+PASS Not throw: windows-1255 has a pointer 13 
+PASS Not throw: windows-1255 has a pointer 14 
+PASS Not throw: windows-1255 has a pointer 15 
+PASS Not throw: windows-1255 has a pointer 16 
+PASS Not throw: windows-1255 has a pointer 17 
+PASS Not throw: windows-1255 has a pointer 18 
+PASS Not throw: windows-1255 has a pointer 19 
+PASS Not throw: windows-1255 has a pointer 20 
+PASS Not throw: windows-1255 has a pointer 21 
+PASS Not throw: windows-1255 has a pointer 22 
+PASS Not throw: windows-1255 has a pointer 23 
+PASS Not throw: windows-1255 has a pointer 24 
+PASS Not throw: windows-1255 has a pointer 25 
+PASS Not throw: windows-1255 has a pointer 26 
+PASS Not throw: windows-1255 has a pointer 27 
+PASS Not throw: windows-1255 has a pointer 28 
+PASS Not throw: windows-1255 has a pointer 29 
+PASS Not throw: windows-1255 has a pointer 30 
+PASS Not throw: windows-1255 has a pointer 31 
+PASS Not throw: windows-1255 has a pointer 32 
+PASS Not throw: windows-1255 has a pointer 33 
+PASS Not throw: windows-1255 has a pointer 34 
+PASS Not throw: windows-1255 has a pointer 35 
+PASS Not throw: windows-1255 has a pointer 36 
+PASS Not throw: windows-1255 has a pointer 37 
+PASS Not throw: windows-1255 has a pointer 38 
+PASS Not throw: windows-1255 has a pointer 39 
+PASS Not throw: windows-1255 has a pointer 40 
+PASS Not throw: windows-1255 has a pointer 41 
+PASS Not throw: windows-1255 has a pointer 42 
+PASS Not throw: windows-1255 has a pointer 43 
+PASS Not throw: windows-1255 has a pointer 44 
+PASS Not throw: windows-1255 has a pointer 45 
+PASS Not throw: windows-1255 has a pointer 46 
+PASS Not throw: windows-1255 has a pointer 47 
+PASS Not throw: windows-1255 has a pointer 48 
+PASS Not throw: windows-1255 has a pointer 49 
+PASS Not throw: windows-1255 has a pointer 50 
+PASS Not throw: windows-1255 has a pointer 51 
+PASS Not throw: windows-1255 has a pointer 52 
+PASS Not throw: windows-1255 has a pointer 53 
+PASS Not throw: windows-1255 has a pointer 54 
+PASS Not throw: windows-1255 has a pointer 55 
+PASS Not throw: windows-1255 has a pointer 56 
+PASS Not throw: windows-1255 has a pointer 57 
+PASS Not throw: windows-1255 has a pointer 58 
+PASS Not throw: windows-1255 has a pointer 59 
+PASS Not throw: windows-1255 has a pointer 60 
+PASS Not throw: windows-1255 has a pointer 61 
+PASS Not throw: windows-1255 has a pointer 62 
+PASS Not throw: windows-1255 has a pointer 63 
+PASS Not throw: windows-1255 has a pointer 64 
+PASS Not throw: windows-1255 has a pointer 65 
+PASS Not throw: windows-1255 has a pointer 66 
+PASS Not throw: windows-1255 has a pointer 67 
+PASS Not throw: windows-1255 has a pointer 68 
+PASS Not throw: windows-1255 has a pointer 69 
+PASS Not throw: windows-1255 has a pointer 70 
+PASS Not throw: windows-1255 has a pointer 71 
+PASS Not throw: windows-1255 has a pointer 72 
+PASS Not throw: windows-1255 has a pointer 73 
+PASS Not throw: windows-1255 has a pointer 74 
+PASS Not throw: windows-1255 has a pointer 75 
+PASS Not throw: windows-1255 has a pointer 76 
+PASS Not throw: windows-1255 has a pointer 77 
+PASS Not throw: windows-1255 has a pointer 78 
+PASS Not throw: windows-1255 has a pointer 79 
+PASS Not throw: windows-1255 has a pointer 80 
+PASS Not throw: windows-1255 has a pointer 81 
+PASS Not throw: windows-1255 has a pointer 82 
+PASS Not throw: windows-1255 has a pointer 83 
+PASS Not throw: windows-1255 has a pointer 84 
+PASS Not throw: windows-1255 has a pointer 85 
+PASS Not throw: windows-1255 has a pointer 86 
+PASS Not throw: windows-1255 has a pointer 87 
+PASS Not throw: windows-1255 has a pointer 88 
+PASS Not throw: windows-1255 has a pointer 89 
+PASS Not throw: windows-1255 has a pointer 90 
+PASS Not throw: windows-1255 has a pointer 91 
+PASS Not throw: windows-1255 has a pointer 92 
+PASS Not throw: windows-1255 has a pointer 93 
+PASS Not throw: windows-1255 has a pointer 94 
+PASS Not throw: windows-1255 has a pointer 95 
+PASS Not throw: windows-1255 has a pointer 96 
+PASS Not throw: windows-1255 has a pointer 97 
+PASS Not throw: windows-1255 has a pointer 98 
+PASS Not throw: windows-1255 has a pointer 99 
+PASS Not throw: windows-1255 has a pointer 100 
+PASS Not throw: windows-1255 has a pointer 101 
+PASS Not throw: windows-1255 has a pointer 102 
+PASS Not throw: windows-1255 has a pointer 103 
+PASS Not throw: windows-1255 has a pointer 104 
+PASS Not throw: windows-1255 has a pointer 105 
+PASS Not throw: windows-1255 has a pointer 106 
+PASS Not throw: windows-1255 has a pointer 107 
+PASS Not throw: windows-1255 has a pointer 108 
+PASS Not throw: windows-1255 has a pointer 109 
+PASS Not throw: windows-1255 has a pointer 110 
+PASS Not throw: windows-1255 has a pointer 111 
+PASS Not throw: windows-1255 has a pointer 112 
+PASS Not throw: windows-1255 has a pointer 113 
+PASS Not throw: windows-1255 has a pointer 114 
+PASS Not throw: windows-1255 has a pointer 115 
+PASS Not throw: windows-1255 has a pointer 116 
+PASS Not throw: windows-1255 has a pointer 117 
+PASS Not throw: windows-1255 has a pointer 118 
+PASS Not throw: windows-1255 has a pointer 119 
+PASS Not throw: windows-1255 has a pointer 120 
+PASS Not throw: windows-1255 has a pointer 121 
+PASS Not throw: windows-1255 has a pointer 122 
+PASS Not throw: windows-1255 has a pointer 123 
+PASS Not throw: windows-1255 has a pointer 124 
+PASS Not throw: windows-1255 has a pointer 125 
+PASS Not throw: windows-1255 has a pointer 126 
+PASS Not throw: windows-1255 has a pointer 127 
+PASS Not throw: windows-1255 has a pointer 128 
+PASS Not throw: windows-1255 has a pointer 129 
+PASS Not throw: windows-1255 has a pointer 130 
+PASS Not throw: windows-1255 has a pointer 131 
+PASS Not throw: windows-1255 has a pointer 132 
+PASS Not throw: windows-1255 has a pointer 133 
+PASS Not throw: windows-1255 has a pointer 134 
+PASS Not throw: windows-1255 has a pointer 135 
+PASS Not throw: windows-1255 has a pointer 136 
+PASS Not throw: windows-1255 has a pointer 137 
+PASS Not throw: windows-1255 has a pointer 138 
+PASS Not throw: windows-1255 has a pointer 139 
+PASS Not throw: windows-1255 has a pointer 140 
+PASS Not throw: windows-1255 has a pointer 141 
+PASS Not throw: windows-1255 has a pointer 142 
+PASS Not throw: windows-1255 has a pointer 143 
+PASS Not throw: windows-1255 has a pointer 144 
+PASS Not throw: windows-1255 has a pointer 145 
+PASS Not throw: windows-1255 has a pointer 146 
+PASS Not throw: windows-1255 has a pointer 147 
+PASS Not throw: windows-1255 has a pointer 148 
+PASS Not throw: windows-1255 has a pointer 149 
+PASS Not throw: windows-1255 has a pointer 150 
+PASS Not throw: windows-1255 has a pointer 151 
+PASS Not throw: windows-1255 has a pointer 152 
+PASS Not throw: windows-1255 has a pointer 153 
+PASS Not throw: windows-1255 has a pointer 154 
+PASS Not throw: windows-1255 has a pointer 155 
+PASS Not throw: windows-1255 has a pointer 156 
+PASS Not throw: windows-1255 has a pointer 157 
+PASS Not throw: windows-1255 has a pointer 158 
+PASS Not throw: windows-1255 has a pointer 159 
+PASS Not throw: windows-1255 has a pointer 160 
+PASS Not throw: windows-1255 has a pointer 161 
+PASS Not throw: windows-1255 has a pointer 162 
+PASS Not throw: windows-1255 has a pointer 163 
+PASS Not throw: windows-1255 has a pointer 164 
+PASS Not throw: windows-1255 has a pointer 165 
+PASS Not throw: windows-1255 has a pointer 166 
+PASS Not throw: windows-1255 has a pointer 167 
+PASS Not throw: windows-1255 has a pointer 168 
+PASS Not throw: windows-1255 has a pointer 169 
+PASS Not throw: windows-1255 has a pointer 170 
+PASS Not throw: windows-1255 has a pointer 171 
+PASS Not throw: windows-1255 has a pointer 172 
+PASS Not throw: windows-1255 has a pointer 173 
+PASS Not throw: windows-1255 has a pointer 174 
+PASS Not throw: windows-1255 has a pointer 175 
+PASS Not throw: windows-1255 has a pointer 176 
+PASS Not throw: windows-1255 has a pointer 177 
+PASS Not throw: windows-1255 has a pointer 178 
+PASS Not throw: windows-1255 has a pointer 179 
+PASS Not throw: windows-1255 has a pointer 180 
+PASS Not throw: windows-1255 has a pointer 181 
+PASS Not throw: windows-1255 has a pointer 182 
+PASS Not throw: windows-1255 has a pointer 183 
+PASS Not throw: windows-1255 has a pointer 184 
+PASS Not throw: windows-1255 has a pointer 185 
+PASS Not throw: windows-1255 has a pointer 186 
+PASS Not throw: windows-1255 has a pointer 187 
+PASS Not throw: windows-1255 has a pointer 188 
+PASS Not throw: windows-1255 has a pointer 189 
+PASS Not throw: windows-1255 has a pointer 190 
+PASS Not throw: windows-1255 has a pointer 191 
+PASS Not throw: windows-1255 has a pointer 192 
+PASS Not throw: windows-1255 has a pointer 193 
+PASS Not throw: windows-1255 has a pointer 194 
+PASS Not throw: windows-1255 has a pointer 195 
+PASS Not throw: windows-1255 has a pointer 196 
+PASS Not throw: windows-1255 has a pointer 197 
+PASS Not throw: windows-1255 has a pointer 198 
+PASS Not throw: windows-1255 has a pointer 199 
+PASS Not throw: windows-1255 has a pointer 200 
+PASS Not throw: windows-1255 has a pointer 201 
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 202 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1255 has a pointer 203 
+PASS Not throw: windows-1255 has a pointer 204 
+PASS Not throw: windows-1255 has a pointer 205 
+PASS Not throw: windows-1255 has a pointer 206 
+PASS Not throw: windows-1255 has a pointer 207 
+PASS Not throw: windows-1255 has a pointer 208 
+PASS Not throw: windows-1255 has a pointer 209 
+PASS Not throw: windows-1255 has a pointer 210 
+PASS Not throw: windows-1255 has a pointer 211 
+PASS Not throw: windows-1255 has a pointer 212 
+PASS Not throw: windows-1255 has a pointer 213 
+PASS Not throw: windows-1255 has a pointer 214 
+PASS Not throw: windows-1255 has a pointer 215 
+PASS Not throw: windows-1255 has a pointer 216 
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 217 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 218 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 219 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 220 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 221 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 222 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 223 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1255 has a pointer 224 
+PASS Not throw: windows-1255 has a pointer 225 
+PASS Not throw: windows-1255 has a pointer 226 
+PASS Not throw: windows-1255 has a pointer 227 
+PASS Not throw: windows-1255 has a pointer 228 
+PASS Not throw: windows-1255 has a pointer 229 
+PASS Not throw: windows-1255 has a pointer 230 
+PASS Not throw: windows-1255 has a pointer 231 
+PASS Not throw: windows-1255 has a pointer 232 
+PASS Not throw: windows-1255 has a pointer 233 
+PASS Not throw: windows-1255 has a pointer 234 
+PASS Not throw: windows-1255 has a pointer 235 
+PASS Not throw: windows-1255 has a pointer 236 
+PASS Not throw: windows-1255 has a pointer 237 
+PASS Not throw: windows-1255 has a pointer 238 
+PASS Not throw: windows-1255 has a pointer 239 
+PASS Not throw: windows-1255 has a pointer 240 
+PASS Not throw: windows-1255 has a pointer 241 
+PASS Not throw: windows-1255 has a pointer 242 
+PASS Not throw: windows-1255 has a pointer 243 
+PASS Not throw: windows-1255 has a pointer 244 
+PASS Not throw: windows-1255 has a pointer 245 
+PASS Not throw: windows-1255 has a pointer 246 
+PASS Not throw: windows-1255 has a pointer 247 
+PASS Not throw: windows-1255 has a pointer 248 
+PASS Not throw: windows-1255 has a pointer 249 
+PASS Not throw: windows-1255 has a pointer 250 
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 251 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 252 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1255 has a pointer 253 
+PASS Not throw: windows-1255 has a pointer 254 
+FAIL Throw due to fatal flag: windows-1255 doesn't have a pointer 255 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1256 has a pointer 0 
+PASS Not throw: windows-1256 has a pointer 1 
+PASS Not throw: windows-1256 has a pointer 2 
+PASS Not throw: windows-1256 has a pointer 3 
+PASS Not throw: windows-1256 has a pointer 4 
+PASS Not throw: windows-1256 has a pointer 5 
+PASS Not throw: windows-1256 has a pointer 6 
+PASS Not throw: windows-1256 has a pointer 7 
+PASS Not throw: windows-1256 has a pointer 8 
+PASS Not throw: windows-1256 has a pointer 9 
+PASS Not throw: windows-1256 has a pointer 10 
+PASS Not throw: windows-1256 has a pointer 11 
+PASS Not throw: windows-1256 has a pointer 12 
+PASS Not throw: windows-1256 has a pointer 13 
+PASS Not throw: windows-1256 has a pointer 14 
+PASS Not throw: windows-1256 has a pointer 15 
+PASS Not throw: windows-1256 has a pointer 16 
+PASS Not throw: windows-1256 has a pointer 17 
+PASS Not throw: windows-1256 has a pointer 18 
+PASS Not throw: windows-1256 has a pointer 19 
+PASS Not throw: windows-1256 has a pointer 20 
+PASS Not throw: windows-1256 has a pointer 21 
+PASS Not throw: windows-1256 has a pointer 22 
+PASS Not throw: windows-1256 has a pointer 23 
+PASS Not throw: windows-1256 has a pointer 24 
+PASS Not throw: windows-1256 has a pointer 25 
+PASS Not throw: windows-1256 has a pointer 26 
+PASS Not throw: windows-1256 has a pointer 27 
+PASS Not throw: windows-1256 has a pointer 28 
+PASS Not throw: windows-1256 has a pointer 29 
+PASS Not throw: windows-1256 has a pointer 30 
+PASS Not throw: windows-1256 has a pointer 31 
+PASS Not throw: windows-1256 has a pointer 32 
+PASS Not throw: windows-1256 has a pointer 33 
+PASS Not throw: windows-1256 has a pointer 34 
+PASS Not throw: windows-1256 has a pointer 35 
+PASS Not throw: windows-1256 has a pointer 36 
+PASS Not throw: windows-1256 has a pointer 37 
+PASS Not throw: windows-1256 has a pointer 38 
+PASS Not throw: windows-1256 has a pointer 39 
+PASS Not throw: windows-1256 has a pointer 40 
+PASS Not throw: windows-1256 has a pointer 41 
+PASS Not throw: windows-1256 has a pointer 42 
+PASS Not throw: windows-1256 has a pointer 43 
+PASS Not throw: windows-1256 has a pointer 44 
+PASS Not throw: windows-1256 has a pointer 45 
+PASS Not throw: windows-1256 has a pointer 46 
+PASS Not throw: windows-1256 has a pointer 47 
+PASS Not throw: windows-1256 has a pointer 48 
+PASS Not throw: windows-1256 has a pointer 49 
+PASS Not throw: windows-1256 has a pointer 50 
+PASS Not throw: windows-1256 has a pointer 51 
+PASS Not throw: windows-1256 has a pointer 52 
+PASS Not throw: windows-1256 has a pointer 53 
+PASS Not throw: windows-1256 has a pointer 54 
+PASS Not throw: windows-1256 has a pointer 55 
+PASS Not throw: windows-1256 has a pointer 56 
+PASS Not throw: windows-1256 has a pointer 57 
+PASS Not throw: windows-1256 has a pointer 58 
+PASS Not throw: windows-1256 has a pointer 59 
+PASS Not throw: windows-1256 has a pointer 60 
+PASS Not throw: windows-1256 has a pointer 61 
+PASS Not throw: windows-1256 has a pointer 62 
+PASS Not throw: windows-1256 has a pointer 63 
+PASS Not throw: windows-1256 has a pointer 64 
+PASS Not throw: windows-1256 has a pointer 65 
+PASS Not throw: windows-1256 has a pointer 66 
+PASS Not throw: windows-1256 has a pointer 67 
+PASS Not throw: windows-1256 has a pointer 68 
+PASS Not throw: windows-1256 has a pointer 69 
+PASS Not throw: windows-1256 has a pointer 70 
+PASS Not throw: windows-1256 has a pointer 71 
+PASS Not throw: windows-1256 has a pointer 72 
+PASS Not throw: windows-1256 has a pointer 73 
+PASS Not throw: windows-1256 has a pointer 74 
+PASS Not throw: windows-1256 has a pointer 75 
+PASS Not throw: windows-1256 has a pointer 76 
+PASS Not throw: windows-1256 has a pointer 77 
+PASS Not throw: windows-1256 has a pointer 78 
+PASS Not throw: windows-1256 has a pointer 79 
+PASS Not throw: windows-1256 has a pointer 80 
+PASS Not throw: windows-1256 has a pointer 81 
+PASS Not throw: windows-1256 has a pointer 82 
+PASS Not throw: windows-1256 has a pointer 83 
+PASS Not throw: windows-1256 has a pointer 84 
+PASS Not throw: windows-1256 has a pointer 85 
+PASS Not throw: windows-1256 has a pointer 86 
+PASS Not throw: windows-1256 has a pointer 87 
+PASS Not throw: windows-1256 has a pointer 88 
+PASS Not throw: windows-1256 has a pointer 89 
+PASS Not throw: windows-1256 has a pointer 90 
+PASS Not throw: windows-1256 has a pointer 91 
+PASS Not throw: windows-1256 has a pointer 92 
+PASS Not throw: windows-1256 has a pointer 93 
+PASS Not throw: windows-1256 has a pointer 94 
+PASS Not throw: windows-1256 has a pointer 95 
+PASS Not throw: windows-1256 has a pointer 96 
+PASS Not throw: windows-1256 has a pointer 97 
+PASS Not throw: windows-1256 has a pointer 98 
+PASS Not throw: windows-1256 has a pointer 99 
+PASS Not throw: windows-1256 has a pointer 100 
+PASS Not throw: windows-1256 has a pointer 101 
+PASS Not throw: windows-1256 has a pointer 102 
+PASS Not throw: windows-1256 has a pointer 103 
+PASS Not throw: windows-1256 has a pointer 104 
+PASS Not throw: windows-1256 has a pointer 105 
+PASS Not throw: windows-1256 has a pointer 106 
+PASS Not throw: windows-1256 has a pointer 107 
+PASS Not throw: windows-1256 has a pointer 108 
+PASS Not throw: windows-1256 has a pointer 109 
+PASS Not throw: windows-1256 has a pointer 110 
+PASS Not throw: windows-1256 has a pointer 111 
+PASS Not throw: windows-1256 has a pointer 112 
+PASS Not throw: windows-1256 has a pointer 113 
+PASS Not throw: windows-1256 has a pointer 114 
+PASS Not throw: windows-1256 has a pointer 115 
+PASS Not throw: windows-1256 has a pointer 116 
+PASS Not throw: windows-1256 has a pointer 117 
+PASS Not throw: windows-1256 has a pointer 118 
+PASS Not throw: windows-1256 has a pointer 119 
+PASS Not throw: windows-1256 has a pointer 120 
+PASS Not throw: windows-1256 has a pointer 121 
+PASS Not throw: windows-1256 has a pointer 122 
+PASS Not throw: windows-1256 has a pointer 123 
+PASS Not throw: windows-1256 has a pointer 124 
+PASS Not throw: windows-1256 has a pointer 125 
+PASS Not throw: windows-1256 has a pointer 126 
+PASS Not throw: windows-1256 has a pointer 127 
+PASS Not throw: windows-1256 has a pointer 128 
+PASS Not throw: windows-1256 has a pointer 129 
+PASS Not throw: windows-1256 has a pointer 130 
+PASS Not throw: windows-1256 has a pointer 131 
+PASS Not throw: windows-1256 has a pointer 132 
+PASS Not throw: windows-1256 has a pointer 133 
+PASS Not throw: windows-1256 has a pointer 134 
+PASS Not throw: windows-1256 has a pointer 135 
+PASS Not throw: windows-1256 has a pointer 136 
+PASS Not throw: windows-1256 has a pointer 137 
+PASS Not throw: windows-1256 has a pointer 138 
+PASS Not throw: windows-1256 has a pointer 139 
+PASS Not throw: windows-1256 has a pointer 140 
+PASS Not throw: windows-1256 has a pointer 141 
+PASS Not throw: windows-1256 has a pointer 142 
+PASS Not throw: windows-1256 has a pointer 143 
+PASS Not throw: windows-1256 has a pointer 144 
+PASS Not throw: windows-1256 has a pointer 145 
+PASS Not throw: windows-1256 has a pointer 146 
+PASS Not throw: windows-1256 has a pointer 147 
+PASS Not throw: windows-1256 has a pointer 148 
+PASS Not throw: windows-1256 has a pointer 149 
+PASS Not throw: windows-1256 has a pointer 150 
+PASS Not throw: windows-1256 has a pointer 151 
+PASS Not throw: windows-1256 has a pointer 152 
+PASS Not throw: windows-1256 has a pointer 153 
+PASS Not throw: windows-1256 has a pointer 154 
+PASS Not throw: windows-1256 has a pointer 155 
+PASS Not throw: windows-1256 has a pointer 156 
+PASS Not throw: windows-1256 has a pointer 157 
+PASS Not throw: windows-1256 has a pointer 158 
+PASS Not throw: windows-1256 has a pointer 159 
+PASS Not throw: windows-1256 has a pointer 160 
+PASS Not throw: windows-1256 has a pointer 161 
+PASS Not throw: windows-1256 has a pointer 162 
+PASS Not throw: windows-1256 has a pointer 163 
+PASS Not throw: windows-1256 has a pointer 164 
+PASS Not throw: windows-1256 has a pointer 165 
+PASS Not throw: windows-1256 has a pointer 166 
+PASS Not throw: windows-1256 has a pointer 167 
+PASS Not throw: windows-1256 has a pointer 168 
+PASS Not throw: windows-1256 has a pointer 169 
+PASS Not throw: windows-1256 has a pointer 170 
+PASS Not throw: windows-1256 has a pointer 171 
+PASS Not throw: windows-1256 has a pointer 172 
+PASS Not throw: windows-1256 has a pointer 173 
+PASS Not throw: windows-1256 has a pointer 174 
+PASS Not throw: windows-1256 has a pointer 175 
+PASS Not throw: windows-1256 has a pointer 176 
+PASS Not throw: windows-1256 has a pointer 177 
+PASS Not throw: windows-1256 has a pointer 178 
+PASS Not throw: windows-1256 has a pointer 179 
+PASS Not throw: windows-1256 has a pointer 180 
+PASS Not throw: windows-1256 has a pointer 181 
+PASS Not throw: windows-1256 has a pointer 182 
+PASS Not throw: windows-1256 has a pointer 183 
+PASS Not throw: windows-1256 has a pointer 184 
+PASS Not throw: windows-1256 has a pointer 185 
+PASS Not throw: windows-1256 has a pointer 186 
+PASS Not throw: windows-1256 has a pointer 187 
+PASS Not throw: windows-1256 has a pointer 188 
+PASS Not throw: windows-1256 has a pointer 189 
+PASS Not throw: windows-1256 has a pointer 190 
+PASS Not throw: windows-1256 has a pointer 191 
+PASS Not throw: windows-1256 has a pointer 192 
+PASS Not throw: windows-1256 has a pointer 193 
+PASS Not throw: windows-1256 has a pointer 194 
+PASS Not throw: windows-1256 has a pointer 195 
+PASS Not throw: windows-1256 has a pointer 196 
+PASS Not throw: windows-1256 has a pointer 197 
+PASS Not throw: windows-1256 has a pointer 198 
+PASS Not throw: windows-1256 has a pointer 199 
+PASS Not throw: windows-1256 has a pointer 200 
+PASS Not throw: windows-1256 has a pointer 201 
+PASS Not throw: windows-1256 has a pointer 202 
+PASS Not throw: windows-1256 has a pointer 203 
+PASS Not throw: windows-1256 has a pointer 204 
+PASS Not throw: windows-1256 has a pointer 205 
+PASS Not throw: windows-1256 has a pointer 206 
+PASS Not throw: windows-1256 has a pointer 207 
+PASS Not throw: windows-1256 has a pointer 208 
+PASS Not throw: windows-1256 has a pointer 209 
+PASS Not throw: windows-1256 has a pointer 210 
+PASS Not throw: windows-1256 has a pointer 211 
+PASS Not throw: windows-1256 has a pointer 212 
+PASS Not throw: windows-1256 has a pointer 213 
+PASS Not throw: windows-1256 has a pointer 214 
+PASS Not throw: windows-1256 has a pointer 215 
+PASS Not throw: windows-1256 has a pointer 216 
+PASS Not throw: windows-1256 has a pointer 217 
+PASS Not throw: windows-1256 has a pointer 218 
+PASS Not throw: windows-1256 has a pointer 219 
+PASS Not throw: windows-1256 has a pointer 220 
+PASS Not throw: windows-1256 has a pointer 221 
+PASS Not throw: windows-1256 has a pointer 222 
+PASS Not throw: windows-1256 has a pointer 223 
+PASS Not throw: windows-1256 has a pointer 224 
+PASS Not throw: windows-1256 has a pointer 225 
+PASS Not throw: windows-1256 has a pointer 226 
+PASS Not throw: windows-1256 has a pointer 227 
+PASS Not throw: windows-1256 has a pointer 228 
+PASS Not throw: windows-1256 has a pointer 229 
+PASS Not throw: windows-1256 has a pointer 230 
+PASS Not throw: windows-1256 has a pointer 231 
+PASS Not throw: windows-1256 has a pointer 232 
+PASS Not throw: windows-1256 has a pointer 233 
+PASS Not throw: windows-1256 has a pointer 234 
+PASS Not throw: windows-1256 has a pointer 235 
+PASS Not throw: windows-1256 has a pointer 236 
+PASS Not throw: windows-1256 has a pointer 237 
+PASS Not throw: windows-1256 has a pointer 238 
+PASS Not throw: windows-1256 has a pointer 239 
+PASS Not throw: windows-1256 has a pointer 240 
+PASS Not throw: windows-1256 has a pointer 241 
+PASS Not throw: windows-1256 has a pointer 242 
+PASS Not throw: windows-1256 has a pointer 243 
+PASS Not throw: windows-1256 has a pointer 244 
+PASS Not throw: windows-1256 has a pointer 245 
+PASS Not throw: windows-1256 has a pointer 246 
+PASS Not throw: windows-1256 has a pointer 247 
+PASS Not throw: windows-1256 has a pointer 248 
+PASS Not throw: windows-1256 has a pointer 249 
+PASS Not throw: windows-1256 has a pointer 250 
+PASS Not throw: windows-1256 has a pointer 251 
+PASS Not throw: windows-1256 has a pointer 252 
+PASS Not throw: windows-1256 has a pointer 253 
+PASS Not throw: windows-1256 has a pointer 254 
+PASS Not throw: windows-1256 has a pointer 255 
+PASS Not throw: windows-1257 has a pointer 0 
+PASS Not throw: windows-1257 has a pointer 1 
+PASS Not throw: windows-1257 has a pointer 2 
+PASS Not throw: windows-1257 has a pointer 3 
+PASS Not throw: windows-1257 has a pointer 4 
+PASS Not throw: windows-1257 has a pointer 5 
+PASS Not throw: windows-1257 has a pointer 6 
+PASS Not throw: windows-1257 has a pointer 7 
+PASS Not throw: windows-1257 has a pointer 8 
+PASS Not throw: windows-1257 has a pointer 9 
+PASS Not throw: windows-1257 has a pointer 10 
+PASS Not throw: windows-1257 has a pointer 11 
+PASS Not throw: windows-1257 has a pointer 12 
+PASS Not throw: windows-1257 has a pointer 13 
+PASS Not throw: windows-1257 has a pointer 14 
+PASS Not throw: windows-1257 has a pointer 15 
+PASS Not throw: windows-1257 has a pointer 16 
+PASS Not throw: windows-1257 has a pointer 17 
+PASS Not throw: windows-1257 has a pointer 18 
+PASS Not throw: windows-1257 has a pointer 19 
+PASS Not throw: windows-1257 has a pointer 20 
+PASS Not throw: windows-1257 has a pointer 21 
+PASS Not throw: windows-1257 has a pointer 22 
+PASS Not throw: windows-1257 has a pointer 23 
+PASS Not throw: windows-1257 has a pointer 24 
+PASS Not throw: windows-1257 has a pointer 25 
+PASS Not throw: windows-1257 has a pointer 26 
+PASS Not throw: windows-1257 has a pointer 27 
+PASS Not throw: windows-1257 has a pointer 28 
+PASS Not throw: windows-1257 has a pointer 29 
+PASS Not throw: windows-1257 has a pointer 30 
+PASS Not throw: windows-1257 has a pointer 31 
+PASS Not throw: windows-1257 has a pointer 32 
+PASS Not throw: windows-1257 has a pointer 33 
+PASS Not throw: windows-1257 has a pointer 34 
+PASS Not throw: windows-1257 has a pointer 35 
+PASS Not throw: windows-1257 has a pointer 36 
+PASS Not throw: windows-1257 has a pointer 37 
+PASS Not throw: windows-1257 has a pointer 38 
+PASS Not throw: windows-1257 has a pointer 39 
+PASS Not throw: windows-1257 has a pointer 40 
+PASS Not throw: windows-1257 has a pointer 41 
+PASS Not throw: windows-1257 has a pointer 42 
+PASS Not throw: windows-1257 has a pointer 43 
+PASS Not throw: windows-1257 has a pointer 44 
+PASS Not throw: windows-1257 has a pointer 45 
+PASS Not throw: windows-1257 has a pointer 46 
+PASS Not throw: windows-1257 has a pointer 47 
+PASS Not throw: windows-1257 has a pointer 48 
+PASS Not throw: windows-1257 has a pointer 49 
+PASS Not throw: windows-1257 has a pointer 50 
+PASS Not throw: windows-1257 has a pointer 51 
+PASS Not throw: windows-1257 has a pointer 52 
+PASS Not throw: windows-1257 has a pointer 53 
+PASS Not throw: windows-1257 has a pointer 54 
+PASS Not throw: windows-1257 has a pointer 55 
+PASS Not throw: windows-1257 has a pointer 56 
+PASS Not throw: windows-1257 has a pointer 57 
+PASS Not throw: windows-1257 has a pointer 58 
+PASS Not throw: windows-1257 has a pointer 59 
+PASS Not throw: windows-1257 has a pointer 60 
+PASS Not throw: windows-1257 has a pointer 61 
+PASS Not throw: windows-1257 has a pointer 62 
+PASS Not throw: windows-1257 has a pointer 63 
+PASS Not throw: windows-1257 has a pointer 64 
+PASS Not throw: windows-1257 has a pointer 65 
+PASS Not throw: windows-1257 has a pointer 66 
+PASS Not throw: windows-1257 has a pointer 67 
+PASS Not throw: windows-1257 has a pointer 68 
+PASS Not throw: windows-1257 has a pointer 69 
+PASS Not throw: windows-1257 has a pointer 70 
+PASS Not throw: windows-1257 has a pointer 71 
+PASS Not throw: windows-1257 has a pointer 72 
+PASS Not throw: windows-1257 has a pointer 73 
+PASS Not throw: windows-1257 has a pointer 74 
+PASS Not throw: windows-1257 has a pointer 75 
+PASS Not throw: windows-1257 has a pointer 76 
+PASS Not throw: windows-1257 has a pointer 77 
+PASS Not throw: windows-1257 has a pointer 78 
+PASS Not throw: windows-1257 has a pointer 79 
+PASS Not throw: windows-1257 has a pointer 80 
+PASS Not throw: windows-1257 has a pointer 81 
+PASS Not throw: windows-1257 has a pointer 82 
+PASS Not throw: windows-1257 has a pointer 83 
+PASS Not throw: windows-1257 has a pointer 84 
+PASS Not throw: windows-1257 has a pointer 85 
+PASS Not throw: windows-1257 has a pointer 86 
+PASS Not throw: windows-1257 has a pointer 87 
+PASS Not throw: windows-1257 has a pointer 88 
+PASS Not throw: windows-1257 has a pointer 89 
+PASS Not throw: windows-1257 has a pointer 90 
+PASS Not throw: windows-1257 has a pointer 91 
+PASS Not throw: windows-1257 has a pointer 92 
+PASS Not throw: windows-1257 has a pointer 93 
+PASS Not throw: windows-1257 has a pointer 94 
+PASS Not throw: windows-1257 has a pointer 95 
+PASS Not throw: windows-1257 has a pointer 96 
+PASS Not throw: windows-1257 has a pointer 97 
+PASS Not throw: windows-1257 has a pointer 98 
+PASS Not throw: windows-1257 has a pointer 99 
+PASS Not throw: windows-1257 has a pointer 100 
+PASS Not throw: windows-1257 has a pointer 101 
+PASS Not throw: windows-1257 has a pointer 102 
+PASS Not throw: windows-1257 has a pointer 103 
+PASS Not throw: windows-1257 has a pointer 104 
+PASS Not throw: windows-1257 has a pointer 105 
+PASS Not throw: windows-1257 has a pointer 106 
+PASS Not throw: windows-1257 has a pointer 107 
+PASS Not throw: windows-1257 has a pointer 108 
+PASS Not throw: windows-1257 has a pointer 109 
+PASS Not throw: windows-1257 has a pointer 110 
+PASS Not throw: windows-1257 has a pointer 111 
+PASS Not throw: windows-1257 has a pointer 112 
+PASS Not throw: windows-1257 has a pointer 113 
+PASS Not throw: windows-1257 has a pointer 114 
+PASS Not throw: windows-1257 has a pointer 115 
+PASS Not throw: windows-1257 has a pointer 116 
+PASS Not throw: windows-1257 has a pointer 117 
+PASS Not throw: windows-1257 has a pointer 118 
+PASS Not throw: windows-1257 has a pointer 119 
+PASS Not throw: windows-1257 has a pointer 120 
+PASS Not throw: windows-1257 has a pointer 121 
+PASS Not throw: windows-1257 has a pointer 122 
+PASS Not throw: windows-1257 has a pointer 123 
+PASS Not throw: windows-1257 has a pointer 124 
+PASS Not throw: windows-1257 has a pointer 125 
+PASS Not throw: windows-1257 has a pointer 126 
+PASS Not throw: windows-1257 has a pointer 127 
+PASS Not throw: windows-1257 has a pointer 128 
+PASS Not throw: windows-1257 has a pointer 129 
+PASS Not throw: windows-1257 has a pointer 130 
+PASS Not throw: windows-1257 has a pointer 131 
+PASS Not throw: windows-1257 has a pointer 132 
+PASS Not throw: windows-1257 has a pointer 133 
+PASS Not throw: windows-1257 has a pointer 134 
+PASS Not throw: windows-1257 has a pointer 135 
+PASS Not throw: windows-1257 has a pointer 136 
+PASS Not throw: windows-1257 has a pointer 137 
+PASS Not throw: windows-1257 has a pointer 138 
+PASS Not throw: windows-1257 has a pointer 139 
+PASS Not throw: windows-1257 has a pointer 140 
+PASS Not throw: windows-1257 has a pointer 141 
+PASS Not throw: windows-1257 has a pointer 142 
+PASS Not throw: windows-1257 has a pointer 143 
+PASS Not throw: windows-1257 has a pointer 144 
+PASS Not throw: windows-1257 has a pointer 145 
+PASS Not throw: windows-1257 has a pointer 146 
+PASS Not throw: windows-1257 has a pointer 147 
+PASS Not throw: windows-1257 has a pointer 148 
+PASS Not throw: windows-1257 has a pointer 149 
+PASS Not throw: windows-1257 has a pointer 150 
+PASS Not throw: windows-1257 has a pointer 151 
+PASS Not throw: windows-1257 has a pointer 152 
+PASS Not throw: windows-1257 has a pointer 153 
+PASS Not throw: windows-1257 has a pointer 154 
+PASS Not throw: windows-1257 has a pointer 155 
+PASS Not throw: windows-1257 has a pointer 156 
+PASS Not throw: windows-1257 has a pointer 157 
+PASS Not throw: windows-1257 has a pointer 158 
+PASS Not throw: windows-1257 has a pointer 159 
+PASS Not throw: windows-1257 has a pointer 160 
+FAIL Throw due to fatal flag: windows-1257 doesn't have a pointer 161 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1257 has a pointer 162 
+PASS Not throw: windows-1257 has a pointer 163 
+PASS Not throw: windows-1257 has a pointer 164 
+FAIL Throw due to fatal flag: windows-1257 doesn't have a pointer 165 assert_throws: function "function () {
+                    new TextDecoder(t.encod..." did not throw
+PASS Not throw: windows-1257 has a pointer 166 
+PASS Not throw: windows-1257 has a pointer 167 
+PASS Not throw: windows-1257 has a pointer 168 
+PASS Not throw: windows-1257 has a pointer 169 
+PASS Not throw: windows-1257 has a pointer 170 
+PASS Not throw: windows-1257 has a pointer 171 
+PASS Not throw: windows-1257 has a pointer 172 
+PASS Not throw: windows-1257 has a pointer 173 
+PASS Not throw: windows-1257 has a pointer 174 
+PASS Not throw: windows-1257 has a pointer 175 
+PASS Not throw: windows-1257 has a pointer 176 
+PASS Not throw: windows-1257 has a pointer 177 
+PASS Not throw: windows-1257 has a pointer 178 
+PASS Not throw: windows-1257 has a pointer 179 
+PASS Not throw: windows-1257 has a pointer 180 
+PASS Not throw: windows-1257 has a pointer 181 
+PASS Not throw: windows-1257 has a pointer 182 
+PASS Not throw: windows-1257 has a pointer 183 
+PASS Not throw: windows-1257 has a pointer 184 
+PASS Not throw: windows-1257 has a pointer 185 
+PASS Not throw: windows-1257 has a pointer 186 
+PASS Not throw: windows-1257 has a pointer 187 
+PASS Not throw: windows-1257 has a pointer 188 
+PASS Not throw: windows-1257 has a pointer 189 
+PASS Not throw: windows-1257 has a pointer 190 
+PASS Not throw: windows-1257 has a pointer 191 
+PASS Not throw: windows-1257 has a pointer 192 
+PASS Not throw: windows-1257 has a pointer 193 
+PASS Not throw: windows-1257 has a pointer 194 
+PASS Not throw: windows-1257 has a pointer 195 
+PASS Not throw: windows-1257 has a pointer 196 
+PASS Not throw: windows-1257 has a pointer 197 
+PASS Not throw: windows-1257 has a pointer 198 
+PASS Not throw: windows-1257 has a pointer 199 
+PASS Not throw: windows-1257 has a pointer 200 
+PASS Not throw: windows-1257 has a pointer 201 
+PASS Not throw: windows-1257 has a pointer 202 
+PASS Not throw: windows-1257 has a pointer 203 
+PASS Not throw: windows-1257 has a pointer 204 
+PASS Not throw: windows-1257 has a pointer 205 
+PASS Not throw: windows-1257 has a pointer 206 
+PASS Not throw: windows-1257 has a pointer 207 
+PASS Not throw: windows-1257 has a pointer 208 
+PASS Not throw: windows-1257 has a pointer 209 
+PASS Not throw: windows-1257 has a pointer 210 
+PASS Not throw: windows-1257 has a pointer 211 
+PASS Not throw: windows-1257 has a pointer 212 
+PASS Not throw: windows-1257 has a pointer 213 
+PASS Not throw: windows-1257 has a pointer 214 
+PASS Not throw: windows-1257 has a pointer 215 
+PASS Not throw: windows-1257 has a pointer 216 
+PASS Not throw: windows-1257 has a pointer 217 
+PASS Not throw: windows-1257 has a pointer 218 
+PASS Not throw: windows-1257 has a pointer 219 
+PASS Not throw: windows-1257 has a pointer 220 
+PASS Not throw: windows-1257 has a pointer 221 
+PASS Not throw: windows-1257 has a pointer 222 
+PASS Not throw: windows-1257 has a pointer 223 
+PASS Not throw: windows-1257 has a pointer 224 
+PASS Not throw: windows-1257 has a pointer 225 
+PASS Not throw: windows-1257 has a pointer 226 
+PASS Not throw: windows-1257 has a pointer 227 
+PASS Not throw: windows-1257 has a pointer 228 
+PASS Not throw: windows-1257 has a pointer 229 
+PASS Not throw: windows-1257 has a pointer 230 
+PASS Not throw: windows-1257 has a pointer 231 
+PASS Not throw: windows-1257 has a pointer 232 
+PASS Not throw: windows-1257 has a pointer 233 
+PASS Not throw: windows-1257 has a pointer 234 
+PASS Not throw: windows-1257 has a pointer 235 
+PASS Not throw: windows-1257 has a pointer 236 
+PASS Not throw: windows-1257 has a pointer 237 
+PASS Not throw: windows-1257 has a pointer 238 
+PASS Not throw: windows-1257 has a pointer 239 
+PASS Not throw: windows-1257 has a pointer 240 
+PASS Not throw: windows-1257 has a pointer 241 
+PASS Not throw: windows-1257 has a pointer 242 
+PASS Not throw: windows-1257 has a pointer 243 
+PASS Not throw: windows-1257 has a pointer 244 
+PASS Not throw: windows-1257 has a pointer 245 
+PASS Not throw: windows-1257 has a pointer 246 
+PASS Not throw: windows-1257 has a pointer 247 
+PASS Not throw: windows-1257 has a pointer 248 
+PASS Not throw: windows-1257 has a pointer 249 
+PASS Not throw: windows-1257 has a pointer 250 
+PASS Not throw: windows-1257 has a pointer 251 
+PASS Not throw: windows-1257 has a pointer 252 
+PASS Not throw: windows-1257 has a pointer 253 
+PASS Not throw: windows-1257 has a pointer 254 
+PASS Not throw: windows-1257 has a pointer 255 
+PASS Not throw: windows-1258 has a pointer 0 
+PASS Not throw: windows-1258 has a pointer 1 
+PASS Not throw: windows-1258 has a pointer 2 
+PASS Not throw: windows-1258 has a pointer 3 
+PASS Not throw: windows-1258 has a pointer 4 
+PASS Not throw: windows-1258 has a pointer 5 
+PASS Not throw: windows-1258 has a pointer 6 
+PASS Not throw: windows-1258 has a pointer 7 
+PASS Not throw: windows-1258 has a pointer 8 
+PASS Not throw: windows-1258 has a pointer 9 
+PASS Not throw: windows-1258 has a pointer 10 
+PASS Not throw: windows-1258 has a pointer 11 
+PASS Not throw: windows-1258 has a pointer 12 
+PASS Not throw: windows-1258 has a pointer 13 
+PASS Not throw: windows-1258 has a pointer 14 
+PASS Not throw: windows-1258 has a pointer 15 
+PASS Not throw: windows-1258 has a pointer 16 
+PASS Not throw: windows-1258 has a pointer 17 
+PASS Not throw: windows-1258 has a pointer 18 
+PASS Not throw: windows-1258 has a pointer 19 
+PASS Not throw: windows-1258 has a pointer 20 
+PASS Not throw: windows-1258 has a pointer 21 
+PASS Not throw: windows-1258 has a pointer 22 
+PASS Not throw: windows-1258 has a pointer 23 
+PASS Not throw: windows-1258 has a pointer 24 
+PASS Not throw: windows-1258 has a pointer 25 
+PASS Not throw: windows-1258 has a pointer 26 
+PASS Not throw: windows-1258 has a pointer 27 
+PASS Not throw: windows-1258 has a pointer 28 
+PASS Not throw: windows-1258 has a pointer 29 
+PASS Not throw: windows-1258 has a pointer 30 
+PASS Not throw: windows-1258 has a pointer 31 
+PASS Not throw: windows-1258 has a pointer 32 
+PASS Not throw: windows-1258 has a pointer 33 
+PASS Not throw: windows-1258 has a pointer 34 
+PASS Not throw: windows-1258 has a pointer 35 
+PASS Not throw: windows-1258 has a pointer 36 
+PASS Not throw: windows-1258 has a pointer 37 
+PASS Not throw: windows-1258 has a pointer 38 
+PASS Not throw: windows-1258 has a pointer 39 
+PASS Not throw: windows-1258 has a pointer 40 
+PASS Not throw: windows-1258 has a pointer 41 
+PASS Not throw: windows-1258 has a pointer 42 
+PASS Not throw: windows-1258 has a pointer 43 
+PASS Not throw: windows-1258 has a pointer 44 
+PASS Not throw: windows-1258 has a pointer 45 
+PASS Not throw: windows-1258 has a pointer 46 
+PASS Not throw: windows-1258 has a pointer 47 
+PASS Not throw: windows-1258 has a pointer 48 
+PASS Not throw: windows-1258 has a pointer 49 
+PASS Not throw: windows-1258 has a pointer 50 
+PASS Not throw: windows-1258 has a pointer 51 
+PASS Not throw: windows-1258 has a pointer 52 
+PASS Not throw: windows-1258 has a pointer 53 
+PASS Not throw: windows-1258 has a pointer 54 
+PASS Not throw: windows-1258 has a pointer 55 
+PASS Not throw: windows-1258 has a pointer 56 
+PASS Not throw: windows-1258 has a pointer 57 
+PASS Not throw: windows-1258 has a pointer 58 
+PASS Not throw: windows-1258 has a pointer 59 
+PASS Not throw: windows-1258 has a pointer 60 
+PASS Not throw: windows-1258 has a pointer 61 
+PASS Not throw: windows-1258 has a pointer 62 
+PASS Not throw: windows-1258 has a pointer 63 
+PASS Not throw: windows-1258 has a pointer 64 
+PASS Not throw: windows-1258 has a pointer 65 
+PASS Not throw: windows-1258 has a pointer 66 
+PASS Not throw: windows-1258 has a pointer 67 
+PASS Not throw: windows-1258 has a pointer 68 
+PASS Not throw: windows-1258 has a pointer 69 
+PASS Not throw: windows-1258 has a pointer 70 
+PASS Not throw: windows-1258 has a pointer 71 
+PASS Not throw: windows-1258 has a pointer 72 
+PASS Not throw: windows-1258 has a pointer 73 
+PASS Not throw: windows-1258 has a pointer 74 
+PASS Not throw: windows-1258 has a pointer 75 
+PASS Not throw: windows-1258 has a pointer 76 
+PASS Not throw: windows-1258 has a pointer 77 
+PASS Not throw: windows-1258 has a pointer 78 
+PASS Not throw: windows-1258 has a pointer 79 
+PASS Not throw: windows-1258 has a pointer 80 
+PASS Not throw: windows-1258 has a pointer 81 
+PASS Not throw: windows-1258 has a pointer 82 
+PASS Not throw: windows-1258 has a pointer 83 
+PASS Not throw: windows-1258 has a pointer 84 
+PASS Not throw: windows-1258 has a pointer 85 
+PASS Not throw: windows-1258 has a pointer 86 
+PASS Not throw: windows-1258 has a pointer 87 
+PASS Not throw: windows-1258 has a pointer 88 
+PASS Not throw: windows-1258 has a pointer 89 
+PASS Not throw: windows-1258 has a pointer 90 
+PASS Not throw: windows-1258 has a pointer 91 
+PASS Not throw: windows-1258 has a pointer 92 
+PASS Not throw: windows-1258 has a pointer 93 
+PASS Not throw: windows-1258 has a pointer 94 
+PASS Not throw: windows-1258 has a pointer 95 
+PASS Not throw: windows-1258 has a pointer 96 
+PASS Not throw: windows-1258 has a pointer 97 
+PASS Not throw: windows-1258 has a pointer 98 
+PASS Not throw: windows-1258 has a pointer 99 
+PASS Not throw: windows-1258 has a pointer 100 
+PASS Not throw: windows-1258 has a pointer 101 
+PASS Not throw: windows-1258 has a pointer 102 
+PASS Not throw: windows-1258 has a pointer 103 
+PASS Not throw: windows-1258 has a pointer 104 
+PASS Not throw: windows-1258 has a pointer 105 
+PASS Not throw: windows-1258 has a pointer 106 
+PASS Not throw: windows-1258 has a pointer 107 
+PASS Not throw: windows-1258 has a pointer 108 
+PASS Not throw: windows-1258 has a pointer 109 
+PASS Not throw: windows-1258 has a pointer 110 
+PASS Not throw: windows-1258 has a pointer 111 
+PASS Not throw: windows-1258 has a pointer 112 
+PASS Not throw: windows-1258 has a pointer 113 
+PASS Not throw: windows-1258 has a pointer 114 
+PASS Not throw: windows-1258 has a pointer 115 
+PASS Not throw: windows-1258 has a pointer 116 
+PASS Not throw: windows-1258 has a pointer 117 
+PASS Not throw: windows-1258 has a pointer 118 
+PASS Not throw: windows-1258 has a pointer 119 
+PASS Not throw: windows-1258 has a pointer 120 
+PASS Not throw: windows-1258 has a pointer 121 
+PASS Not throw: windows-1258 has a pointer 122 
+PASS Not throw: windows-1258 has a pointer 123 
+PASS Not throw: windows-1258 has a pointer 124 
+PASS Not throw: windows-1258 has a pointer 125 
+PASS Not throw: windows-1258 has a pointer 126 
+PASS Not throw: windows-1258 has a pointer 127 
+PASS Not throw: windows-1258 has a pointer 128 
+PASS Not throw: windows-1258 has a pointer 129 
+PASS Not throw: windows-1258 has a pointer 130 
+PASS Not throw: windows-1258 has a pointer 131 
+PASS Not throw: windows-1258 has a pointer 132 
+PASS Not throw: windows-1258 has a pointer 133 
+PASS Not throw: windows-1258 has a pointer 134 
+PASS Not throw: windows-1258 has a pointer 135 
+PASS Not throw: windows-1258 has a pointer 136 
+PASS Not throw: windows-1258 has a pointer 137 
+PASS Not throw: windows-1258 has a pointer 138 
+PASS Not throw: windows-1258 has a pointer 139 
+PASS Not throw: windows-1258 has a pointer 140 
+PASS Not throw: windows-1258 has a pointer 141 
+PASS Not throw: windows-1258 has a pointer 142 
+PASS Not throw: windows-1258 has a pointer 143 
+PASS Not throw: windows-1258 has a pointer 144 
+PASS Not throw: windows-1258 has a pointer 145 
+PASS Not throw: windows-1258 has a pointer 146 
+PASS Not throw: windows-1258 has a pointer 147 
+PASS Not throw: windows-1258 has a pointer 148 
+PASS Not throw: windows-1258 has a pointer 149 
+PASS Not throw: windows-1258 has a pointer 150 
+PASS Not throw: windows-1258 has a pointer 151 
+PASS Not throw: windows-1258 has a pointer 152 
+PASS Not throw: windows-1258 has a pointer 153 
+PASS Not throw: windows-1258 has a pointer 154 
+PASS Not throw: windows-1258 has a pointer 155 
+PASS Not throw: windows-1258 has a pointer 156 
+PASS Not throw: windows-1258 has a pointer 157 
+PASS Not throw: windows-1258 has a pointer 158 
+PASS Not throw: windows-1258 has a pointer 159 
+PASS Not throw: windows-1258 has a pointer 160 
+PASS Not throw: windows-1258 has a pointer 161 
+PASS Not throw: windows-1258 has a pointer 162 
+PASS Not throw: windows-1258 has a pointer 163 
+PASS Not throw: windows-1258 has a pointer 164 
+PASS Not throw: windows-1258 has a pointer 165 
+PASS Not throw: windows-1258 has a pointer 166 
+PASS Not throw: windows-1258 has a pointer 167 
+PASS Not throw: windows-1258 has a pointer 168 
+PASS Not throw: windows-1258 has a pointer 169 
+PASS Not throw: windows-1258 has a pointer 170 
+PASS Not throw: windows-1258 has a pointer 171 
+PASS Not throw: windows-1258 has a pointer 172 
+PASS Not throw: windows-1258 has a pointer 173 
+PASS Not throw: windows-1258 has a pointer 174 
+PASS Not throw: windows-1258 has a pointer 175 
+PASS Not throw: windows-1258 has a pointer 176 
+PASS Not throw: windows-1258 has a pointer 177 
+PASS Not throw: windows-1258 has a pointer 178 
+PASS Not throw: windows-1258 has a pointer 179 
+PASS Not throw: windows-1258 has a pointer 180 
+PASS Not throw: windows-1258 has a pointer 181 
+PASS Not throw: windows-1258 has a pointer 182 
+PASS Not throw: windows-1258 has a pointer 183 
+PASS Not throw: windows-1258 has a pointer 184 
+PASS Not throw: windows-1258 has a pointer 185 
+PASS Not throw: windows-1258 has a pointer 186 
+PASS Not throw: windows-1258 has a pointer 187 
+PASS Not throw: windows-1258 has a pointer 188 
+PASS Not throw: windows-1258 has a pointer 189 
+PASS Not throw: windows-1258 has a pointer 190 
+PASS Not throw: windows-1258 has a pointer 191 
+PASS Not throw: windows-1258 has a pointer 192 
+PASS Not throw: windows-1258 has a pointer 193 
+PASS Not throw: windows-1258 has a pointer 194 
+PASS Not throw: windows-1258 has a pointer 195 
+PASS Not throw: windows-1258 has a pointer 196 
+PASS Not throw: windows-1258 has a pointer 197 
+PASS Not throw: windows-1258 has a pointer 198 
+PASS Not throw: windows-1258 has a pointer 199 
+PASS Not throw: windows-1258 has a pointer 200 
+PASS Not throw: windows-1258 has a pointer 201 
+PASS Not throw: windows-1258 has a pointer 202 
+PASS Not throw: windows-1258 has a pointer 203 
+PASS Not throw: windows-1258 has a pointer 204 
+PASS Not throw: windows-1258 has a pointer 205 
+PASS Not throw: windows-1258 has a pointer 206 
+PASS Not throw: windows-1258 has a pointer 207 
+PASS Not throw: windows-1258 has a pointer 208 
+PASS Not throw: windows-1258 has a pointer 209 
+PASS Not throw: windows-1258 has a pointer 210 
+PASS Not throw: windows-1258 has a pointer 211 
+PASS Not throw: windows-1258 has a pointer 212 
+PASS Not throw: windows-1258 has a pointer 213 
+PASS Not throw: windows-1258 has a pointer 214 
+PASS Not throw: windows-1258 has a pointer 215 
+PASS Not throw: windows-1258 has a pointer 216 
+PASS Not throw: windows-1258 has a pointer 217 
+PASS Not throw: windows-1258 has a pointer 218 
+PASS Not throw: windows-1258 has a pointer 219 
+PASS Not throw: windows-1258 has a pointer 220 
+PASS Not throw: windows-1258 has a pointer 221 
+PASS Not throw: windows-1258 has a pointer 222 
+PASS Not throw: windows-1258 has a pointer 223 
+PASS Not throw: windows-1258 has a pointer 224 
+PASS Not throw: windows-1258 has a pointer 225 
+PASS Not throw: windows-1258 has a pointer 226 
+PASS Not throw: windows-1258 has a pointer 227 
+PASS Not throw: windows-1258 has a pointer 228 
+PASS Not throw: windows-1258 has a pointer 229 
+PASS Not throw: windows-1258 has a pointer 230 
+PASS Not throw: windows-1258 has a pointer 231 
+PASS Not throw: windows-1258 has a pointer 232 
+PASS Not throw: windows-1258 has a pointer 233 
+PASS Not throw: windows-1258 has a pointer 234 
+PASS Not throw: windows-1258 has a pointer 235 
+PASS Not throw: windows-1258 has a pointer 236 
+PASS Not throw: windows-1258 has a pointer 237 
+PASS Not throw: windows-1258 has a pointer 238 
+PASS Not throw: windows-1258 has a pointer 239 
+PASS Not throw: windows-1258 has a pointer 240 
+PASS Not throw: windows-1258 has a pointer 241 
+PASS Not throw: windows-1258 has a pointer 242 
+PASS Not throw: windows-1258 has a pointer 243 
+PASS Not throw: windows-1258 has a pointer 244 
+PASS Not throw: windows-1258 has a pointer 245 
+PASS Not throw: windows-1258 has a pointer 246 
+PASS Not throw: windows-1258 has a pointer 247 
+PASS Not throw: windows-1258 has a pointer 248 
+PASS Not throw: windows-1258 has a pointer 249 
+PASS Not throw: windows-1258 has a pointer 250 
+PASS Not throw: windows-1258 has a pointer 251 
+PASS Not throw: windows-1258 has a pointer 252 
+PASS Not throw: windows-1258 has a pointer 253 
+PASS Not throw: windows-1258 has a pointer 254 
+PASS Not throw: windows-1258 has a pointer 255 
+PASS Not throw: x-mac-cyrillic has a pointer 0 
+PASS Not throw: x-mac-cyrillic has a pointer 1 
+PASS Not throw: x-mac-cyrillic has a pointer 2 
+PASS Not throw: x-mac-cyrillic has a pointer 3 
+PASS Not throw: x-mac-cyrillic has a pointer 4 
+PASS Not throw: x-mac-cyrillic has a pointer 5 
+PASS Not throw: x-mac-cyrillic has a pointer 6 
+PASS Not throw: x-mac-cyrillic has a pointer 7 
+PASS Not throw: x-mac-cyrillic has a pointer 8 
+PASS Not throw: x-mac-cyrillic has a pointer 9 
+PASS Not throw: x-mac-cyrillic has a pointer 10 
+PASS Not throw: x-mac-cyrillic has a pointer 11 
+PASS Not throw: x-mac-cyrillic has a pointer 12 
+PASS Not throw: x-mac-cyrillic has a pointer 13 
+PASS Not throw: x-mac-cyrillic has a pointer 14 
+PASS Not throw: x-mac-cyrillic has a pointer 15 
+PASS Not throw: x-mac-cyrillic has a pointer 16 
+PASS Not throw: x-mac-cyrillic has a pointer 17 
+PASS Not throw: x-mac-cyrillic has a pointer 18 
+PASS Not throw: x-mac-cyrillic has a pointer 19 
+PASS Not throw: x-mac-cyrillic has a pointer 20 
+PASS Not throw: x-mac-cyrillic has a pointer 21 
+PASS Not throw: x-mac-cyrillic has a pointer 22 
+PASS Not throw: x-mac-cyrillic has a pointer 23 
+PASS Not throw: x-mac-cyrillic has a pointer 24 
+PASS Not throw: x-mac-cyrillic has a pointer 25 
+PASS Not throw: x-mac-cyrillic has a pointer 26 
+PASS Not throw: x-mac-cyrillic has a pointer 27 
+PASS Not throw: x-mac-cyrillic has a pointer 28 
+PASS Not throw: x-mac-cyrillic has a pointer 29 
+PASS Not throw: x-mac-cyrillic has a pointer 30 
+PASS Not throw: x-mac-cyrillic has a pointer 31 
+PASS Not throw: x-mac-cyrillic has a pointer 32 
+PASS Not throw: x-mac-cyrillic has a pointer 33 
+PASS Not throw: x-mac-cyrillic has a pointer 34 
+PASS Not throw: x-mac-cyrillic has a pointer 35 
+PASS Not throw: x-mac-cyrillic has a pointer 36 
+PASS Not throw: x-mac-cyrillic has a pointer 37 
+PASS Not throw: x-mac-cyrillic has a pointer 38 
+PASS Not throw: x-mac-cyrillic has a pointer 39 
+PASS Not throw: x-mac-cyrillic has a pointer 40 
+PASS Not throw: x-mac-cyrillic has a pointer 41 
+PASS Not throw: x-mac-cyrillic has a pointer 42 
+PASS Not throw: x-mac-cyrillic has a pointer 43 
+PASS Not throw: x-mac-cyrillic has a pointer 44 
+PASS Not throw: x-mac-cyrillic has a pointer 45 
+PASS Not throw: x-mac-cyrillic has a pointer 46 
+PASS Not throw: x-mac-cyrillic has a pointer 47 
+PASS Not throw: x-mac-cyrillic has a pointer 48 
+PASS Not throw: x-mac-cyrillic has a pointer 49 
+PASS Not throw: x-mac-cyrillic has a pointer 50 
+PASS Not throw: x-mac-cyrillic has a pointer 51 
+PASS Not throw: x-mac-cyrillic has a pointer 52 
+PASS Not throw: x-mac-cyrillic has a pointer 53 
+PASS Not throw: x-mac-cyrillic has a pointer 54 
+PASS Not throw: x-mac-cyrillic has a pointer 55 
+PASS Not throw: x-mac-cyrillic has a pointer 56 
+PASS Not throw: x-mac-cyrillic has a pointer 57 
+PASS Not throw: x-mac-cyrillic has a pointer 58 
+PASS Not throw: x-mac-cyrillic has a pointer 59 
+PASS Not throw: x-mac-cyrillic has a pointer 60 
+PASS Not throw: x-mac-cyrillic has a pointer 61 
+PASS Not throw: x-mac-cyrillic has a pointer 62 
+PASS Not throw: x-mac-cyrillic has a pointer 63 
+PASS Not throw: x-mac-cyrillic has a pointer 64 
+PASS Not throw: x-mac-cyrillic has a pointer 65 
+PASS Not throw: x-mac-cyrillic has a pointer 66 
+PASS Not throw: x-mac-cyrillic has a pointer 67 
+PASS Not throw: x-mac-cyrillic has a pointer 68 
+PASS Not throw: x-mac-cyrillic has a pointer 69 
+PASS Not throw: x-mac-cyrillic has a pointer 70 
+PASS Not throw: x-mac-cyrillic has a pointer 71 
+PASS Not throw: x-mac-cyrillic has a pointer 72 
+PASS Not throw: x-mac-cyrillic has a pointer 73 
+PASS Not throw: x-mac-cyrillic has a pointer 74 
+PASS Not throw: x-mac-cyrillic has a pointer 75 
+PASS Not throw: x-mac-cyrillic has a pointer 76 
+PASS Not throw: x-mac-cyrillic has a pointer 77 
+PASS Not throw: x-mac-cyrillic has a pointer 78 
+PASS Not throw: x-mac-cyrillic has a pointer 79 
+PASS Not throw: x-mac-cyrillic has a pointer 80 
+PASS Not throw: x-mac-cyrillic has a pointer 81 
+PASS Not throw: x-mac-cyrillic has a pointer 82 
+PASS Not throw: x-mac-cyrillic has a pointer 83 
+PASS Not throw: x-mac-cyrillic has a pointer 84 
+PASS Not throw: x-mac-cyrillic has a pointer 85 
+PASS Not throw: x-mac-cyrillic has a pointer 86 
+PASS Not throw: x-mac-cyrillic has a pointer 87 
+PASS Not throw: x-mac-cyrillic has a pointer 88 
+PASS Not throw: x-mac-cyrillic has a pointer 89 
+PASS Not throw: x-mac-cyrillic has a pointer 90 
+PASS Not throw: x-mac-cyrillic has a pointer 91 
+PASS Not throw: x-mac-cyrillic has a pointer 92 
+PASS Not throw: x-mac-cyrillic has a pointer 93 
+PASS Not throw: x-mac-cyrillic has a pointer 94 
+PASS Not throw: x-mac-cyrillic has a pointer 95 
+PASS Not throw: x-mac-cyrillic has a pointer 96 
+PASS Not throw: x-mac-cyrillic has a pointer 97 
+PASS Not throw: x-mac-cyrillic has a pointer 98 
+PASS Not throw: x-mac-cyrillic has a pointer 99 
+PASS Not throw: x-mac-cyrillic has a pointer 100 
+PASS Not throw: x-mac-cyrillic has a pointer 101 
+PASS Not throw: x-mac-cyrillic has a pointer 102 
+PASS Not throw: x-mac-cyrillic has a pointer 103 
+PASS Not throw: x-mac-cyrillic has a pointer 104 
+PASS Not throw: x-mac-cyrillic has a pointer 105 
+PASS Not throw: x-mac-cyrillic has a pointer 106 
+PASS Not throw: x-mac-cyrillic has a pointer 107 
+PASS Not throw: x-mac-cyrillic has a pointer 108 
+PASS Not throw: x-mac-cyrillic has a pointer 109 
+PASS Not throw: x-mac-cyrillic has a pointer 110 
+PASS Not throw: x-mac-cyrillic has a pointer 111 
+PASS Not throw: x-mac-cyrillic has a pointer 112 
+PASS Not throw: x-mac-cyrillic has a pointer 113 
+PASS Not throw: x-mac-cyrillic has a pointer 114 
+PASS Not throw: x-mac-cyrillic has a pointer 115 
+PASS Not throw: x-mac-cyrillic has a pointer 116 
+PASS Not throw: x-mac-cyrillic has a pointer 117 
+PASS Not throw: x-mac-cyrillic has a pointer 118 
+PASS Not throw: x-mac-cyrillic has a pointer 119 
+PASS Not throw: x-mac-cyrillic has a pointer 120 
+PASS Not throw: x-mac-cyrillic has a pointer 121 
+PASS Not throw: x-mac-cyrillic has a pointer 122 
+PASS Not throw: x-mac-cyrillic has a pointer 123 
+PASS Not throw: x-mac-cyrillic has a pointer 124 
+PASS Not throw: x-mac-cyrillic has a pointer 125 
+PASS Not throw: x-mac-cyrillic has a pointer 126 
+PASS Not throw: x-mac-cyrillic has a pointer 127 
+PASS Not throw: x-mac-cyrillic has a pointer 128 
+PASS Not throw: x-mac-cyrillic has a pointer 129 
+PASS Not throw: x-mac-cyrillic has a pointer 130 
+PASS Not throw: x-mac-cyrillic has a pointer 131 
+PASS Not throw: x-mac-cyrillic has a pointer 132 
+PASS Not throw: x-mac-cyrillic has a pointer 133 
+PASS Not throw: x-mac-cyrillic has a pointer 134 
+PASS Not throw: x-mac-cyrillic has a pointer 135 
+PASS Not throw: x-mac-cyrillic has a pointer 136 
+PASS Not throw: x-mac-cyrillic has a pointer 137 
+PASS Not throw: x-mac-cyrillic has a pointer 138 
+PASS Not throw: x-mac-cyrillic has a pointer 139 
+PASS Not throw: x-mac-cyrillic has a pointer 140 
+PASS Not throw: x-mac-cyrillic has a pointer 141 
+PASS Not throw: x-mac-cyrillic has a pointer 142 
+PASS Not throw: x-mac-cyrillic has a pointer 143 
+PASS Not throw: x-mac-cyrillic has a pointer 144 
+PASS Not throw: x-mac-cyrillic has a pointer 145 
+PASS Not throw: x-mac-cyrillic has a pointer 146 
+PASS Not throw: x-mac-cyrillic has a pointer 147 
+PASS Not throw: x-mac-cyrillic has a pointer 148 
+PASS Not throw: x-mac-cyrillic has a pointer 149 
+PASS Not throw: x-mac-cyrillic has a pointer 150 
+PASS Not throw: x-mac-cyrillic has a pointer 151 
+PASS Not throw: x-mac-cyrillic has a pointer 152 
+PASS Not throw: x-mac-cyrillic has a pointer 153 
+PASS Not throw: x-mac-cyrillic has a pointer 154 
+PASS Not throw: x-mac-cyrillic has a pointer 155 
+PASS Not throw: x-mac-cyrillic has a pointer 156 
+PASS Not throw: x-mac-cyrillic has a pointer 157 
+PASS Not throw: x-mac-cyrillic has a pointer 158 
+PASS Not throw: x-mac-cyrillic has a pointer 159 
+PASS Not throw: x-mac-cyrillic has a pointer 160 
+PASS Not throw: x-mac-cyrillic has a pointer 161 
+PASS Not throw: x-mac-cyrillic has a pointer 162 
+PASS Not throw: x-mac-cyrillic has a pointer 163 
+PASS Not throw: x-mac-cyrillic has a pointer 164 
+PASS Not throw: x-mac-cyrillic has a pointer 165 
+PASS Not throw: x-mac-cyrillic has a pointer 166 
+PASS Not throw: x-mac-cyrillic has a pointer 167 
+PASS Not throw: x-mac-cyrillic has a pointer 168 
+PASS Not throw: x-mac-cyrillic has a pointer 169 
+PASS Not throw: x-mac-cyrillic has a pointer 170 
+PASS Not throw: x-mac-cyrillic has a pointer 171 
+PASS Not throw: x-mac-cyrillic has a pointer 172 
+PASS Not throw: x-mac-cyrillic has a pointer 173 
+PASS Not throw: x-mac-cyrillic has a pointer 174 
+PASS Not throw: x-mac-cyrillic has a pointer 175 
+PASS Not throw: x-mac-cyrillic has a pointer 176 
+PASS Not throw: x-mac-cyrillic has a pointer 177 
+PASS Not throw: x-mac-cyrillic has a pointer 178 
+PASS Not throw: x-mac-cyrillic has a pointer 179 
+PASS Not throw: x-mac-cyrillic has a pointer 180 
+PASS Not throw: x-mac-cyrillic has a pointer 181 
+PASS Not throw: x-mac-cyrillic has a pointer 182 
+PASS Not throw: x-mac-cyrillic has a pointer 183 
+PASS Not throw: x-mac-cyrillic has a pointer 184 
+PASS Not throw: x-mac-cyrillic has a pointer 185 
+PASS Not throw: x-mac-cyrillic has a pointer 186 
+PASS Not throw: x-mac-cyrillic has a pointer 187 
+PASS Not throw: x-mac-cyrillic has a pointer 188 
+PASS Not throw: x-mac-cyrillic has a pointer 189 
+PASS Not throw: x-mac-cyrillic has a pointer 190 
+PASS Not throw: x-mac-cyrillic has a pointer 191 
+PASS Not throw: x-mac-cyrillic has a pointer 192 
+PASS Not throw: x-mac-cyrillic has a pointer 193 
+PASS Not throw: x-mac-cyrillic has a pointer 194 
+PASS Not throw: x-mac-cyrillic has a pointer 195 
+PASS Not throw: x-mac-cyrillic has a pointer 196 
+PASS Not throw: x-mac-cyrillic has a pointer 197 
+PASS Not throw: x-mac-cyrillic has a pointer 198 
+PASS Not throw: x-mac-cyrillic has a pointer 199 
+PASS Not throw: x-mac-cyrillic has a pointer 200 
+PASS Not throw: x-mac-cyrillic has a pointer 201 
+PASS Not throw: x-mac-cyrillic has a pointer 202 
+PASS Not throw: x-mac-cyrillic has a pointer 203 
+PASS Not throw: x-mac-cyrillic has a pointer 204 
+PASS Not throw: x-mac-cyrillic has a pointer 205 
+PASS Not throw: x-mac-cyrillic has a pointer 206 
+PASS Not throw: x-mac-cyrillic has a pointer 207 
+PASS Not throw: x-mac-cyrillic has a pointer 208 
+PASS Not throw: x-mac-cyrillic has a pointer 209 
+PASS Not throw: x-mac-cyrillic has a pointer 210 
+PASS Not throw: x-mac-cyrillic has a pointer 211 
+PASS Not throw: x-mac-cyrillic has a pointer 212 
+PASS Not throw: x-mac-cyrillic has a pointer 213 
+PASS Not throw: x-mac-cyrillic has a pointer 214 
+PASS Not throw: x-mac-cyrillic has a pointer 215 
+PASS Not throw: x-mac-cyrillic has a pointer 216 
+PASS Not throw: x-mac-cyrillic has a pointer 217 
+PASS Not throw: x-mac-cyrillic has a pointer 218 
+PASS Not throw: x-mac-cyrillic has a pointer 219 
+PASS Not throw: x-mac-cyrillic has a pointer 220 
+PASS Not throw: x-mac-cyrillic has a pointer 221 
+PASS Not throw: x-mac-cyrillic has a pointer 222 
+PASS Not throw: x-mac-cyrillic has a pointer 223 
+PASS Not throw: x-mac-cyrillic has a pointer 224 
+PASS Not throw: x-mac-cyrillic has a pointer 225 
+PASS Not throw: x-mac-cyrillic has a pointer 226 
+PASS Not throw: x-mac-cyrillic has a pointer 227 
+PASS Not throw: x-mac-cyrillic has a pointer 228 
+PASS Not throw: x-mac-cyrillic has a pointer 229 
+PASS Not throw: x-mac-cyrillic has a pointer 230 
+PASS Not throw: x-mac-cyrillic has a pointer 231 
+PASS Not throw: x-mac-cyrillic has a pointer 232 
+PASS Not throw: x-mac-cyrillic has a pointer 233 
+PASS Not throw: x-mac-cyrillic has a pointer 234 
+PASS Not throw: x-mac-cyrillic has a pointer 235 
+PASS Not throw: x-mac-cyrillic has a pointer 236 
+PASS Not throw: x-mac-cyrillic has a pointer 237 
+PASS Not throw: x-mac-cyrillic has a pointer 238 
+PASS Not throw: x-mac-cyrillic has a pointer 239 
+PASS Not throw: x-mac-cyrillic has a pointer 240 
+PASS Not throw: x-mac-cyrillic has a pointer 241 
+PASS Not throw: x-mac-cyrillic has a pointer 242 
+PASS Not throw: x-mac-cyrillic has a pointer 243 
+PASS Not throw: x-mac-cyrillic has a pointer 244 
+PASS Not throw: x-mac-cyrillic has a pointer 245 
+PASS Not throw: x-mac-cyrillic has a pointer 246 
+PASS Not throw: x-mac-cyrillic has a pointer 247 
+PASS Not throw: x-mac-cyrillic has a pointer 248 
+PASS Not throw: x-mac-cyrillic has a pointer 249 
+PASS Not throw: x-mac-cyrillic has a pointer 250 
+PASS Not throw: x-mac-cyrillic has a pointer 251 
+PASS Not throw: x-mac-cyrillic has a pointer 252 
+PASS Not throw: x-mac-cyrillic has a pointer 253 
+PASS Not throw: x-mac-cyrillic has a pointer 254 
+PASS Not throw: x-mac-cyrillic has a pointer 255 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/encoding/textdecoder-fatal-single-byte.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/encoding/textdecoder-fatal-single-byte.html
new file mode 100644
index 0000000..f2f283c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/encoding/textdecoder-fatal-single-byte.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>Encoding API: Fatal flag for single byte encodings</title>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script>
+
+var singleByteEncodings = [
+     {encoding: 'IBM866', bad: []},
+     {encoding: 'ISO-8859-2', bad: []},
+     {encoding: 'ISO-8859-3', bad: [0xA5, 0xAE, 0xBE, 0xC3, 0xD0, 0xE3, 0xF0]},
+     {encoding: 'ISO-8859-4', bad: []},
+     {encoding: 'ISO-8859-5', bad: []},
+     {encoding: 'ISO-8859-6', bad: [0xA1, 0xA2, 0xA3, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBC, 0xBD, 0xBE, 0xC0, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF]},
+     {encoding: 'ISO-8859-7', bad: [0xAE, 0xD2, 0xFF]},
+     {encoding: 'ISO-8859-8', bad: [0xA1, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xFB, 0xFC, 0xFF]},
+     {encoding: 'ISO-8859-8-I', bad: [0xA1, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xFB, 0xFC, 0xFF]},
+     {encoding: 'ISO-8859-10', bad: []},
+     {encoding: 'ISO-8859-13', bad: []},
+     {encoding: 'ISO-8859-14', bad: []},
+     {encoding: 'ISO-8859-15', bad: []},
+     {encoding: 'ISO-8859-16', bad: []},
+     {encoding: 'KOI8-R', bad: []},
+     {encoding: 'KOI8-U', bad: []},
+     {encoding: 'macintosh', bad: []},
+     {encoding: 'windows-874', bad: [0xDB, 0xDC, 0xDD, 0xDE, 0xFC, 0xFD, 0xFE, 0xFF]},
+     {encoding: 'windows-1250', bad: []},
+     {encoding: 'windows-1251', bad: []},
+     {encoding: 'windows-1252', bad: []},
+     {encoding: 'windows-1253', bad: [0xAA, 0xD2, 0xFF]},
+     {encoding: 'windows-1254', bad: []},
+     {encoding: 'windows-1255', bad: [0xCA, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xFB, 0xFC, 0xFF]},
+     {encoding: 'windows-1256', bad: []},
+     {encoding: 'windows-1257', bad: [0xA1, 0xA5]},
+     {encoding: 'windows-1258', bad: []},
+     {encoding: 'x-mac-cyrillic', bad: []},
+];
+
+singleByteEncodings.forEach(function(t) {
+    for (var i = 0; i < 256; ++i) {
+        if (t.bad.indexOf(i) != -1) {
+            test(function() {
+                assert_throws(new TypeError(), function() {
+                    new TextDecoder(t.encoding, {fatal: true}).decode(new Uint8Array([i]));
+                });
+            }, 'Throw due to fatal flag: ' + t.encoding + ' doesn\'t have a pointer ' + i);
+        }
+        else {
+            test(function() {
+                assert_equals(typeof new TextDecoder(t.encoding, {fatal: true}).decode(new Uint8Array([i])), "string");
+            }, 'Not throw: ' + t.encoding + ' has a pointer ' + i);
+        }
+    }
+});
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/004-1-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/004-1-expected.html
new file mode 100644
index 0000000..c50eddd4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/004-1-expected.html
@@ -0,0 +1 @@
+<!doctype html>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/004-1.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/004-1.html
new file mode 100644
index 0000000..c50eddd4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/004-1.html
@@ -0,0 +1 @@
+<!doctype html>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-1-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-1-expected.html
new file mode 100644
index 0000000..317e1369
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-1-expected.html
@@ -0,0 +1,2 @@
+<!doctype html>
+010-1
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-1.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-1.html
new file mode 100644
index 0000000..317e1369
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-1.html
@@ -0,0 +1,2 @@
+<!doctype html>
+010-1
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-2-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-2-expected.html
new file mode 100644
index 0000000..ea537fcd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-2-expected.html
@@ -0,0 +1,5 @@
+<!doctype html>
+010-2
+<script>
+onload = function() {history.back()}
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-2.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-2.html
new file mode 100644
index 0000000..ea537fcd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-2.html
@@ -0,0 +1,5 @@
+<!doctype html>
+010-2
+<script>
+onload = function() {history.back()}
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-expected.txt
new file mode 100644
index 0000000..f342c3fb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/dom/dynamic-markup-insertion/opening-the-input-stream/010-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Salvagability of document.opened document assert_unreached: Reached unreachable code
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/editing/focus/document-level-focus-apis/test-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/editing/focus/document-level-focus-apis/test-expected.html
new file mode 100644
index 0000000..90d63e51
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/editing/focus/document-level-focus-apis/test-expected.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: focus - document-level APIs</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<input id="ipt">
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/editing/focus/document-level-focus-apis/test.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/editing/focus/document-level-focus-apis/test.html
new file mode 100644
index 0000000..90d63e51
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/editing/focus/document-level-focus-apis/test.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: focus - document-level APIs</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<input id="ipt">
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/selectors/pseudo-classes/focus-iframe-expected.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/selectors/pseudo-classes/focus-iframe-expected.html
new file mode 100644
index 0000000..a269f1c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/selectors/pseudo-classes/focus-iframe-expected.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:focus)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<input id="inputiframe" type=text value="foobar" />
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/selectors/pseudo-classes/focus-iframe.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/selectors/pseudo-classes/focus-iframe.html
new file mode 100644
index 0000000..a269f1c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/semantics/selectors/pseudo-classes/focus-iframe.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:focus)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<input id="inputiframe" type=text value="foobar" />
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1-expected.txt
new file mode 100644
index 0000000..de554c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1-expected.txt
@@ -0,0 +1,6 @@
+CONSOLE ERROR: line 2: Uncaught ReferenceError: thereIsNoSuchCallable is not defined
+ 
+This is a testharness.js-based test.
+FAIL The error event from an event listener should fire on that listener's global assert_true: expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html
new file mode 100644
index 0000000..f91f3fd5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>
+  When a listener from window A is added to an event target in window B via the
+  addEventListener function from window B, errors in that listener should be
+  reported to window A.
+</title>
+<script src=../../../../../../resources/testharness.js></script>
+<script src=../../../../../../resources/testharnessreport.js></script>
+<iframe></iframe>
+<iframe></iframe>
+<script>
+test(function() {
+  var f = new frames[0].Function("thereIsNoSuchCallable()");
+  frames[1].document.addEventListener("myevent", f);
+  var frame0ErrorFired = false;
+  var frame1ErrorFired = false;
+  var ourErrorFired = false;
+  frames[0].addEventListener("error", function() {
+    frame0ErrorFired = true;
+  });
+  frames[1].addEventListener("error", function() {
+    frame1ErrorFired = true;
+  });
+  addEventListener("error", function() {
+    ourErrorFired = true;
+  });
+  frames[1].document.dispatchEvent(new Event("myevent"));
+  assert_true(frame0ErrorFired);
+  assert_false(frame1ErrorFired);
+  assert_false(ourErrorFired);
+}, "The error event from an event listener should fire on that listener's global");
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2-expected.txt
new file mode 100644
index 0000000..de554c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2-expected.txt
@@ -0,0 +1,6 @@
+CONSOLE ERROR: line 2: Uncaught ReferenceError: thereIsNoSuchCallable is not defined
+ 
+This is a testharness.js-based test.
+FAIL The error event from an event listener should fire on that listener's global assert_true: expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html
new file mode 100644
index 0000000..675e736
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>
+  When a listener from window A is added to an event target in window B via the
+  addEventListener function from window A, errors in that listener should be
+  reported to window A.
+</title>
+<script src=../../../../../../resources/testharness.js></script>
+<script src=../../../../../../resources/testharnessreport.js></script>
+<iframe></iframe>
+<iframe></iframe>
+<script>
+test(function() {
+  var f = new frames[0].Function("thereIsNoSuchCallable()");
+  frames[0].document.addEventListener.call(frames[1].document, "myevent", f);
+  var frame0ErrorFired = false;
+  var frame1ErrorFired = false;
+  var ourErrorFired = false;
+  frames[0].addEventListener("error", function() {
+    frame0ErrorFired = true;
+  });
+  frames[1].addEventListener("error", function() {
+    frame1ErrorFired = true;
+  });
+  addEventListener("error", function() {
+    ourErrorFired = true;
+  });
+  frames[1].document.dispatchEvent(new Event("myevent"));
+  assert_true(frame0ErrorFired);
+  assert_false(frame1ErrorFired);
+  assert_false(ourErrorFired);
+}, "The error event from an event listener should fire on that listener's global");
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Document-prototype-adoptNode.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Document-prototype-adoptNode.html
new file mode 100644
index 0000000..44efaffa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Document-prototype-adoptNode.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>DOM and Shadow DOM: Document.prototype.adoptNode</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="The adoptNode(node) method must throw a HierarchyRequestError exception if node is a shadow root.">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-document-adoptnode">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+function testAdoptNode(mode) {
+    test(function () {
+        var newDocument = document.implementation.createHTMLDocument();
+        assert_throws({'name': 'HierarchyRequestError'}, function () {
+            var element = document.createElement('div');
+            var shadowRoot = element.attachShadow({mode: mode});
+            newDocument.adoptNode(shadowRoot);
+        });
+    }, 'adoptNode on a shadow root in ' + mode + ' mode must throw a HierarchyRequestError');
+}
+
+testAdoptNode('open');
+testAdoptNode('closed');
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Document-prototype-importNode.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Document-prototype-importNode.html
new file mode 100644
index 0000000..d718d42
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Document-prototype-importNode.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>DOM and Shadow DOM: Document.prototype.importNode</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="The importNode(node, deep) method must throw a NotSupportedError exception if node is a shadow root.">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-document-importnode">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+function testImportNode(mode) {
+    test(function () {
+        var newDocument = document.implementation.createHTMLDocument();
+        assert_throws({'name': 'NotSupportedError'}, function () {
+            var element = document.createElement('div');
+            var shadowRoot = element.attachShadow({mode: mode});
+            newDocument.importNode(shadowRoot);
+        });
+    }, 'importNode on a shadow root in ' + mode + ' mode must throw a NotSupportedError');
+}
+
+testImportNode('open');
+testImportNode('closed');
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Node-prototype-cloneNode.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Node-prototype-cloneNode.html
new file mode 100644
index 0000000..cebfdbf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/shadow-dom/Node-prototype-cloneNode.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>DOM: cloneNode(deep)</title>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<meta name="assert" content="If context object is a shadow root, then it must throw a NotSupportedError.">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-clonenode">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+
+function testCloneNode(mode) {
+    test(function () {
+        assert_throws({'name': 'NotSupportedError'}, function () {
+            var element = document.createElement('div');
+            var shadowRoot = element.attachShadow({mode: mode});
+            shadowRoot.cloneNode(false);
+        }, 'cloneNode(false) on a shadow root in ' + mode + ' mode must throw a NotSupportedError');
+
+        assert_throws({'name': 'NotSupportedError'}, function () {
+            var element = document.createElement('div');
+            var shadowRoot = element.attachShadow({mode: mode});
+            shadowRoot.cloneNode(false);
+        }, 'cloneNode(true) on a closed shadow root must throw a NotSupportedError');
+
+    }, 'cloneNode on a shadow root in ' + mode + ' mode must throw a NotSupportedError');
+}
+
+testCloneNode('open');
+testCloneNode('closed');
+
+test(function () {
+    var element = document.createElement('div');
+    var shadowRoot = element.attachShadow({mode: 'open'});
+
+    assert_equals(element.cloneNode(false).shadowRoot, null, 'cloneNode(false) on an element with an open shadow root should not clone its shadow root');
+    assert_equals(element.cloneNode(true).shadowRoot, null, 'cloneNode(true) on an element with an open shadow root should not clone its shadow root');
+}, 'cloneNode on an element with an open shadow root should not clone its shadow root');
+
+test(function () {
+    var element = document.createElement('div');
+    var shadowRoot = element.attachShadow({mode: 'closed'});
+
+    assert_true(element.cloneNode(false).attachShadow({mode: 'closed'}) instanceof ShadowRoot,
+        'An element returned by cloneNode(false) on an element with a closed shadow root should allow attachShadow');
+
+    assert_true(element.cloneNode(true).attachShadow({mode: 'closed'}) instanceof ShadowRoot,
+        'An element returned by cloneNode(true) on an element with a closed shadow root should allow attachShadow');
+
+}, 'cloneNode on an element with a closed shadow root should not clone its shadow root');
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/easing-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/easing-expected.txt
new file mode 100644
index 0000000..ccc638c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/easing-expected.txt
@@ -0,0 +1,13 @@
+This is a testharness.js-based test.
+FAIL steps(start) function animation.effect.getComputedTiming is not a function
+FAIL steps(end) function animation.effect.getComputedTiming is not a function
+FAIL linear function animation.effect.getComputedTiming is not a function
+FAIL ease function animation.effect.getComputedTiming is not a function
+FAIL ease-in function animation.effect.getComputedTiming is not a function
+FAIL ease-in-out function animation.effect.getComputedTiming is not a function
+FAIL ease-out function animation.effect.getComputedTiming is not a function
+FAIL easing function which produces values greater than 1 animation.effect.getComputedTiming is not a function
+PASS Test invalid easing value 
+FAIL Change the easing while the animation is running anim.effect.getComputedTiming is not a function
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/easing.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/easing.html
new file mode 100644
index 0000000..51c21dd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/easing.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>easing tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-easing">
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<script src="../resources/effect-easing-tests.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+function assert_progress(animation, currentTime, easingFunction) {
+  animation.currentTime = currentTime;
+  var portion = currentTime / animation.effect.timing.duration;
+  assert_approx_equals(animation.effect.getComputedTiming().progress,
+                       easingFunction(portion),
+                       0.01,
+                       'The progress of the animation should be approximately ' +
+                       easingFunction(portion) + ' at ' + currentTime + 'ms');
+}
+
+gEffectEasingTests.forEach(function(options) {
+  test(function(t) {
+    var target = createDiv(t);
+    var anim = target.animate([ { opacity: 0 }, { opacity: 1 } ],
+                              { duration: 1000 * MS_PER_SEC,
+                                fill: 'forwards' });
+    anim.effect.timing.easing = options.easing;
+    assert_equals(anim.effect.timing.easing, options.easing);
+
+    var easing = options.easingFunction;
+    assert_progress(anim, 0, easing);
+    assert_progress(anim, 250 * MS_PER_SEC, easing);
+    assert_progress(anim, 500 * MS_PER_SEC, easing);
+    assert_progress(anim, 750 * MS_PER_SEC, easing);
+    assert_progress(anim, 1000 * MS_PER_SEC, easing);
+  }, options.desc);
+});
+
+test(function(t) {
+  var div = createDiv(t);
+  var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
+  assert_throws({ name: 'TypeError' },
+                function() {
+                  anim.effect.timing.easing = '';
+                });
+  assert_throws({ name: 'TypeError' },
+                function() {
+                  anim.effect.timing.easing = 'test';
+                });
+}, 'Test invalid easing value');
+
+test(function(t) {
+  var delay = 1000 * MS_PER_SEC;
+
+  var target = createDiv(t);
+  var anim = target.animate([ { opacity: 0 }, { opacity: 1 } ],
+                            { duration: 1000 * MS_PER_SEC,
+                              fill: 'both',
+                              delay: delay,
+                              easing: 'steps(2, start)' });
+
+  anim.effect.timing.easing = 'steps(2, end)';
+  assert_equals(anim.effect.getComputedTiming().progress, 0,
+                'easing replace to steps(2, end) at before phase');
+
+  anim.currentTime = delay + 750 * MS_PER_SEC;
+  assert_equals(anim.effect.getComputedTiming().progress, 0.5,
+                'change currentTime to active phase');
+
+  anim.effect.timing.easing = 'steps(2, start)';
+  assert_equals(anim.effect.getComputedTiming().progress, 1,
+                'easing replace to steps(2, start) at active phase');
+
+  anim.currentTime = delay + 1500 * MS_PER_SEC;
+  anim.effect.timing.easing = 'steps(2, end)';
+  assert_equals(anim.effect.getComputedTiming().progress, 1,
+                'easing replace to steps(2, end) again at after phase');
+}, 'Change the easing while the animation is running');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/fill-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/fill-expected.txt
new file mode 100644
index 0000000..26f70fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/fill-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL set fill none anim.effect.getComputedTiming is not a function
+FAIL set fill forwards anim.effect.getComputedTiming is not a function
+FAIL set fill backwards anim.effect.getComputedTiming is not a function
+FAIL set fill both anim.effect.getComputedTiming is not a function
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/fill.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/fill.html
new file mode 100644
index 0000000..d01fa03a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-effect-timing/fill.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>fill tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-fill">
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+["none", "forwards", "backwards", "both", ].forEach(function(fill){
+  test(function(t) {
+    var div = createDiv(t);
+    var anim = div.animate({ opacity: [ 0, 1 ] }, 100);
+    anim.effect.timing.fill = fill;
+    assert_equals(anim.effect.timing.fill, fill, 'set fill ' + fill);
+    assert_equals(anim.effect.getComputedTiming().fill, fill, 'getComputedTiming() after set fill ' + fill);
+  }, 'set fill ' + fill);
+});
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation-expected.txt
new file mode 100644
index 0000000..c343806
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL Test animating discrete values anim.effect.getComputedTiming is not a function
+FAIL Test discrete animation is used when interpolation fails anim.effect.getComputedTiming is not a function
+PASS Test discrete animation is used only for pairs of values that cannot be interpolated 
+PASS Test the 50% switch point for discrete animation is based on the effect easing 
+PASS Test the 50% switch point for discrete animation is based on the keyframe easing 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html
new file mode 100644
index 0000000..31b7802
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Tests for discrete animation</title>
+<link rel="help" href="http://w3c.github.io/web-animations/#animatable-as-string-section">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../../resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+  var div = createDiv(t);
+
+  var anim = div.animate({ fontStyle: [ 'normal', 'italic' ] },
+                         { duration: 1000, fill: 'forwards' });
+
+  assert_equals(getComputedStyle(div).fontStyle, 'normal',
+                'Animation produces \'from\' value at start of interval');
+  anim.currentTime = anim.effect.getComputedTiming().duration / 2 - 1;
+  assert_equals(getComputedStyle(div).fontStyle, 'normal',
+                'Animation produces \'from\' value just before the middle of'
+                + ' the interval');
+  anim.currentTime++;
+  assert_equals(getComputedStyle(div).fontStyle, 'italic',
+                'Animation produces \'to\' value at exact middle of'
+                + ' the interval');
+  anim.finish();
+  assert_equals(getComputedStyle(div).fontStyle, 'italic',
+                'Animation produces \'to\' value during forwards fill');
+}, 'Test animating discrete values');
+
+test(function(t) {
+  var div = createDiv(t);
+  var originalHeight = getComputedStyle(div).height;
+
+  var anim = div.animate({ height: [ 'auto', '200px' ] },
+                         { duration: 1000, fill: 'forwards' });
+
+  assert_equals(getComputedStyle(div).height, originalHeight,
+                'Animation produces \'from\' value at start of interval');
+  anim.currentTime = anim.effect.getComputedTiming().duration / 2 - 1;
+  assert_equals(getComputedStyle(div).height, originalHeight,
+                'Animation produces \'from\' value just before the middle of'
+                + ' the interval');
+  anim.currentTime++;
+  assert_equals(getComputedStyle(div).height, '200px',
+                'Animation produces \'to\' value at exact middle of'
+                + ' the interval');
+  anim.finish();
+  assert_equals(getComputedStyle(div).height, '200px',
+                'Animation produces \'to\' value during forwards fill');
+}, 'Test discrete animation is used when interpolation fails');
+
+test(function(t) {
+  var div = createDiv(t);
+  var originalHeight = getComputedStyle(div).height;
+
+  var anim = div.animate({ height: [ 'auto',
+                                     '200px',
+                                     '300px',
+                                     'auto',
+                                     '400px' ] },
+                         { duration: 1000, fill: 'forwards' });
+
+  // There are five values, so there are four pairs to try to interpolate.
+  // We test at the middle of each pair.
+  assert_equals(getComputedStyle(div).height, originalHeight,
+                'Animation produces \'from\' value at start of interval');
+  anim.currentTime = 125;
+  assert_equals(getComputedStyle(div).height, '200px',
+                'First non-interpolable pair uses discrete interpolation');
+  anim.currentTime += 250;
+  assert_equals(getComputedStyle(div).height, '250px',
+                'Second interpolable pair uses linear interpolation');
+  anim.currentTime += 250;
+  assert_equals(getComputedStyle(div).height, originalHeight,
+                'Third non-interpolable pair uses discrete interpolation');
+  anim.currentTime += 250;
+  assert_equals(getComputedStyle(div).height, '400px',
+                'Fourth non-interpolable pair uses discrete interpolation');
+}, 'Test discrete animation is used only for pairs of values that cannot'
+   + ' be interpolated');
+
+test(function(t) {
+  var div = createDiv(t);
+  var originalHeight = getComputedStyle(div).height;
+
+  // Easing: http://cubic-bezier.com/#.68,0,1,.01
+  // With this curve, we don't reach the 50% point until about 95% of
+  // the time has expired.
+  var anim = div.animate({ fontStyle: [ 'italic', 'oblique' ] },
+                         { duration: 1000, fill: 'forwards',
+                           easing: 'cubic-bezier(0.68,0,1,0.01)' });
+
+  assert_equals(getComputedStyle(div).fontStyle, 'italic',
+                'Animation produces \'from\' value at start of interval');
+  anim.currentTime = 940;
+  assert_equals(getComputedStyle(div).fontStyle, 'italic',
+                'Animation produces \'from\' value at 94% of the iteration'
+                + ' time');
+  anim.currentTime = 960;
+  assert_equals(getComputedStyle(div).fontStyle, 'oblique',
+                'Animation produces \'to\' value at 96% of the iteration'
+                + ' time');
+}, 'Test the 50% switch point for discrete animation is based on the'
+   + ' effect easing');
+
+test(function(t) {
+  var div = createDiv(t);
+  var originalHeight = getComputedStyle(div).height;
+
+  // Easing: http://cubic-bezier.com/#.68,0,1,.01
+  // With this curve, we don't reach the 50% point until about 95% of
+  // the time has expired.
+  var anim = div.animate([ { fontStyle: 'italic',
+                             easing: 'cubic-bezier(0.68,0,1,0.01)' },
+                           { fontStyle: 'oblique' } ],
+                         { duration: 1000, fill: 'forwards' });
+
+  assert_equals(getComputedStyle(div).fontStyle, 'italic',
+                'Animation produces \'from\' value at start of interval');
+  anim.currentTime = 940;
+  assert_equals(getComputedStyle(div).fontStyle, 'italic',
+                'Animation produces \'from\' value at 94% of the iteration'
+                + ' time');
+  anim.currentTime = 960;
+  assert_equals(getComputedStyle(div).fontStyle, 'oblique',
+                'Animation produces \'to\' value at 96% of the iteration'
+                + ' time');
+}, 'Test the 50% switch point for discrete animation is based on the'
+   + ' keyframe easing');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/not-animatable-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/not-animatable-expected.txt
new file mode 100644
index 0000000..bc24356
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/not-animatable-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL 'display' property cannot be animated using property-indexed notation anim.effect.getFrames is not a function
+FAIL 'display' property cannot be animated using a keyframe sequence anim.effect.getFrames is not a function
+FAIL CSS animations and CSS transitions properties cannot be animated using property-indexed notation anim.effect.getFrames is not a function
+FAIL CSS animations and CSS transitions properties cannot be animated using a sequence of keyframes anim.effect.getFrames is not a function
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html
new file mode 100644
index 0000000..8210937c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Tests for not animatable properties</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#not-animatable-section">
+<script src="../../../../../resources/testharness.js"></script>
+<script src="../../../../../resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+  var div = createDiv(t);
+  var anim = div.animate({ display: [ 'inline', 'inline-block' ] }, 1000);
+
+  assert_equals(anim.effect.getFrames().length, 0,
+                'Animation specified using property-indexed notation but'
+                + ' consisting of only non-animatable properties should not'
+                + ' contain any keyframes');
+}, '\'display\' property cannot be animated using property-indexed notation');
+
+test(function(t) {
+  var div = createDiv(t);
+  var anim = div.animate([ { display: 'inline' }, { display: 'inline-block' } ],
+                         1000);
+
+  assert_equals(anim.effect.getFrames().length, 2,
+                'Animation specified using a keyframe sequence where each'
+                + ' keyframe contains only non-animatable properties should'
+                + ' return an equal number of (empty) keyframes');
+  assert_false(anim.effect.getFrames()[0].hasOwnProperty('display'),
+               'Initial keyframe should not have the \'display\' property');
+  assert_false(anim.effect.getFrames()[1].hasOwnProperty('display'),
+               'Final keyframe should not have the \'display\' property');
+}, '\'display\' property cannot be animated using a keyframe sequence');
+
+test(function(t) {
+  var properties = {
+    // CSS Animations properties
+    animation:                [ 'anim 1s', 'anim 2s' ],
+    animationName:            [ 'abc', 'xyz' ],
+    animationTimingFunction:  [ 'ease', 'steps(2)' ],
+    animationDelay:           [ '1s', '2s' ],
+    animationIterationCount:  [ 1, 2 ],
+    animationDirection:       [ 'normal', 'reverse' ],
+    animationFillMode:        [ 'forwards', 'backwards' ],
+    animationPlayState:       [ 'paused', 'running' ],
+
+    // CSS Transitions properties
+    transition:               [ 'all 1s', 'all 2s' ],
+    transitionDelay:          [ '1s', '2s' ],
+    transitionDuration:       [ '1s', '2s' ],
+    transitionProperty:       [ 'all', 'opacity' ],
+    transitionTimingFunction: [ 'ease', 'ease-out' ]
+  };
+
+  var div = createDiv(t);
+  var anim = div.animate(properties, 1000);
+
+  assert_equals(anim.effect.getFrames().length, 0,
+                'Animation specified using property-indexed notation but'
+                + ' consisting of only non-animatable properties should not'
+                + ' contain any keyframes');
+}, 'CSS animations and CSS transitions properties cannot be animated using'
+   + ' property-indexed notation');
+
+test(function(t) {
+  var frames = [
+    {
+      animation:                'anim 1s',
+      animationName:            'abc',
+      animationTimingFunction:  'ease',
+      animationDelay:           '1s',
+      animationIterationCount:  1,
+      animationDirection:       'normal',
+      animationFillMode:        'forwards',
+      animationPlayState:       'paused',
+      transition:               'all 1s',
+      transitionDelay:          '1s',
+      transitionDuration:       '1s',
+      transitionProperty:       'opacity',
+      transitionTimingFunction: 'ease'
+    },
+    {
+      animation:                'anim 2s',
+      animationName:            'xyz',
+      animationTimingFunction:  'steps(2)',
+      animationDelay:           '2s',
+      animationIterationCount:  2,
+      animationDirection:       'reverse',
+      animationFillMode:        'backwards',
+      animationPlayState:       'running',
+      transition:               'all 2s',
+      transitionDelay:          '2s',
+      transitionDuration:       '2s',
+      transitionProperty:       'all',
+      transitionTimingFunction: 'ease-out'
+    }
+  ];
+  var defaultKeyframeProperties = [ 'computedOffset', 'easing', 'offset' ];
+
+  var div = createDiv(t);
+  var anim = div.animate(frames, 1000);
+
+  assert_equals(anim.effect.getFrames().length, 2,
+                'Animation specified using a keyframe sequence where each'
+                + ' keyframe contains only non-animatable properties should'
+                + ' return an equal number of (empty) keyframes');
+  assert_array_equals(Object.keys(anim.effect.getFrames()[0]),
+                      defaultKeyframeProperties,
+                      'Initial keyframe should not contain any properties other'
+                      + ' than the default keyframe properties');
+  assert_array_equals(Object.keys(anim.effect.getFrames()[1]),
+                      defaultKeyframeProperties,
+                      'Final keyframe should not contain any properties other'
+                      + ' than the default keyframe properties');
+}, 'CSS animations and CSS transitions properties cannot be animated using'
+   + ' a sequence of keyframes');
+</script>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished-expected.txt b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished-expected.txt
new file mode 100644
index 0000000..d18904c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished-expected.txt
@@ -0,0 +1,23 @@
+This is a testharness.js-based test.
+PASS Test pausing then playing does not change the finished promise 
+PASS Test restarting a finished animation 
+PASS Test restarting a reversed finished animation 
+PASS Test redundant finishing of animation 
+PASS Finished promise does not resolve when paused 
+PASS Finished promise does not resolve when pause-pending 
+PASS The finished promise is fulfilled with its Animation 
+PASS finished promise is rejected when an animation is cancelled by calling cancel() 
+PASS cancelling an already-finished animation replaces the finished promise 
+FAIL cancelling an idle animation still replaces the finished promise assert_not_equals: A redundant call to cancel() should still generate a new finished promise got disallowed value object "[object Promise]"
+FAIL Test finished promise changes for animation duration changes assert_false: shortening of the animation duration should resolve the finished promise expected false got true
+PASS Test finished promise changes when playbackRate == 0 
+PASS Test finished promise resolves when reaching to the natural boundary. 
+PASS Test finished promise changes when a prior finished promise resolved and the animation falls out finished state 
+PASS Test no new finished promise generated when finished state is checked asynchronously 
+PASS Test new finished promise generated when finished state is checked synchronously 
+PASS Test synchronous finished promise resolved even if finished state is changed soon 
+PASS Test synchronous finished promise resolved even if asynchronous finished promise happens just before synchronous promise 
+FAIL Test finished promise is not resolved when the animation falls out finished state immediately assert_unreached: Animation.finished should not be resolved Reached unreachable code
+FAIL Test finished promise is not resolved once the animation falls out finished state even though the current finished promise is generated soon after animation state became finished assert_unreached: Animation.finished should not be resolved Reached unreachable code
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished.html
new file mode 100644
index 0000000..dfd65816
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/finished.html
@@ -0,0 +1,371 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.finished</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-finished">
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+  return animation.ready.then(function() {
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise is the same object when playing starts');
+    animation.pause();
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise does not change when pausing');
+    animation.play();
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise does not change when play() unpauses');
+
+    animation.currentTime = 100 * MS_PER_SEC;
+
+    return animation.finished;
+  }).then(function() {
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise is the same object when playing completes');
+  });
+}, 'Test pausing then playing does not change the finished promise');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+  animation.finish();
+  return animation.finished.then(function() {
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise is the same object when playing completes');
+    animation.play();
+    assert_not_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise changes when replaying animation');
+
+    previousFinishedPromise = animation.finished;
+    animation.play();
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise is the same after redundant play() call');
+
+  });
+}, 'Test restarting a finished animation');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise;
+  animation.finish();
+  return animation.finished.then(function() {
+    previousFinishedPromise = animation.finished;
+    animation.playbackRate = -1;
+    assert_not_equals(animation.finished, previousFinishedPromise,
+                      'Finished promise should be replaced when reversing a ' +
+                      'finished promise');
+    animation.currentTime = 0;
+    return animation.finished;
+  }).then(function() {
+    previousFinishedPromise = animation.finished;
+    animation.play();
+    assert_not_equals(animation.finished, previousFinishedPromise,
+                      'Finished promise is replaced after play() call on ' +
+                      'finished, reversed animation');
+  });
+}, 'Test restarting a reversed finished animation');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+  animation.finish();
+  return animation.finished.then(function() {
+    animation.currentTime = 100 * MS_PER_SEC + 1000;
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Finished promise is unchanged jumping past end of ' +
+                  'finished animation');
+  });
+}, 'Test redundant finishing of animation');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  // Setup callback to run if finished promise is resolved
+  var finishPromiseResolved = false;
+  animation.finished.then(function() {
+    finishPromiseResolved = true;
+  });
+  return animation.ready.then(function() {
+    // Jump to mid-way in interval and pause
+    animation.currentTime = 100 * MS_PER_SEC / 2;
+    animation.pause();
+    return animation.ready;
+  }).then(function() {
+    // Jump to the end
+    // (But don't use finish() since that should unpause as well)
+    animation.currentTime = 100 * MS_PER_SEC;
+    return waitForAnimationFrames(2);
+  }).then(function() {
+    assert_false(finishPromiseResolved,
+                 'Finished promise should not resolve when paused');
+  });
+}, 'Finished promise does not resolve when paused');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  // Setup callback to run if finished promise is resolved
+  var finishPromiseResolved = false;
+  animation.finished.then(function() {
+    finishPromiseResolved = true;
+  });
+  return animation.ready.then(function() {
+    // Jump to mid-way in interval and pause
+    animation.currentTime = 100 * MS_PER_SEC / 2;
+    animation.pause();
+    // Jump to the end
+    animation.currentTime = 100 * MS_PER_SEC;
+    return waitForAnimationFrames(2);
+  }).then(function() {
+    assert_false(finishPromiseResolved,
+                 'Finished promise should not resolve when pause-pending');
+  });
+}, 'Finished promise does not resolve when pause-pending');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  animation.finish();
+  return animation.finished.then(function(resolvedAnimation) {
+    assert_equals(resolvedAnimation, animation,
+                  'Object identity of animation passed to Promise callback'
+                  + ' matches the animation object owning the Promise');
+  });
+}, 'The finished promise is fulfilled with its Animation');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+
+  // Set up listeners on finished promise
+  var retPromise = animation.finished.then(function() {
+    assert_unreached('finished promise was fulfilled');
+  }).catch(function(err) {
+    assert_equals(err.name, 'AbortError',
+                  'finished promise is rejected with AbortError');
+    assert_not_equals(animation.finished, previousFinishedPromise,
+                      'Finished promise should change after the original is ' +
+                      'rejected');
+  });
+
+  animation.cancel();
+
+  return retPromise;
+}, 'finished promise is rejected when an animation is cancelled by calling ' +
+   'cancel()');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+  animation.finish();
+  return animation.finished.then(function() {
+    animation.cancel();
+    assert_not_equals(animation.finished, previousFinishedPromise,
+                      'A new finished promise should be created when'
+                      + ' cancelling a finished animation');
+  });
+}, 'cancelling an already-finished animation replaces the finished promise');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  animation.cancel();
+  // The spec says we still create a new finished promise and reject the old
+  // one even if we're already idle. That behavior might change, but for now
+  // test that we do that.
+  var retPromise = animation.finished.catch(function(err) {
+    assert_equals(err.name, 'AbortError',
+                  'finished promise is rejected with AbortError');
+  });
+
+  // Redundant call to cancel();
+  var previousFinishedPromise = animation.finished;
+  animation.cancel();
+  assert_not_equals(animation.finished, previousFinishedPromise,
+                    'A redundant call to cancel() should still generate a new'
+                    + ' finished promise');
+  return retPromise;
+}, 'cancelling an idle animation still replaces the finished promise');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  const HALF_DUR = 100 * MS_PER_SEC / 2;
+  const QUARTER_DUR = 100 * MS_PER_SEC / 4;
+  var gotNextFrame = false;
+  var currentTimeBeforeShortening;
+  animation.currentTime = HALF_DUR;
+  return animation.ready.then(function() {
+    currentTimeBeforeShortening = animation.currentTime;
+    animation.effect.timing.duration = QUARTER_DUR;
+    // Below we use gotNextFrame to check that shortening of the animation
+    // duration causes the finished promise to resolve, rather than it just
+    // getting resolved on the next animation frame. This relies on the fact
+    // that the promises are resolved as a micro-task before the next frame
+    // happens.
+    waitForAnimationFrames(1).then(function() {
+      gotNextFrame = true;
+    });
+
+    return animation.finished;
+  }).then(function() {
+    assert_false(gotNextFrame, 'shortening of the animation duration should ' +
+                               'resolve the finished promise');
+    assert_equals(animation.currentTime, currentTimeBeforeShortening,
+                  'currentTime should be unchanged when duration shortened');
+    var previousFinishedPromise = animation.finished;
+    animation.effect.timing.duration = 100 * MS_PER_SEC;
+    assert_not_equals(animation.finished, previousFinishedPromise,
+                      'Finished promise should change after lengthening the ' +
+                      'duration causes the animation to become active');
+  });
+}, 'Test finished promise changes for animation duration changes');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var retPromise = animation.ready.then(function() {
+    animation.playbackRate = 0;
+    animation.currentTime = 100 * MS_PER_SEC + 1000;
+    return waitForAnimationFrames(2);
+  });
+
+  animation.finished.then(t.step_func(function() {
+    assert_unreached('finished promise should not resolve when playbackRate ' +
+                     'is zero');
+  }));
+
+  return retPromise;
+}, 'Test finished promise changes when playbackRate == 0');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  return animation.ready.then(function() {
+    animation.playbackRate = -1;
+    return animation.finished;
+  });
+}, 'Test finished promise resolves when reaching to the natural boundary.');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+  animation.finish();
+  return animation.finished.then(function() {
+    animation.currentTime = 0;
+    assert_not_equals(animation.finished, previousFinishedPromise,
+                      'Finished promise should change once a prior ' +
+                      'finished promise resolved and the animation ' +
+                      'falls out finished state');
+  });
+}, 'Test finished promise changes when a prior finished promise resolved ' +
+   'and the animation falls out finished state');
+
+test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+  animation.currentTime = 100 * MS_PER_SEC;
+  animation.currentTime = 100 * MS_PER_SEC / 2;
+  assert_equals(animation.finished, previousFinishedPromise,
+                'No new finished promise generated when finished state ' +
+                'is checked asynchronously');
+}, 'Test no new finished promise generated when finished state ' +
+   'is checked asynchronously');
+
+test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var previousFinishedPromise = animation.finished;
+  animation.finish();
+  animation.currentTime = 100 * MS_PER_SEC / 2;
+  assert_not_equals(animation.finished, previousFinishedPromise,
+                    'New finished promise generated when finished state ' +
+                    'is checked synchronously');
+}, 'Test new finished promise generated when finished state ' +
+   'is checked synchronously');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var resolvedFinished = false;
+  animation.finished.then(function() {
+    resolvedFinished = true;
+  });
+  return animation.ready.then(function() {
+    animation.finish();
+    animation.currentTime = 100 * MS_PER_SEC / 2;
+  }).then(function() {
+    assert_true(resolvedFinished,
+      'Animation.finished should be resolved even if ' +
+      'the finished state is changed soon');
+  });
+
+}, 'Test synchronous finished promise resolved even if finished state ' +
+   'is changed soon');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var resolvedFinished = false;
+  animation.finished.then(function() {
+    resolvedFinished = true;
+  });
+
+  return animation.ready.then(function() {
+    animation.currentTime = 100 * MS_PER_SEC;
+    animation.finish();
+  }).then(function() {
+    assert_true(resolvedFinished,
+      'Animation.finished should be resolved soon after finish() is ' +
+      'called even if there are other asynchronous promises just before it');
+  });
+}, 'Test synchronous finished promise resolved even if asynchronous ' +
+   'finished promise happens just before synchronous promise');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  animation.finished.then(t.step_func(function() {
+    assert_unreached('Animation.finished should not be resolved');
+  }));
+
+  return animation.ready.then(function() {
+    animation.currentTime = 100 * MS_PER_SEC;
+    animation.currentTime = 100 * MS_PER_SEC / 2;
+  });
+}, 'Test finished promise is not resolved when the animation ' +
+   'falls out finished state immediately');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  return animation.ready.then(function() {
+    animation.currentTime = 100 * MS_PER_SEC;
+    animation.finished.then(t.step_func(function() {
+      assert_unreached('Animation.finished should not be resolved');
+    }));
+    animation.currentTime = 0;
+  });
+
+}, 'Test finished promise is not resolved once the animation ' +
+   'falls out finished state even though the current finished ' +
+   'promise is generated soon after animation state became finished');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/oncancel.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/oncancel.html
new file mode 100644
index 0000000..ac8ca38
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/oncancel.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.oncancel</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-oncancel">
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+async_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var finishedTimelineTime;
+  animation.finished.then().catch(function() {
+    finishedTimelineTime = animation.timeline.currentTime;
+  });
+
+  animation.oncancel = t.step_func_done(function(event) {
+    assert_equals(event.currentTime, null,
+      'event.currentTime should be null');
+    assert_equals(event.timelineTime, finishedTimelineTime,
+      'event.timelineTime should equal to the animation timeline ' +
+      'when finished promise is rejected');
+  });
+
+  animation.cancel();
+}, 'oncancel event is fired when animation.cancel() is called.');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/onfinish.html b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/onfinish.html
new file mode 100644
index 0000000..320a995
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/web-animations/animation/onfinish.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.onfinish</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-onfinish">
+<script src="../../../../resources/testharness.js"></script>
+<script src="../../../../resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="../../../../resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+async_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  var finishedTimelineTime;
+  animation.finished.then(function() {
+    finishedTimelineTime = animation.timeline.currentTime;
+  });
+
+  animation.onfinish = t.step_func_done(function(event) {
+    assert_equals(event.currentTime, 0,
+      'event.currentTime should be zero');
+    assert_equals(event.timelineTime, finishedTimelineTime,
+      'event.timelineTime should equal to the animation timeline ' +
+      'when finished promise is resolved');
+  });
+
+  animation.playbackRate = -1;
+}, 'onfinish event is fired when the currentTime < 0 and ' +
+   'the playbackRate < 0');
+
+async_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+
+  var finishedTimelineTime;
+  animation.finished.then(function() {
+    finishedTimelineTime = animation.timeline.currentTime;
+  });
+
+  animation.onfinish = t.step_func_done(function(event) {
+    assert_equals(event.currentTime, 100 * MS_PER_SEC,
+      'event.currentTime should be the effect end');
+    assert_equals(event.timelineTime, finishedTimelineTime,
+      'event.timelineTime should equal to the animation timeline ' +
+      'when finished promise is resolved');
+  });
+
+  animation.currentTime = 100 * MS_PER_SEC;
+}, 'onfinish event is fired when the currentTime > 0 and ' +
+   'the playbackRate > 0');
+
+async_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+
+  var finishedTimelineTime;
+  animation.finished.then(function() {
+    finishedTimelineTime = animation.timeline.currentTime;
+  });
+
+  animation.onfinish = t.step_func_done(function(event) {
+    assert_equals(event.currentTime, 100 * MS_PER_SEC,
+      'event.currentTime should be the effect end');
+    assert_equals(event.timelineTime, finishedTimelineTime,
+      'event.timelineTime should equal to the animation timeline ' +
+      'when finished promise is resolved');
+  });
+
+  animation.finish();
+}, 'onfinish event is fired when animation.finish() is called');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+
+  animation.onfinish = function(event) {
+    assert_unreached('onfinish event should not be fired');
+  };
+
+  animation.currentTime = 100 * MS_PER_SEC / 2;
+  animation.pause();
+
+  return animation.ready.then(function() {
+    animation.currentTime = 100 * MS_PER_SEC;
+    return waitForAnimationFrames(2);
+  });
+}, 'onfinish event is not fired when paused');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  animation.onfinish = function(event) {
+    assert_unreached('onfinish event should not be fired');
+  };
+
+  return animation.ready.then(function() {
+    animation.playbackRate = 0;
+    animation.currentTime = 100 * MS_PER_SEC;
+    return waitForAnimationFrames(2);
+  });
+}, 'onfinish event is not fired when the playbackRate is zero');
+
+promise_test(function(t) {
+  var div = createDiv(t);
+  var animation = div.animate({}, 100 * MS_PER_SEC);
+  animation.onfinish = function(event) {
+    assert_unreached('onfinish event should not be fired');
+  };
+
+  return animation.ready.then(function() {
+    animation.currentTime = 100 * MS_PER_SEC;
+    animation.currentTime = 100 * MS_PER_SEC / 2;
+    return waitForAnimationFrames(2);
+  });
+}, 'onfinish event is not fired when the animation falls out ' +
+   'finished state immediately');
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents-expected.txt
index baa38fa3..864c21cd 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents-expected.txt
@@ -3,7 +3,7 @@
 CONFIRM: confirm
 PROMPT: prompt, default text: 
 Opening dialog: type=beforeunload; message=beforeunload in javascriptDialogEvents
-Closed dialog: result=true
+Closed dialog: result=false
 Opening dialog: type=alert; message=alert
 Closed dialog: result=true
 Opening dialog: type=confirm; message=confirm
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents.html b/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents.html
index 8d8303ae..87c7f08 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents.html
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/page/javascriptDialogEvents.html
@@ -3,6 +3,8 @@
 <script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script>
 <script>
 
+testRunner.setShouldStayOnPageAfterHandlingBeforeUnload(true);
+
 window.onbeforeunload = onBeforeUnload;
 
 function onBeforeUnload()
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-source-lines-inline.html b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-source-lines-inline.html
index c3e81f88..fc43a07 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-source-lines-inline.html
+++ b/third_party/WebKit/LayoutTests/inspector/elements/styles-4/styles-source-lines-inline.html
@@ -31,7 +31,7 @@
 </p>
 
 <div id="foo" class="foo" style="display:none">Foo</div>
-<iframe src="resources/styles-source-lines-inline-iframe.html">
+<iframe src="../styles/resources/styles-source-lines-inline-iframe.html">
 
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js b/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js
index e919e660..952efae 100644
--- a/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js
+++ b/third_party/WebKit/LayoutTests/inspector/sass/sass-test.js
@@ -26,13 +26,7 @@
 
 InspectorTest.parseSCSS = function(url, text)
 {
-    return self.runtime.instancePromise(WebInspector.TokenizerFactory)
-        .then(onTokenizer);
-
-    function onTokenizer(tokenizer)
-    {
-        return WebInspector.SASSSupport.parseSCSS(tokenizer, url, text);
-    }
+    return WebInspector.SASSSupport.parseSCSS(url, text);
 }
 
 InspectorTest.loadASTMapping = function(header, callback)
diff --git a/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-3-expected.txt b/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-3-expected.txt
index db0db39..9f64431 100644
--- a/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-3-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-3-expected.txt
@@ -64,8 +64,8 @@
         disabled: false
 rule 2: "mixins"
     property 0
-        name: "@include border-radius"
-            range: {"startLine":13,"startColumn":4,"endLine":13,"endColumn":26}
+        name: "border-radius"
+            range: {"startLine":13,"startColumn":13,"endLine":13,"endColumn":26}
         value: "15px"
             range: {"startLine":13,"startColumn":27,"endLine":13,"endColumn":31}
         range: {"startLine":13,"startColumn":4,"endLine":13,"endColumn":32}
diff --git a/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-5-expected.txt b/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-5-expected.txt
index 6d025ca..95de7346 100644
--- a/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-5-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sass/test-ast-scss-5-expected.txt
@@ -23,10 +23,9 @@
     property 1
         name: "margin"
             range: {"startLine":2,"startColumn":4,"endLine":2,"endColumn":10}
-        value: " 0 auto
-"
-            range: {"startLine":2,"startColumn":11,"endLine":3,"endColumn":0}
-        range: {"startLine":2,"startColumn":4,"endLine":3,"endColumn":1}
+        value: " 0 auto"
+            range: {"startLine":2,"startColumn":11,"endLine":2,"endColumn":18}
+        range: {"startLine":2,"startColumn":4,"endLine":3,"endColumn":0}
         disabled: false
     property 2
         name: "color"
@@ -38,8 +37,8 @@
     property 3
         name: "margin"
             range: {"startLine":7,"startColumn":7,"endLine":7,"endColumn":13}
-        value: " 0 auto "
-            range: {"startLine":7,"startColumn":14,"endLine":7,"endColumn":22}
+        value: " 0 auto"
+            range: {"startLine":7,"startColumn":14,"endLine":7,"endColumn":21}
         range: {"startLine":7,"startColumn":4,"endLine":7,"endColumn":24}
         disabled: true
 rule 2: "mixins"
diff --git a/third_party/WebKit/LayoutTests/media/track/track-default-attribute-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-default-attribute-expected.txt
deleted file mode 100644
index eed3e46b..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-default-attribute-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Tests that a track with the 'default' attribute loads automatically.
-
-EVENT(load)
-EXPECTED (event.target.readyState == '2') OK
-EXPECTED (event.target.id == 'default') OK
-EXPECTED (event.target.default == 'true') OK
-
-END OF TEST
-
diff --git a/third_party/WebKit/LayoutTests/media/track/track-default-attribute.html b/third_party/WebKit/LayoutTests/media/track/track-default-attribute.html
index 53600d8f..1ff2ecd 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-default-attribute.html
+++ b/third_party/WebKit/LayoutTests/media/track/track-default-attribute.html
@@ -1,36 +1,26 @@
 <!DOCTYPE html>
-<html>
-    <head>
-        <script src=../media-file.js></script>
-        <!-- TODO(philipj): Convert test to testharness.js. crbug.com/588956
-             (Please avoid writing new tests using video-test.js) -->
-        <script src=../video-test.js></script>
-        <script>
-
-            var timer = null;
-
-            function trackLoaded()
-            {
-                consoleWrite("EVENT(load)");
-                testExpected("event.target.readyState", HTMLTrackElement.LOADED);
-                testExpected("event.target.id", "default");
-                testExpected("event.target.default", true);
-                consoleWrite("");
-
-                // End the test after a brief pause so we allow other tracks to load if they will.
-                if (timer)
-                    clearTimeout(timer);
-                timer = setTimeout(function() { endTest() }, 200);
-            }
-
-        </script>
-    </head>
-    <body>
-        <p>Tests that a track with the 'default' attribute loads automatically.</p>
-        <video>
-            <track kind="captions" src="captions-webvtt/tc005-default-styles.vtt" onload="trackLoaded()">
-            <track kind="captions" src="captions-webvtt/tc005-metadata-area.vtt" onload="trackLoaded()">
-            <track default kind="captions" src="captions-webvtt/tc004-webvtt-file.vtt" onload="trackLoaded()" id="default" >
-        </video>
-    </body>
-</html>
+<title>Tests that a track with the "default" attribute loads automatically.</title>
+<video>
+    <track kind="captions" src="captions-webvtt/tc005-default-styles.vtt">
+    <track kind="captions" src="captions-webvtt/tc005-metadata-area.vtt">
+    <track default kind="captions" src="captions-webvtt/tc004-webvtt-file.vtt" id="default">
+</video>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+async_test(function(t) {
+    var timer = null;
+    var tracks = document.querySelectorAll("track");
+    for (var track of tracks) {
+        track.onload = t.step_func(function() {
+            assert_equals(event.target.readyState, HTMLTrackElement.LOADED);
+            assert_equals(event.target.id, "default");
+            assert_true(event.target.default);
+            // End the test after a brief pause so we allow other tracks to load if they will.
+            if (timer)
+                clearTimeout(timer);
+            timer = setTimeout(function() { t.done(); }, 200);
+        });
+    }
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-disabled-addcue-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-disabled-addcue-expected.txt
deleted file mode 100644
index 33efe870..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-disabled-addcue-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Test adding cues to a disabled text track.
-
-Waiting for 2 cue durations to elapse.
-2 cue durations have elapsed.
-END OF TEST
-
diff --git a/third_party/WebKit/LayoutTests/media/track/track-disabled-addcue.html b/third_party/WebKit/LayoutTests/media/track/track-disabled-addcue.html
index d313319..147eced 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-disabled-addcue.html
+++ b/third_party/WebKit/LayoutTests/media/track/track-disabled-addcue.html
@@ -1,46 +1,34 @@
 <!DOCTYPE html>
-<html>
-    <head>
-        <script src="../media-file.js"></script>
-        <!-- TODO(philipj): Convert test to testharness.js. crbug.com/588956
-             (Please avoid writing new tests using video-test.js) -->
-        <script src="../video-test.js"></script>
-        <script>
-            function onLoad()
-            {
-                if (window.testRunner)
-                    testRunner.dumpAsText();
+<title>Test adding cues to a disabled text track. </title>
+<script src="../media-file.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+async_test(function(t) {
+    var cueDuration = 0.1;
+    var video = document.createElement("video");
+    var track = video.addTextTrack("subtitles");
+    track.mode = "disabled";
 
-                var cueDuration = 0.1;
-                var video = document.querySelector("#vid");
-                var track = video.addTextTrack("subtitles");
-                track.mode = "disabled";
+    for (var i = 0; i < 10; ++i) {
+        var start = i * cueDuration;
+        var end = start + cueDuration;
+        track.addCue(new VTTCue(start, end, "Test Cue " + i));
+    }
 
-                for (var i = 0; i < 10; ++i) {
-                    var start = i * cueDuration;
-                    var end = start + cueDuration;
-                    track.addCue(new VTTCue(start, end, "Test Cue " + i));
-                }
+    // Waiting for 2 cue durations to elapse.
+    video.ontimeupdate = t.step_func(function(e) {
+        if (e.target.currentTime < (2 * cueDuration))
+            return;
 
-                consoleWrite("Waiting for 2 cue durations to elapse.");
+        // End test after at least 2 cueDurations to make sure the test
+        // doesn't crash during the period the first 2 cues would have been
+        // rendered if the track was not disabled.
+        // 2 cue durations have elapsed.
+        t.done();
+    });
 
-                video.addEventListener('timeupdate', function (e)
-                {
-                     if (e.target.currentTime < 2 * cueDuration)
-                          return;
-
-                      // End test after at least 2 cueDurations to make sure the test
-                      // doesn't crash during the period the first 2 cues would have been
-                      // rendered if the track was not disabled.
-                      consoleWrite("2 cue durations have elapsed.");
-                      endTest();
-                });
-                video.play();
-            }
-        </script>
-    </head>
-    <body onload="onLoad()">
-        <p>Test adding cues to a disabled text track. </p>
-        <video id="vid" src="../content/test.ogv" controls></video>
-    </body>
-</html>
+    video.src = findMediaFile("video", "../content/test");
+    video.play();
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-disabled-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-disabled-expected.txt
deleted file mode 100644
index b7c6fb9..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-disabled-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-EVENT(loadstart)
-Waiting for the duration of the first cue to elapse.
-The duration of the first cue has elapsed.
-END OF TEST
-
diff --git a/third_party/WebKit/LayoutTests/media/track/track-disabled.html b/third_party/WebKit/LayoutTests/media/track/track-disabled.html
index 88c749b..5b44aa8 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-disabled.html
+++ b/third_party/WebKit/LayoutTests/media/track/track-disabled.html
@@ -1,38 +1,29 @@
 <!DOCTYPE html>
-<html>
-    <head>
-        <script src="../media-file.js"></script>
-        <!-- TODO(philipj): Convert test to testharness.js. crbug.com/588956
-             (Please avoid writing new tests using video-test.js) -->
-        <script src="../video-test.js"></script>
-        <script>
-            if (window.testRunner)
-                testRunner.dumpAsText();
+<title>Test disabling a track.</title>
+<video>
+    <track kind="subtitles" src="captions-webvtt/captions.vtt"/>
+</video>
+<script src="../media-file.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+async_test(function(t) {
+    var video = document.querySelector("video");
+    video.textTracks[0].mode = "disabled";
 
-            waitForEvent('loadstart', function ()
-            {
-                var video = document.getElementById('vid');
-                video.textTracks[0].mode = "disabled";
+    // Waiting for the duration of the first cue to elapse.
+    video.ontimeupdate = t.step_func(function (e) {
+         if (e.target.currentTime < 1)
+              return;
 
-                consoleWrite("Waiting for the duration of the first cue to elapse.");
-                video.addEventListener('timeupdate', function (e)
-                {
-                     if (e.target.currentTime < 1)
-                          return;
+          // End test after the duration of the first cue to make sure
+          // the test doesn't crash during the period this cue would
+          // have been rendered if the track was not disabled.
+          // The duration of the first cue has elapsed.
+          t.done();
+    });
 
-                      // End test after the duration of the first cue to make sure the test
-                      // doesn't crash during the period this cue would have been
-                      // rendered if the track was not disabled.
-                      consoleWrite("The duration of the first cue has elapsed.");
-                      endTest();
-                });
-            });
-
-        </script>
-    </head>
-    <body>
-        <video id="vid" src="../content/test.ogv" autoplay controls>
-            <track kind='subtitles' srclang='en' label='English' src='captions-webvtt/captions.vtt' />
-        </video>
-    </body>
-</html>
+    video.src = findMediaFile("video", "../content/test");
+    video.play();
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-element-dom-change-crash-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-element-dom-change-crash-expected.txt
deleted file mode 100644
index 45156c702..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-element-dom-change-crash-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Tests that the browser handles properly simple DOM mutations.
-
-** Create video and text track element **
-** Append the track element to the video element **
-** Set the mode of the text track to "showing" **
-
-No crash. PASS.
-
-END OF TEST
-
diff --git a/third_party/WebKit/LayoutTests/media/track/track-element-dom-change-crash.html b/third_party/WebKit/LayoutTests/media/track/track-element-dom-change-crash.html
index 8c6549d5..277525ec 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-element-dom-change-crash.html
+++ b/third_party/WebKit/LayoutTests/media/track/track-element-dom-change-crash.html
@@ -1,34 +1,16 @@
 <!DOCTYPE html>
-<html>
-    <head>
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Tests that the browser handles simple DOM mutations properly.</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(function() {
+    var video = document.createElement("video");
+    var testTrack = document.createElement("track");
 
-        <script src=../media-file.js></script>
-        <!-- TODO(philipj): Convert test to testharness.js. crbug.com/588956
-             (Please avoid writing new tests using video-test.js) -->
-        <script src=../video-test.js></script>
-        <script>
-            function startTest()
-            {
-                consoleWrite("** Create video and text track element **");
-                var video = document.createElement("video");
-                var track = document.createElement("track");
+    // Append the track element to the video element.
+    video.appendChild(testTrack);
 
-                consoleWrite("** Append the track element to the video element **");
-                video.appendChild(track);
-
-                consoleWrite("** Set the mode of the text track to \"showing\" **");
-                track.track.mode = "showing";
-
-                consoleWrite("");
-                consoleWrite("No crash. PASS.");
-                consoleWrite("");
-
-                endTest();
-            }
-        </script>
-    </head>
-    <body onload="startTest()">
-      <p>Tests that the browser handles properly simple DOM mutations.</p>
-    </body>
-</html>
+    // Set the mode of the text track to "showing".
+    testTrack.track.mode = "showing";
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-id-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-id-expected.txt
deleted file mode 100644
index eea221c8..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-id-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Tests that the TextTrack "id" attribute is appropriately set.
-
-
-++ Test default attribute value
-EXPECTED (textTrack.id == 'LoremIpsum') OK
-EXPECTED (video.textTracks[0].id == 'LoremIpsum') OK
-
-++ Make sure we can look tracks up by id
-EXPECTED (video.textTracks.getTrackById('LoremIpsum') == '[object TextTrack]') OK
-
-++ Test that it's readonly
-RUN(textTrack.id = 'newvalue';)
-EXPECTED (textTrack.id == 'LoremIpsum') OK
-END OF TEST
-
diff --git a/third_party/WebKit/LayoutTests/media/track/track-id.html b/third_party/WebKit/LayoutTests/media/track/track-id.html
index f2b25d4..6edeebc 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-id.html
+++ b/third_party/WebKit/LayoutTests/media/track/track-id.html
@@ -1,44 +1,27 @@
 <!DOCTYPE html>
-<html>
-    <head>
+<title>Tests that the TextTrack "id" attribute is set appropriately.</title>
+<video>
+    <track id="LoremIpsum" src="captions-webvtt/captions-fast.vtt" default>
+</video>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(function() {
+    var video = document.querySelector("video");
 
-        <script src=../media-file.js></script>
-        <!-- TODO(philipj): Convert test to testharness.js. crbug.com/588956
-             (Please avoid writing new tests using video-test.js) -->
-        <script src=../video-test.js></script>
-        <script>
+    var track = document.querySelector("track");
+    
+    var textTrack = track.track;
 
-            var textTrack;
+    // Test default attribute value.
+    assert_equals(textTrack.id, "LoremIpsum");
+    assert_equals(video.textTracks[0].id, "LoremIpsum");
 
-            function start()
-            {
-                findMediaElement();
-                consoleWrite("");
+    // Make sure we can look up tracks by id.
+    assert_equals(video.textTracks.getTrackById("LoremIpsum"), textTrack);
 
-                textTrack = document.getElementById("LoremIpsum").track;
-
-                consoleWrite("<b>++ Test default attribute value</b>");
-                testExpected("textTrack.id", "LoremIpsum");
-                testExpected("video.textTracks[0].id", "LoremIpsum");
-                consoleWrite("");
-
-                consoleWrite("<b>++ Make sure we can look tracks up by id</b>");
-                testExpected("video.textTracks.getTrackById('LoremIpsum')", textTrack);
-                consoleWrite("");
-
-                consoleWrite("<b>++ Test that it's readonly</b>");
-                run("textTrack.id = 'newvalue';");
-                testExpected("textTrack.id", "LoremIpsum");
-
-                endTest();
-            }
-
-        </script>
-    </head>
-    <body >
-        <p>Tests that the TextTrack "id" attribute is appropriately set.</p>
-        <video>
-            <track id="LoremIpsum" src="captions-webvtt/captions-fast.vtt" onload="start()" default>
-        </video>
-    </body>
-</html>
+    // Test that it's readonly.
+    textTrack.id = "newvalue";
+    assert_equals(textTrack.id, "LoremIpsum");
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-insert-after-load-crash-expected.txt b/third_party/WebKit/LayoutTests/media/track/track-insert-after-load-crash-expected.txt
deleted file mode 100644
index 3f91c2f..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-insert-after-load-crash-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Tests that inserting a <track> element immediately after a load() doesn't crash.
-
-END OF TEST
-
diff --git a/third_party/WebKit/LayoutTests/media/track/track-insert-after-load-crash.html b/third_party/WebKit/LayoutTests/media/track/track-insert-after-load-crash.html
index 7d0e92e..7e2e95ff 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-insert-after-load-crash.html
+++ b/third_party/WebKit/LayoutTests/media/track/track-insert-after-load-crash.html
@@ -1,20 +1,14 @@
 <!DOCTYPE  html>
-<html>
-    <head>
-        <script src="../media-file.js"></script>
-        <!-- TODO(philipj): Convert test to testharness.js. crbug.com/588956
-             (Please avoid writing new tests using video-test.js) -->
-        <script src="../video-test.js"></script>
-    </head>
-    <body>
-      <p>Tests that inserting a &lt;track&gt; element immediately after a load() doesn't crash.</p>
-      <video id="v"></video>
-      <script>
-        var v = document.querySelector('#v');
-        v.src = findMediaFile('video', '../content/test');
-        v.load();
-        v.appendChild(document.createElement('track'));
-        v.addEventListener('loadedmetadata', endTest);
-      </script>
-    </body>
-</html>
+<title>Tests that inserting a track element immediately after a load() doesn't crash.</title>
+<script src="../media-file.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+async_test(function(t) {
+    var video = document.createElement('video');
+    video.src = findMediaFile('video', '../content/test');
+    video.load();
+    video.appendChild(document.createElement('track'));
+    video.onloadedmetadata = t.step_func_done();
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
rename to third_party/WebKit/LayoutTests/platform/android/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
diff --git a/third_party/WebKit/LayoutTests/platform/android/transforms/2d/transform-borderbox-expected.png b/third_party/WebKit/LayoutTests/platform/android/transforms/2d/transform-borderbox-expected.png
new file mode 100644
index 0000000..eba23752
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/transforms/2d/transform-borderbox-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/transforms/2d/transform-borderbox-expected.txt b/third_party/WebKit/LayoutTests/platform/android/transforms/2d/transform-borderbox-expected.txt
new file mode 100644
index 0000000..fbfd42f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/transforms/2d/transform-borderbox-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x306
+  LayoutBlockFlow {HTML} at (0,0) size 800x306
+    LayoutBlockFlow {BODY} at (8,16) size 784x260
+      LayoutBlockFlow {P} at (0,0) size 784x0
+      LayoutBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 633x19
+          text run at (0,0) width 633: "Top box should have gray part extending outside the black outline. Lower box should lie inside the outline"
+      LayoutBlockFlow {DIV} at (30,50) size 400x210
+layer at (38,66) size 250x100
+  LayoutBlockFlow {DIV} at (0,0) size 250x100 [bgcolor=#008000] [border: none (50px solid #808080) none]
+    LayoutText {#text} at (0,0) size 94x19
+      text run at (0,0) width 94: "box-sizing: auto"
+layer at (38,176) size 200x100
+  LayoutBlockFlow {DIV} at (0,110) size 200x100 [bgcolor=#008000] [border: none (50px solid #808080) none]
+    LayoutText {#text} at (0,0) size 138x19
+      text run at (0,0) width 138: "box-sizing: border-box"
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
similarity index 100%
copy from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
copy to third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
similarity index 100%
copy from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
copy to third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
similarity index 100%
copy from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
copy to third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
similarity index 100%
copy from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
copy to third_party/WebKit/LayoutTests/platform/android/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
diff --git a/third_party/WebKit/LayoutTests/platform/linux-precise/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/linux-precise/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..9bddfb2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux-precise/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux-precise/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux-precise/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..1101921
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux-precise/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
rename to third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
similarity index 100%
rename from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
rename to third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
new file mode 100644
index 0000000..fceedccd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x36
+  LayoutBlockFlow {HTML} at (0,0) size 800x36
+    LayoutBlockFlow {BODY} at (8,8) size 784x20
+      LayoutText {#text} at (0,0) size 464x19
+        text run at (0,0) width 464: "Tests that we paint area outline properly when the image's container is scaled."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (100,100) size 100x100
+  LayoutBlockFlow (positioned) {DIV} at (100,100) size 100x100
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/clip-path-referencing-use2-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/clip-path-referencing-use2-expected.txt
index b434344..8d3ffe8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/clip-path-referencing-use2-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/clip-path-referencing-use2-expected.txt
@@ -11,8 +11,8 @@
           LayoutSVGContainer {g} at (0,0) size 50x50
             LayoutSVGRect {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=50.00] [height=50.00]
     LayoutSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
-    LayoutSVGContainer {g} at (0,0) size 50x50
-      [clipPath="clip"] LayoutSVGResourceClipper {clipPath} at (0,0) size 50x50
+    LayoutSVGContainer {g} at (0,0) size 0x0
+      [clipPath="clip"] LayoutSVGResourceClipper {clipPath} at (0,0) size 0x0
       LayoutSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
     LayoutSVGText {text} at (10,105) size 360x19 contains 1 chunk(s)
       LayoutSVGInlineText {#text} at (0,0) size 360x19
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.png b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.png
index eba23752..a758253 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.txt
index fbfd42f..6b55424 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/transform-borderbox-expected.txt
@@ -5,8 +5,8 @@
     LayoutBlockFlow {BODY} at (8,16) size 784x260
       LayoutBlockFlow {P} at (0,0) size 784x0
       LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 633x19
-          text run at (0,0) width 633: "Top box should have gray part extending outside the black outline. Lower box should lie inside the outline"
+        LayoutText {#text} at (0,0) size 632x19
+          text run at (0,0) width 632: "Top box should have gray part extending outside the black outline. Lower box should lie inside the outline"
       LayoutBlockFlow {DIV} at (30,50) size 400x210
 layer at (38,66) size 250x100
   LayoutBlockFlow {DIV} at (0,0) size 250x100 [bgcolor=#008000] [border: none (50px solid #808080) none]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..9bddfb2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
similarity index 100%
copy from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
copy to third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
new file mode 100644
index 0000000..5eaa9a5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
similarity index 100%
copy from third_party/WebKit/LayoutTests/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
copy to third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..1101921
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
new file mode 100644
index 0000000..fceedccd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x36
+  LayoutBlockFlow {HTML} at (0,0) size 800x36
+    LayoutBlockFlow {BODY} at (8,8) size 784x20
+      LayoutText {#text} at (0,0) size 464x19
+        text run at (0,0) width 464: "Tests that we paint area outline properly when the image's container is scaled."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (100,100) size 100x100
+  LayoutBlockFlow (positioned) {DIV} at (100,100) size 100x100
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
index 27e5e799..4b8000d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..f2f6e92
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..4e0ea55
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..f2f6e92
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..4e0ea55
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..f2f6e92
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..4e0ea55
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..8213251c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
new file mode 100644
index 0000000..3ba5197
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 564x18
+        text run at (0,0) width 564: "Tests that we paint area outline properly when the image is inside positioned containers."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (20,50) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (20,50) size 0x0
+layer at (30,60) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (10,10) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
new file mode 100644
index 0000000..9793e7c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
new file mode 100644
index 0000000..0839108
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 447x18
+        text run at (0,0) width 447: "Tests that we paint area outline properly when the paintroot is shifted."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (5,50) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (5,50) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..f8d61c8a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
new file mode 100644
index 0000000..ef870b0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 498x18
+        text run at (0,0) width 498: "Tests that we paint area outline properly when the image's container is scaled."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (100,100) size 100x100
+  LayoutBlockFlow (positioned) {DIV} at (100,100) size 100x100
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-zoom-expected.png
index 69bc6de..739144c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/images/imagemap-focus-ring-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.png
index 8694754..75991850 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.txt
index ba26faf..41ad960 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/2d/transform-borderbox-expected.txt
@@ -5,8 +5,8 @@
     LayoutBlockFlow {BODY} at (8,16) size 784x258
       LayoutBlockFlow {P} at (0,0) size 784x0
       LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 683x18
-          text run at (0,0) width 683: "Top box should have gray part extending outside the black outline. Lower box should lie inside the outline"
+        LayoutText {#text} at (0,0) size 682x18
+          text run at (0,0) width 682: "Top box should have gray part extending outside the black outline. Lower box should lie inside the outline"
       LayoutBlockFlow {DIV} at (30,48) size 400x210
 layer at (38,64) size 250x100
   LayoutBlockFlow {DIV} at (0,0) size 250x100 [bgcolor=#008000] [border: none (50px solid #808080) none]
@@ -14,5 +14,5 @@
       text run at (0,0) width 104: "box-sizing: auto"
 layer at (38,174) size 200x100
   LayoutBlockFlow {DIV} at (0,110) size 200x100 [bgcolor=#008000] [border: none (50px solid #808080) none]
-    LayoutText {#text} at (0,0) size 148x18
-      text run at (0,0) width 148: "box-sizing: border-box"
+    LayoutText {#text} at (0,0) size 147x18
+      text run at (0,0) width 147: "box-sizing: border-box"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..f2f6e92
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
new file mode 100644
index 0000000..3ba5197
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 564x18
+        text run at (0,0) width 564: "Tests that we paint area outline properly when the image is inside positioned containers."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (20,50) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (20,50) size 0x0
+layer at (30,60) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (10,10) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
new file mode 100644
index 0000000..6e0dbeb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
new file mode 100644
index 0000000..0839108
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 447x18
+        text run at (0,0) width 447: "Tests that we paint area outline properly when the paintroot is shifted."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (5,50) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (5,50) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..4e0ea55
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
new file mode 100644
index 0000000..ef870b0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 498x18
+        text run at (0,0) width 498: "Tests that we paint area outline properly when the image's container is scaled."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (100,100) size 100x100
+  LayoutBlockFlow (positioned) {DIV} at (100,100) size 100x100
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
index 9a0e86f..03140a5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..5fdf6d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
new file mode 100644
index 0000000..cb37e0c8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 564x17
+        text run at (0,0) width 564: "Tests that we paint area outline properly when the image is inside positioned containers."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (20,50) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (20,50) size 0x0
+layer at (30,60) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (10,10) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
new file mode 100644
index 0000000..5066715
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
new file mode 100644
index 0000000..c95135c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 447x17
+        text run at (0,0) width 447: "Tests that we paint area outline properly when the paintroot is shifted."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (5,50) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (5,50) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..f97fcfd2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
new file mode 100644
index 0000000..b25ca06c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 498x17
+        text run at (0,0) width 498: "Tests that we paint area outline properly when the image's container is scaled."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (100,100) size 100x100
+  LayoutBlockFlow (positioned) {DIV} at (100,100) size 100x100
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-zoom-expected.png
index c3d80c4..63634f8e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/images/imagemap-focus-ring-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.png b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.png
index cf0fbd5..d6c4641 100644
--- a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.txt b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.txt
index f05b3f8..1401afa 100644
--- a/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/transforms/2d/transform-borderbox-expected.txt
@@ -5,8 +5,8 @@
     LayoutBlockFlow {BODY} at (8,16) size 784x258
       LayoutBlockFlow {P} at (0,0) size 784x0
       LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 683x17
-          text run at (0,0) width 683: "Top box should have gray part extending outside the black outline. Lower box should lie inside the outline"
+        LayoutText {#text} at (0,0) size 682x17
+          text run at (0,0) width 682: "Top box should have gray part extending outside the black outline. Lower box should lie inside the outline"
       LayoutBlockFlow {DIV} at (30,48) size 400x210
 layer at (38,64) size 250x100
   LayoutBlockFlow {DIV} at (0,0) size 250x100 [bgcolor=#008000] [border: none (50px solid #808080) none]
@@ -14,5 +14,5 @@
       text run at (0,0) width 104: "box-sizing: auto"
 layer at (38,174) size 200x100
   LayoutBlockFlow {DIV} at (0,110) size 200x100 [bgcolor=#008000] [border: none (50px solid #808080) none]
-    LayoutText {#text} at (0,0) size 148x17
-      text run at (0,0) width 148: "box-sizing: border-box"
+    LayoutText {#text} at (0,0) size 147x17
+      text run at (0,0) width 147: "box-sizing: border-box"
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..4fabfef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
new file mode 100644
index 0000000..cb37e0c8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 564x17
+        text run at (0,0) width 564: "Tests that we paint area outline properly when the image is inside positioned containers."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (20,50) size 0x0
+  LayoutBlockFlow (positioned) {DIV} at (20,50) size 0x0
+layer at (30,60) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (10,10) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
new file mode 100644
index 0000000..8cb38ae
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
new file mode 100644
index 0000000..c95135c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-paint-root-offset-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 447x17
+        text run at (0,0) width 447: "Tests that we paint area outline properly when the paintroot is shifted."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (5,50) size 50x54
+  LayoutBlockFlow (positioned) {DIV} at (5,50) size 50x54
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..858219c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
new file mode 100644
index 0000000..b25ca06c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.txt
@@ -0,0 +1,16 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x34
+  LayoutBlockFlow {HTML} at (0,0) size 800x34
+    LayoutBlockFlow {BODY} at (8,8) size 784x18
+      LayoutText {#text} at (0,0) size 498x17
+        text run at (0,0) width 498: "Tests that we paint area outline properly when the image's container is scaled."
+      LayoutText {#text} at (0,0) size 0x0
+      LayoutText {#text} at (0,0) size 0x0
+layer at (100,100) size 100x100
+  LayoutBlockFlow (positioned) {DIV} at (100,100) size 100x100
+    LayoutImage {IMG} at (0,0) size 50x50
+    LayoutText {#text} at (0,0) size 0x0
+    LayoutInline {MAP} at (0,0) size 0x0
+      LayoutInline {AREA} at (0,0) size 0x0
+    LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
index 2e1da96..7f78487 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
new file mode 100644
index 0000000..4fabfef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-in-positioned-container-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
new file mode 100644
index 0000000..858219c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/fast/images/imagemap-focus-ring-with-scale-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/clip-path/visible-clip-path-as-hidden-use-element-expected.html b/third_party/WebKit/LayoutTests/svg/clip-path/visible-clip-path-as-hidden-use-element-expected.html
new file mode 100644
index 0000000..f718ea6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/clip-path/visible-clip-path-as-hidden-use-element-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/clip-path/visible-clip-path-as-hidden-use-element.html b/third_party/WebKit/LayoutTests/svg/clip-path/visible-clip-path-as-hidden-use-element.html
new file mode 100644
index 0000000..dcc53d51
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/clip-path/visible-clip-path-as-hidden-use-element.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<svg>
+  <defs>
+    <rect id="rect" width="100" height="100" visibility="visible"></rect>
+    <clipPath id="clip" visibility="hidden">
+      <use xlink:href="#rect"/>
+    </clipPath>
+  </defs>
+  <rect width="400" height="400" fill="green" clip-path="url(#clip)"></rect>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/svg/clip-path/visible-nested-clip-path-as-hidden-use-element-expected.html b/third_party/WebKit/LayoutTests/svg/clip-path/visible-nested-clip-path-as-hidden-use-element-expected.html
new file mode 100644
index 0000000..f718ea6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/clip-path/visible-nested-clip-path-as-hidden-use-element-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/clip-path/visible-nested-clip-path-as-hidden-use-element.html b/third_party/WebKit/LayoutTests/svg/clip-path/visible-nested-clip-path-as-hidden-use-element.html
new file mode 100644
index 0000000..0872265
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/clip-path/visible-nested-clip-path-as-hidden-use-element.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<svg>
+    <defs>
+        <rect id="rect" width="100" height="100" visibility="visible"/>
+        <clipPath id="clipClip">
+            <rect width="100" height="100"/>
+        </clipPath>
+        <clipPath id="clip" clip-path="url(#clipClip)">
+            <use visibility="hidden" xlink:href="#rect"/>
+        </clipPath>
+    </defs>
+    <rect height="400" width="400" fill="green" clip-path="url(#clip)"/>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/clip-path-referencing-use2-expected.txt b/third_party/WebKit/LayoutTests/svg/custom/clip-path-referencing-use2-expected.txt
index 83a99543..094d3b0b 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/clip-path-referencing-use2-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/custom/clip-path-referencing-use2-expected.txt
@@ -11,8 +11,8 @@
           LayoutSVGContainer {g} at (0,0) size 50x50
             LayoutSVGRect {rect} at (0,0) size 50x50 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=50.00] [height=50.00]
     LayoutSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
-    LayoutSVGContainer {g} at (0,0) size 50x50
-      [clipPath="clip"] LayoutSVGResourceClipper {clipPath} at (0,0) size 50x50
+    LayoutSVGContainer {g} at (0,0) size 0x0
+      [clipPath="clip"] LayoutSVGResourceClipper {clipPath} at (0,0) size 0x0
       LayoutSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
     LayoutSVGText {text} at (10,106) size 381x18 contains 1 chunk(s)
       LayoutSVGInlineText {#text} at (0,0) size 381x18
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index fa7fcde3..21e73d44 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -3399,6 +3399,7 @@
     attribute @@toStringTag
     getter data
     getter inputType
+    getter isComposing
     method constructor
 interface IntersectionObserver
     attribute @@toStringTag
diff --git a/third_party/WebKit/Source/BUILD.gn b/third_party/WebKit/Source/BUILD.gn
index 3ba6966..1f316a41 100644
--- a/third_party/WebKit/Source/BUILD.gn
+++ b/third_party/WebKit/Source/BUILD.gn
@@ -80,15 +80,6 @@
       "-Xclang",
       "blink-gc-plugin",
     ]
-
-    if (enable_oilpan) {
-      cflags += [
-        "-Xclang",
-        "-plugin-arg-blink-gc-plugin",
-        "-Xclang",
-        "enable-oilpan",
-      ]
-    }
   }
 
   ## TODO(GYP) : gn does not yet support use_system_icu.
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.cpp b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.cpp
index d3324ea9..03781b5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.cpp
@@ -17,10 +17,9 @@
 
 SerializedScriptValueFactory* SerializedScriptValueFactory::m_instance = 0;
 
-PassRefPtr<SerializedScriptValue> SerializedScriptValueFactory::create(v8::Isolate* isolate, v8::Local<v8::Value> value, Transferables* transferables, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState)
+PassRefPtr<SerializedScriptValue> SerializedScriptValueFactory::create(v8::Isolate* isolate, v8::Local<v8::Value> value, SerializedScriptValueWriter& writer, Transferables* transferables, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState)
 {
     RefPtr<SerializedScriptValue> serializedValue = create();
-    SerializedScriptValueWriter writer;
     ScriptValueSerializer::Status status;
     String errorMessage;
     {
@@ -35,7 +34,7 @@
     switch (status) {
     case ScriptValueSerializer::InputError:
     case ScriptValueSerializer::DataCloneError:
-        exceptionState.throwDOMException(ScriptValueSerializer::DataCloneError, errorMessage);
+        exceptionState.throwDOMException(DataCloneError, errorMessage);
         return serializedValue.release();
     case ScriptValueSerializer::Success:
         transferData(serializedValue.get(), writer, transferables, exceptionState, isolate);
@@ -48,6 +47,12 @@
     return serializedValue.release();
 }
 
+PassRefPtr<SerializedScriptValue> SerializedScriptValueFactory::create(v8::Isolate* isolate, v8::Local<v8::Value> value, Transferables* transferables, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState)
+{
+    SerializedScriptValueWriter writer;
+    return create(isolate, value, writer, transferables, blobInfo, exceptionState);
+}
+
 PassRefPtr<SerializedScriptValue> SerializedScriptValueFactory::create(v8::Isolate* isolate, v8::Local<v8::Value> value, Transferables* transferables, ExceptionState& exceptionState)
 {
     return create(isolate, value, transferables, 0, exceptionState);
diff --git a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.h b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.h
index 28dd617..0abe1a34 100644
--- a/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.h
+++ b/third_party/WebKit/Source/bindings/core/v8/SerializedScriptValueFactory.h
@@ -25,6 +25,7 @@
     // the caller must not invoke any V8 operations until control returns to
     // V8. When serialization is successful, |didThrow| is false.
     virtual PassRefPtr<SerializedScriptValue> create(v8::Isolate*, v8::Local<v8::Value>, Transferables*, WebBlobInfoArray*, ExceptionState&);
+    PassRefPtr<SerializedScriptValue> create(v8::Isolate*, v8::Local<v8::Value>, SerializedScriptValueWriter&, Transferables*, WebBlobInfoArray*, ExceptionState&);
     PassRefPtr<SerializedScriptValue> create(v8::Isolate*, v8::Local<v8::Value>, Transferables*, ExceptionState&);
     PassRefPtr<SerializedScriptValue> createFromWire(const String&);
     PassRefPtr<SerializedScriptValue> createFromWireBytes(const char* data, size_t length);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8.h b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
index 3f4a9779..497deccc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ToV8.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ToV8.h
@@ -209,7 +209,7 @@
         v8::Local<v8::Value> value = toV8(*iter, array, isolate);
         if (value.IsEmpty())
             value = v8::Undefined(isolate);
-        if (!v8CallBoolean(array->Set(isolate->GetCurrentContext(), v8::Integer::New(isolate, index++), value)))
+        if (!v8CallBoolean(array->CreateDataProperty(isolate->GetCurrentContext(), index++, value)))
             return v8::Local<v8::Value>();
     }
     return array;
@@ -239,7 +239,7 @@
         v8::Local<v8::Value> v8Value = toV8(value[i].second, object, isolate);
         if (v8Value.IsEmpty())
             v8Value = v8::Undefined(isolate);
-        if (!v8CallBoolean(object->Set(isolate->GetCurrentContext(), v8String(isolate, value[i].first), v8Value)))
+        if (!v8CallBoolean(object->CreateDataProperty(isolate->GetCurrentContext(), v8String(isolate, value[i].first), v8Value)))
             return v8::Local<v8::Value>();
     }
     return object;
diff --git a/third_party/WebKit/Source/bindings/modules/v8/SerializedScriptValueForModulesFactory.cpp b/third_party/WebKit/Source/bindings/modules/v8/SerializedScriptValueForModulesFactory.cpp
index bafa2c9..5f03c5b 100644
--- a/third_party/WebKit/Source/bindings/modules/v8/SerializedScriptValueForModulesFactory.cpp
+++ b/third_party/WebKit/Source/bindings/modules/v8/SerializedScriptValueForModulesFactory.cpp
@@ -13,33 +13,8 @@
 
 PassRefPtr<SerializedScriptValue> SerializedScriptValueForModulesFactory::create(v8::Isolate* isolate, v8::Local<v8::Value> value, Transferables* transferables, WebBlobInfoArray* blobInfo, ExceptionState& exceptionState)
 {
-    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValueFactory::create();
     SerializedScriptValueWriterForModules writer;
-    ScriptValueSerializer::Status status;
-    String errorMessage;
-    {
-        v8::TryCatch tryCatch(isolate);
-        status = SerializedScriptValueFactory::doSerialize(value, writer, transferables, blobInfo, serializedValue.get(), tryCatch, errorMessage, isolate);
-        if (status == ScriptValueSerializer::JSException) {
-            // If there was a JS exception thrown, re-throw it.
-            exceptionState.rethrowV8Exception(tryCatch.Exception());
-            return serializedValue.release();
-        }
-    }
-    switch (status) {
-    case ScriptValueSerializer::InputError:
-    case ScriptValueSerializer::DataCloneError:
-        exceptionState.throwDOMException(DataCloneError, errorMessage);
-        return serializedValue.release();
-    case ScriptValueSerializer::Success:
-        transferData(serializedValue.get(), writer, transferables, exceptionState, isolate);
-        return serializedValue.release();
-    case ScriptValueSerializer::JSException:
-        ASSERT_NOT_REACHED();
-        break;
-    }
-    ASSERT_NOT_REACHED();
-    return serializedValue.release();
+    return SerializedScriptValueFactory::create(isolate, value, writer, transferables, blobInfo, exceptionState);
 }
 
 PassRefPtr<SerializedScriptValue> SerializedScriptValueForModulesFactory::create(v8::Isolate* isolate, const String& data)
diff --git a/third_party/WebKit/Source/build/features.gypi b/third_party/WebKit/Source/build/features.gypi
index 4d58abd..aaaadd4 100644
--- a/third_party/WebKit/Source/build/features.gypi
+++ b/third_party/WebKit/Source/build/features.gypi
@@ -48,10 +48,6 @@
     # We have to nest variables inside variables so that they can be overridden
     # through GYP_DEFINES.
     'variables': {
-      # Enables the Oilpan garbage-collection infrastructure.
-      # If you update the default value below, be sure to update the one in
-      # ../config.gyp, too!
-      'enable_oilpan%': 1,
       'blink_logging_always_on%': 0,
     },
     'conditions': [
diff --git a/third_party/WebKit/Source/build/scripts/make_runtime_features.py b/third_party/WebKit/Source/build/scripts/make_runtime_features.py
index e98f558e..206d147 100755
--- a/third_party/WebKit/Source/build/scripts/make_runtime_features.py
+++ b/third_party/WebKit/Source/build/scripts/make_runtime_features.py
@@ -49,6 +49,7 @@
         'depends_on': [],
         'custom': False,
         'status': None,
+        'settable_from_internals': False,
     }
 
     def __init__(self, in_file_path):
diff --git a/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.h.tmpl
index df2f2f6..dc486ac 100644
--- a/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.h.tmpl
@@ -21,12 +21,12 @@
         return new InternalRuntimeFlags;
     }
 
-{#
-    Setting after startup does not work for most runtime flags, but we
-    could add an option to print setters for ones which do:
+    // These are reset between layout tests from Internals::resetToConsistentState
+    // using RuntimeEnabledFeatures::Backup.
+    {% for feature in standard_features if feature.settable_from_internals %}
     void set{{feature.name}}Enabled(bool isEnabled) { RuntimeEnabledFeatures::set{{feature.name}}Enabled(isEnabled); }
-    If we do that, we also need to respect Internals::resetToConsistentState.
-#}
+    {% endfor %}
+
     {% for feature in standard_features %}
     bool {{feature.first_lowered_name}}Enabled() { return RuntimeEnabledFeatures::{{feature.first_lowered_name}}Enabled(); }
     {% endfor %}
diff --git a/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.idl.tmpl b/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.idl.tmpl
index cfdd2c0d..16e4693 100644
--- a/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.idl.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/InternalRuntimeFlags.idl.tmpl
@@ -5,11 +5,11 @@
     GarbageCollected,
 ] interface InternalRuntimeFlags {
     {% for feature in standard_features %}
-{#
-    Currently assuming that runtime flags cannot be changed after startup
-    it's possible that some can be and should be conditionally readonly.
-#}
     {%+ if feature.condition %}[Conditional={{feature.condition}}] {% endif -%}
+    {% if feature.settable_from_internals %}
+    attribute boolean {{feature.first_lowered_name}}Enabled;
+    {% else %}
     readonly attribute boolean {{feature.first_lowered_name}}Enabled;
+    {% endif %}
     {% endfor %}
 };
diff --git a/third_party/WebKit/Source/config.gyp b/third_party/WebKit/Source/config.gyp
index 9d5e020..7874b97 100644
--- a/third_party/WebKit/Source/config.gyp
+++ b/third_party/WebKit/Source/config.gyp
@@ -32,10 +32,6 @@
     # If set to 1, doesn't compile debug symbols into webcore reducing the
     # size of the binary and increasing the speed of gdb.  gcc only.
     'remove_webcore_debug_symbols%': 0,
-    # Enables the Oilpan garbage-collection infrastructure.
-    # If you update the default value below, be sure to update the one in
-    # build/features.gypi, too!
-    'enable_oilpan%': 1,
     # If set to 1 (default) and using clang, the Blink GC plugin will check the
     # usage of the garbage-collection infrastructure during compilation.
     'blink_gc_plugin%': 1,
@@ -96,13 +92,13 @@
         }],
         # Only enable the blink_gc_plugin when using clang and chrome plugins.
         ['blink_gc_plugin==1 and clang==1 and clang_use_chrome_plugins==1', {
-          'cflags': ['<!@(python <(DEPTH)/tools/clang/scripts/blink_gc_plugin_flags.py enable-oilpan=<(enable_oilpan) <(blink_gc_plugin_flags))'],
+          'cflags': ['<!@(python <(DEPTH)/tools/clang/scripts/blink_gc_plugin_flags.py <(blink_gc_plugin_flags))'],
           'xcode_settings': {
-            'OTHER_CFLAGS': ['<!@(python <(DEPTH)/tools/clang/scripts/blink_gc_plugin_flags.py enable-oilpan=<(enable_oilpan) <(blink_gc_plugin_flags))'],
+            'OTHER_CFLAGS': ['<!@(python <(DEPTH)/tools/clang/scripts/blink_gc_plugin_flags.py <(blink_gc_plugin_flags))'],
           },
           'msvs_settings': {
             'VCCLCompilerTool': {
-              'AdditionalOptions': ['<!@(python <(DEPTH)/tools/clang/scripts/blink_gc_plugin_flags.py enable-oilpan=<(enable_oilpan) <(blink_gc_plugin_flags))'],
+              'AdditionalOptions': ['<!@(python <(DEPTH)/tools/clang/scripts/blink_gc_plugin_flags.py <(blink_gc_plugin_flags))'],
             },
           },
         }],
diff --git a/third_party/WebKit/Source/core/OWNERS b/third_party/WebKit/Source/core/OWNERS
index 94d63475..64dbf62 100644
--- a/third_party/WebKit/Source/core/OWNERS
+++ b/third_party/WebKit/Source/core/OWNERS
@@ -43,8 +43,6 @@
 # pdr reviews many svg and text autosizing patches.
 pdr@chromium.org
 pfeldman@chromium.org
-# philipj reviews <video>, <track>, WebVTT and Fullscreen.
-philipj@opera.com
 pkasting@chromium.org
 # rbyers reviews input related changes (eg. event handling, mouse cursors, touch hit testing, scrolling coordinator)
 rbyers@chromium.org
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 85f5b12..5f3cd06 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -1872,7 +1872,6 @@
             'inspector/InspectorWorkerAgent.h',
             'inspector/InstanceCounters.cpp',
             'inspector/InstanceCounters.h',
-            'inspector/InstrumentingSessions.h',
             'inspector/LayoutEditor.cpp',
             'inspector/LayoutEditor.h',
             'inspector/MainThreadDebugger.cpp',
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserToken.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserToken.cpp
index 5101465..864a5ea 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserToken.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserToken.cpp
@@ -147,6 +147,36 @@
     return copy;
 }
 
+bool CSSParserToken::operator==(const CSSParserToken& other) const
+{
+    if (m_type != other.m_type)
+        return false;
+    switch (m_type) {
+    case DelimiterToken:
+        return delimiter() == other.delimiter();
+    case HashToken:
+        if (m_hashTokenType != other.m_hashTokenType)
+            return false;
+        // fallthrough
+    case IdentToken:
+    case FunctionToken:
+    case StringToken:
+    case UrlToken:
+        return m_valueDataCharRaw == other.m_valueDataCharRaw && m_valueLength == other.m_valueLength && m_valueIs8Bit == other.m_valueIs8Bit;
+    case DimensionToken:
+        if (m_valueDataCharRaw != other.m_valueDataCharRaw || m_valueLength != other.m_valueLength || m_valueIs8Bit != other.m_valueIs8Bit)
+            return false;
+        // fallthrough
+    case NumberToken:
+    case PercentageToken:
+        return m_numericSign == other.m_numericSign && m_numericValue == other.m_numericValue && m_numericValueType == other.m_numericValueType;
+    case UnicodeRangeToken:
+        return m_unicodeRange.start == other.m_unicodeRange.start && m_unicodeRange.end == other.m_unicodeRange.end;
+    default:
+        return true;
+    }
+}
+
 void CSSParserToken::serialize(StringBuilder& builder) const
 {
     // This is currently only used for @supports CSSOM. To keep our implementation
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserToken.h b/third_party/WebKit/Source/core/css/parser/CSSParserToken.h
index 9ee58f4..f857b3d 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSParserToken.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserToken.h
@@ -82,38 +82,7 @@
 
     CSSParserToken(HashTokenType, CSSParserString);
 
-    bool operator==(const CSSParserToken& other) const
-    {
-        if (m_type != other.m_type)
-            return false;
-        switch (m_type) {
-        case DelimiterToken:
-            return delimiter() == other.delimiter();
-        case HashToken:
-            if (m_hashTokenType != other.m_hashTokenType)
-                return false;
-            // fallthrough
-        case IdentToken:
-        case FunctionToken:
-        case StringToken:
-        case UrlToken:
-            return m_valueDataCharRaw == other.m_valueDataCharRaw && m_valueLength == other.m_valueLength && m_valueIs8Bit == other.m_valueIs8Bit;
-        case NumberToken:
-            if (m_numericSign != other.m_numericSign)
-                return false;
-            // fallthrough
-        case DimensionToken:
-            if (m_valueDataCharRaw != other.m_valueDataCharRaw || m_valueLength != other.m_valueLength || m_valueIs8Bit != other.m_valueIs8Bit)
-                return false;
-            // fallthrough
-        case PercentageToken:
-            return m_numericValue == other.m_numericValue && m_numericValueType == other.m_numericValueType;
-        case UnicodeRangeToken:
-            return m_unicodeRange.start == other.m_unicodeRange.start && m_unicodeRange.end == other.m_unicodeRange.end;
-        default:
-            return true;
-        }
-    }
+    bool operator==(const CSSParserToken& other) const;
 
     // Converts NumberToken to DimensionToken.
     void convertToDimensionWithUnit(CSSParserString);
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
index bdfadf91..46e3da7 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -1738,7 +1738,7 @@
         return DispatchEventResult::NotCanceled;
     if (!target)
         return DispatchEventResult::NotCanceled;
-    InputEvent* beforeInputEvent = InputEvent::createBeforeInput(InputEvent::InputType::InsertText, data, InputEvent::EventCancelable::IsCancelable);
+    InputEvent* beforeInputEvent = InputEvent::createBeforeInput(InputEvent::InputType::InsertText, data, InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotComposing);
     return target->dispatchEvent(beforeInputEvent);
 }
 
@@ -1748,7 +1748,7 @@
         return DispatchEventResult::NotCanceled;
     if (!target)
         return DispatchEventResult::NotCanceled;
-    InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data, InputEvent::EventCancelable::NotCancelable);
+    InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data, InputEvent::EventCancelable::NotCancelable, InputEvent::EventIsComposing::IsComposing);
     return target->dispatchEvent(beforeInputEvent);
 }
 
@@ -1758,7 +1758,7 @@
         return DispatchEventResult::NotCanceled;
     if (!target)
         return DispatchEventResult::NotCanceled;
-    InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data, InputEvent::EventCancelable::IsCancelable);
+    InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data, InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotComposing);
     return target->dispatchEvent(beforeInputEvent);
 }
 
diff --git a/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp b/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp
index b7558279..4af9689 100644
--- a/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp
@@ -7,7 +7,10 @@
 #include "core/dom/Element.h"
 #include "core/dom/Range.h"
 #include "core/editing/FrameSelection.h"
+#include "core/events/MouseEvent.h"
+#include "core/frame/FrameView.h"
 #include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
 #include "core/html/HTMLDocument.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/testing/DummyPageHolder.h"
@@ -190,4 +193,31 @@
     EXPECT_STREQ("foo", input->value().utf8().data());
 }
 
+TEST_F(InputMethodControllerTest, CompositionFireBeforeInput)
+{
+    document().settings()->setScriptEnabled(true);
+    Element* editable = insertHTMLElement("<div id='sample' contentEditable='true'></div>", "sample");
+    Element* script = document().createElement("script", ASSERT_NO_EXCEPTION);
+    script->setInnerHTML(
+        "document.getElementById('sample').addEventListener('beforeinput', function(event) {"
+        "    document.title = `beforeinput.isComposing:${event.isComposing}`;"
+        "});",
+        ASSERT_NO_EXCEPTION);
+    document().body()->appendChild(script, ASSERT_NO_EXCEPTION);
+    document().view()->updateAllLifecyclePhases();
+
+    // Simulate composition in the |contentEditable|.
+    Vector<CompositionUnderline> underlines;
+    underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
+    editable->focus();
+
+    document().setTitle(emptyString());
+    controller().setComposition("foo", underlines, 0, 3);
+    EXPECT_STREQ("beforeinput.isComposing:true", document().title().utf8().data());
+
+    document().setTitle(emptyString());
+    controller().confirmComposition();
+    EXPECT_STREQ("beforeinput.isComposing:false", document().title().utf8().data());
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/events/InputEvent.cpp b/third_party/WebKit/Source/core/events/InputEvent.cpp
index e5bef79..337496a 100644
--- a/third_party/WebKit/Source/core/events/InputEvent.cpp
+++ b/third_party/WebKit/Source/core/events/InputEvent.cpp
@@ -60,10 +60,12 @@
         m_inputType = convertStringToInputType(initializer.inputType());
     if (initializer.hasData())
         m_data = initializer.data();
+    if (initializer.hasIsComposing())
+        m_isComposing = initializer.isComposing();
 }
 
 /* static */
-InputEvent* InputEvent::createBeforeInput(InputType inputType, const String& data, EventCancelable cancelable)
+InputEvent* InputEvent::createBeforeInput(InputType inputType, const String& data, EventCancelable cancelable, EventIsComposing isComposing)
 {
     InputEventInit inputEventInit;
 
@@ -73,6 +75,7 @@
     // See InputEvent::InputEvent() for the second conversion.
     inputEventInit.setInputType(convertInputTypeToString(inputType));
     inputEventInit.setData(data);
+    inputEventInit.setIsComposing(isComposing == IsComposing);
 
     return InputEvent::create(EventTypeNames::beforeinput, inputEventInit);
 }
diff --git a/third_party/WebKit/Source/core/events/InputEvent.h b/third_party/WebKit/Source/core/events/InputEvent.h
index 4c14550f..651ee134 100644
--- a/third_party/WebKit/Source/core/events/InputEvent.h
+++ b/third_party/WebKit/Source/core/events/InputEvent.h
@@ -42,10 +42,16 @@
         IsCancelable = true,
     };
 
-    static InputEvent* createBeforeInput(InputType, const String& data, EventCancelable);
+    enum EventIsComposing : bool {
+        NotComposing = false,
+        IsComposing = true,
+    };
+
+    static InputEvent* createBeforeInput(InputType, const String& data, EventCancelable, EventIsComposing);
 
     String inputType() const;
     const String& data() const { return m_data; }
+    bool isComposing() const { return m_isComposing; }
 
     bool isInputEvent() const override;
 
@@ -57,6 +63,7 @@
 
     InputType m_inputType;
     String m_data;
+    bool m_isComposing;
 };
 
 DEFINE_EVENT_TYPE_CASTS(InputEvent);
diff --git a/third_party/WebKit/Source/core/events/InputEvent.idl b/third_party/WebKit/Source/core/events/InputEvent.idl
index 6d6dfa7..ce907c7 100644
--- a/third_party/WebKit/Source/core/events/InputEvent.idl
+++ b/third_party/WebKit/Source/core/events/InputEvent.idl
@@ -10,5 +10,6 @@
 ] interface InputEvent : UIEvent {
     readonly attribute DOMString inputType;
     readonly attribute DOMString data;
-    // TODO(chongz): Add 'isComposing' and 'targetRanges'
+    readonly attribute boolean isComposing;
+    // TODO(chongz): Add 'targetRanges'
 };
diff --git a/third_party/WebKit/Source/core/events/InputEventInit.idl b/third_party/WebKit/Source/core/events/InputEventInit.idl
index 89c8e09..e9b0b5d 100644
--- a/third_party/WebKit/Source/core/events/InputEventInit.idl
+++ b/third_party/WebKit/Source/core/events/InputEventInit.idl
@@ -9,5 +9,6 @@
 ] dictionary InputEventInit : UIEventInit {
     DOMString inputType = "";
     DOMString data = "";
-    // TODO(chongz): Add 'isComposing' and 'targetRanges'
+    boolean isComposing = false;
+    // TODO(chongz): Add 'targetRanges'
 };
diff --git a/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp b/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
index 8aa33d1..78ebcd9 100644
--- a/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
@@ -51,6 +51,7 @@
 
 CSSStyleSheetResource::CSSStyleSheetResource(const ResourceRequest& resourceRequest, const ResourceLoaderOptions& options, const String& charset)
     : StyleSheetResource(resourceRequest, CSSStyleSheet, options, "text/css", charset)
+    , m_didNotifyFirstData(false)
 {
 }
 
@@ -98,6 +99,17 @@
     return decodedText();
 }
 
+void CSSStyleSheetResource::appendData(const char* data, size_t length)
+{
+    Resource::appendData(data, length);
+    if (m_didNotifyFirstData)
+        return;
+    ResourceClientWalker<StyleSheetResourceClient> w(m_clients);
+    while (StyleSheetResourceClient* c = w.next())
+        c->didAppendFirstData(this);
+    m_didNotifyFirstData = true;
+}
+
 void CSSStyleSheetResource::checkNotify()
 {
     // Decode the data to find out the encoding and keep the sheet text around during checkNotify()
diff --git a/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h b/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h
index 0e60508..12fa0c9b 100644
--- a/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h
+++ b/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h
@@ -55,6 +55,8 @@
     StyleSheetContents* restoreParsedStyleSheet(const CSSParserContext&);
     void saveParsedStyleSheet(StyleSheetContents*);
 
+    void appendData(const char* data, size_t length) override;
+
 protected:
     bool isSafeToUnlock() const override;
     void destroyDecodedDataIfPossible() override;
@@ -80,6 +82,8 @@
     String m_decodedSheetText;
 
     Member<StyleSheetContents> m_parsedStyleSheetCache;
+
+    bool m_didNotifyFirstData;
 };
 
 DEFINE_RESOURCE_TYPE_CASTS(CSSStyleSheet);
diff --git a/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h b/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h
index 9656bd0f..62c9475d 100644
--- a/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h
+++ b/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h
@@ -40,6 +40,10 @@
     ResourceClientType getResourceClientType() const final { return StyleSheetType; }
     virtual void setCSSStyleSheet(const String& /* href */, const KURL& /* baseURL */, const String& /* charset */, const CSSStyleSheetResource*) {}
     virtual void setXSLStyleSheet(const String& /* href */, const KURL& /* baseURL */, const String& /* sheet */) {}
+
+    // This gets called on the very first appendData call for the
+    // CSSStyleSheetResource.
+    virtual void didAppendFirstData(const CSSStyleSheetResource*) {}
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp
index ab7a501..1b6b9e7 100644
--- a/third_party/WebKit/Source/core/frame/Frame.cpp
+++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -288,6 +288,14 @@
     return nullptr;
 }
 
+bool Frame::isCrossOrigin() const
+{
+    // Check to see if the frame can script into the top level document.
+    const SecurityOrigin* securityOrigin = securityContext()->getSecurityOrigin();
+    Frame* top = tree().top();
+    return top && !securityOrigin->canAccess(top->securityContext()->getSecurityOrigin());
+}
+
 Frame::Frame(FrameClient* client, FrameHost* host, FrameOwner* owner)
     : m_treeNode(this)
     , m_host(host)
diff --git a/third_party/WebKit/Source/core/frame/Frame.h b/third_party/WebKit/Source/core/frame/Frame.h
index 8554f00..37808189 100644
--- a/third_party/WebKit/Source/core/frame/Frame.h
+++ b/third_party/WebKit/Source/core/frame/Frame.h
@@ -121,6 +121,10 @@
 
     Settings* settings() const; // can be null
 
+    // Return true if and only if this frame is a cross-origin frame with
+    // respect to the top-level frame.
+    bool isCrossOrigin() const;
+
     // isLoading() is true when the embedder should think a load is in progress.
     // In the case of LocalFrames, it means that the frame has sent a didStartLoading()
     // callback, but not the matching didStopLoading(). Inside blink, you probably
diff --git a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
index a088867..6427f7e 100644
--- a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
@@ -329,7 +329,7 @@
         WTF::TextEncoding textEncoding(styleSheet.contents()->charset());
         ASSERT(textEncoding.isValid());
         String textString = cssText.toString();
-        CString text = textEncoding.encode(textString, WTF::EntitiesForUnencodables);
+        CString text = textEncoding.encode(textString, WTF::CSSEncodedEntitiesForUnencodables);
         m_resources->append(SerializedResource(url, String("text/css"), SharedBuffer::create(text.data(), text.length())));
         m_resourceURLs.add(url);
     }
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index 030f8964..282a730 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -9,6 +9,7 @@
 #include "core/html/ImageData.h"
 #include "platform/graphics/skia/SkiaUtils.h"
 #include "platform/image-decoders/ImageDecoder.h"
+#include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "wtf/RefPtr.h"
 
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
index 680b60b..704bd387 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -43,6 +43,7 @@
 #include "platform/heap/Handle.h"
 #include "platform/network/ResourceRequest.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "wtf/OwnPtr.h"
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index e7f6e39..7ed2ae79 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -79,33 +79,47 @@
 
 namespace blink {
 
-LocalDOMWindow::WindowFrameObserver::WindowFrameObserver(LocalDOMWindow* window, LocalFrame& frame)
-    : LocalFrameLifecycleObserver(&frame)
-    , m_window(window)
-{
-}
+// Rather than simply inheriting LocalFrameLifecycleObserver like most other
+// classes, LocalDOMWindow hides its LocalFrameLifecycleObserver with
+// composition. This prevents conflicting overloads between DOMWindow, which
+// has a frame() accessor that returns Frame* for bindings code, and
+// LocalFrameLifecycleObserver, which has a frame() accessor that returns a
+// LocalFrame*.
+class LocalDOMWindow::WindowFrameObserver final : public GarbageCollected<LocalDOMWindow::WindowFrameObserver>, public LocalFrameLifecycleObserver {
+    USING_GARBAGE_COLLECTED_MIXIN(WindowFrameObserver);
+public:
+    static WindowFrameObserver* create(LocalDOMWindow* window, LocalFrame& frame)
+    {
+        return new WindowFrameObserver(window, frame);
+    }
 
-LocalDOMWindow::WindowFrameObserver* LocalDOMWindow::WindowFrameObserver::create(LocalDOMWindow* window, LocalFrame& frame)
-{
-    return new WindowFrameObserver(window, frame);
-}
+    DEFINE_INLINE_VIRTUAL_TRACE()
+    {
+        visitor->trace(m_window);
+        LocalFrameLifecycleObserver::trace(visitor);
+    }
 
-DEFINE_TRACE(LocalDOMWindow::WindowFrameObserver)
-{
-    visitor->trace(m_window);
-    LocalFrameLifecycleObserver::trace(visitor);
-}
+    // LocalFrameLifecycleObserver overrides:
+    void willDetachFrameHost() override
+    {
+        m_window->willDetachFrameHost();
+    }
 
-void LocalDOMWindow::WindowFrameObserver::willDetachFrameHost()
-{
-    m_window->willDetachFrameHost();
-}
+    void contextDestroyed() override
+    {
+        m_window->frameDestroyed();
+        LocalFrameLifecycleObserver::contextDestroyed();
+    }
 
-void LocalDOMWindow::WindowFrameObserver::contextDestroyed()
-{
-    m_window->frameDestroyed();
-    LocalFrameLifecycleObserver::contextDestroyed();
-}
+private:
+    WindowFrameObserver(LocalDOMWindow* window, LocalFrame& frame)
+        : LocalFrameLifecycleObserver(&frame)
+        , m_window(window)
+    {
+    }
+
+    Member<LocalDOMWindow> m_window;
+};
 
 class PostMessageTimer final : public GarbageCollectedFinalized<PostMessageTimer>, public SuspendableTimer {
     USING_GARBAGE_COLLECTED_MIXIN(PostMessageTimer);
@@ -122,7 +136,7 @@
         InspectorInstrumentation::asyncTaskScheduled(window.document(), "postMessage", this);
     }
 
-    MessageEvent* event() const { return m_event.get(); }
+    MessageEvent* event() const { return m_event; }
     SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
     ScriptCallStack* stackTrace() const { return m_stackTrace.get(); }
     UserGestureToken* userGestureToken() const { return m_userGestureToken.get(); }
@@ -286,9 +300,6 @@
 LocalDOMWindow::LocalDOMWindow(LocalFrame& frame)
     : m_frameObserver(WindowFrameObserver::create(this, frame))
     , m_shouldPrintWhenFinishedLoading(false)
-#if ENABLE(ASSERT)
-    , m_hasBeenReset(false)
-#endif
 {
     ThreadState::current()->registerPreFinalizer(this);
 }
@@ -534,9 +545,6 @@
     m_media = nullptr;
     m_customElements = nullptr;
     m_applicationCache = nullptr;
-#if ENABLE(ASSERT)
-    m_hasBeenReset = true;
-#endif
 
     LocalDOMWindow::notifyContextDestroyed();
 }
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
index 765fc5fe..207635ef 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -207,29 +207,7 @@
     bool removeEventListenerInternal(const AtomicString& eventType, EventListener*, const EventListenerOptions&) override;
 
 private:
-    // Rather than simply inheriting LocalFrameLifecycleObserver like most other
-    // classes, LocalDOMWindow hides its LocalFrameLifecycleObserver with
-    // composition. This prevents conflicting overloads between DOMWindow, which
-    // has a frame() accessor that returns Frame* for bindings code, and
-    // LocalFrameLifecycleObserver, which has a frame() accessor that returns a
-    // LocalFrame*.
-    class WindowFrameObserver final : public GarbageCollected<WindowFrameObserver>, public LocalFrameLifecycleObserver {
-        USING_GARBAGE_COLLECTED_MIXIN(WindowFrameObserver);
-    public:
-        static WindowFrameObserver* create(LocalDOMWindow*, LocalFrame&);
-
-        DECLARE_VIRTUAL_TRACE();
-
-        // LocalFrameLifecycleObserver overrides:
-        void willDetachFrameHost() override;
-        void contextDestroyed() override;
-
-    private:
-        WindowFrameObserver(LocalDOMWindow*, LocalFrame&);
-
-        Member<LocalDOMWindow> m_window;
-    };
-    friend WTF::OwnedPtrDeleter<WindowFrameObserver>;
+    class WindowFrameObserver;
 
     explicit LocalDOMWindow(LocalFrame&);
     void dispose();
@@ -245,9 +223,6 @@
     Member<Document> m_document;
 
     bool m_shouldPrintWhenFinishedLoading;
-#if ENABLE(ASSERT)
-    bool m_hasBeenReset;
-#endif
 
     HeapHashSet<WeakMember<DOMWindowProperty>> m_properties;
 
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index 41a30a1..ef1a0ead 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -30,6 +30,7 @@
 #include "core/frame/LocalFrame.h"
 
 #include "bindings/core/v8/ScriptController.h"
+#include "core/InstrumentingAgents.h"
 #include "core/dom/DocumentType.h"
 #include "core/dom/StyleChangeReason.h"
 #include "core/editing/EditingUtilities.h"
@@ -51,7 +52,6 @@
 #include "core/input/EventHandler.h"
 #include "core/inspector/ConsoleMessageStorage.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/inspector/InspectorSession.h"
 #include "core/layout/HitTestResult.h"
 #include "core/layout/LayoutView.h"
 #include "core/layout/api/LayoutViewItem.h"
@@ -117,7 +117,7 @@
         AffineTransform transform;
         transform.scale(deviceScaleFactor, deviceScaleFactor);
         transform.translate(-m_bounds.x(), -m_bounds.y());
-        context().getPaintController().createAndAppend<BeginTransformDisplayItem>(*m_localFrame, transform);
+        context().getPaintController().createAndAppend<BeginTransformDisplayItem>(*m_pictureBuilder, transform);
     }
 
     GraphicsContext& context() { return m_pictureBuilder->context(); }
@@ -126,7 +126,7 @@
     {
         if (m_draggedNode && m_draggedNode->layoutObject())
             m_draggedNode->layoutObject()->updateDragState(false);
-        context().getPaintController().endItem<EndTransformDisplayItem>(*m_localFrame);
+        context().getPaintController().endItem<EndTransformDisplayItem>(*m_pictureBuilder);
         RefPtr<const SkPicture> recording = m_pictureBuilder->endRecording();
         RefPtr<SkImage> skImage = adoptRef(SkImage::NewFromPicture(recording.get(),
             SkISize::Make(m_bounds.width(), m_bounds.height()), nullptr, nullptr));
@@ -240,7 +240,7 @@
 
 DEFINE_TRACE(LocalFrame)
 {
-    visitor->trace(m_instrumentingSessions);
+    visitor->trace(m_instrumentingAgents);
     visitor->trace(m_loader);
     visitor->trace(m_navigationScheduler);
     visitor->trace(m_view);
@@ -786,9 +786,9 @@
     , m_serviceRegistry(serviceRegistry)
 {
     if (isLocalRoot())
-        m_instrumentingSessions = new InstrumentingSessions();
+        m_instrumentingAgents = new InstrumentingAgents();
     else
-        m_instrumentingSessions = localFrameRoot()->m_instrumentingSessions;
+        m_instrumentingAgents = localFrameRoot()->m_instrumentingAgents;
 }
 
 WebFrameScheduler* LocalFrame::frameScheduler()
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.h b/third_party/WebKit/Source/core/frame/LocalFrame.h
index eb05df2..2e24a55 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.h
@@ -33,13 +33,11 @@
 #include "core/frame/Frame.h"
 #include "core/frame/LocalFrameLifecycleNotifier.h"
 #include "core/frame/LocalFrameLifecycleObserver.h"
-#include "core/inspector/InstrumentingSessions.h"
 #include "core/loader/FrameLoader.h"
 #include "core/page/FrameTree.h"
 #include "core/paint/PaintPhase.h"
 #include "platform/Supplementable.h"
 #include "platform/graphics/ImageOrientation.h"
-#include "platform/graphics/paint/DisplayItem.h"
 #include "platform/heap/Handle.h"
 #include "platform/scroll/ScrollTypes.h"
 #include "wtf/HashSet.h"
@@ -62,6 +60,7 @@
 class InputMethodController;
 class IntPoint;
 class IntSize;
+class InstrumentingAgents;
 class LayoutViewItem;
 class LocalDOMWindow;
 class NavigationScheduler;
@@ -78,7 +77,7 @@
 class WebFrameScheduler;
 template <typename Strategy> class PositionWithAffinityTemplate;
 
-class CORE_EXPORT LocalFrame : public Frame, public LocalFrameLifecycleNotifier, public Supplementable<LocalFrame>, public DisplayItemClient {
+class CORE_EXPORT LocalFrame : public Frame, public LocalFrameLifecycleNotifier, public Supplementable<LocalFrame> {
     USING_GARBAGE_COLLECTED_MIXIN(LocalFrame);
 public:
     static LocalFrame* create(FrameLoaderClient*, FrameHost*, FrameOwner*, ServiceRegistry* = nullptr);
@@ -134,7 +133,7 @@
     // should be updated to avoid storing things on the main frame.
     LocalFrame* localFrameRoot();
 
-    InstrumentingSessions* instrumentingSessions() { return m_instrumentingSessions.get(); }
+    InstrumentingAgents* instrumentingAgents() { return m_instrumentingAgents.get(); }
 
     // ======== All public functions below this point are candidates to move out of LocalFrame into another class. ========
 
@@ -171,11 +170,6 @@
     bool shouldReuseDefaultView(const KURL&) const;
     void removeSpellingMarkersUnderWords(const Vector<String>& words);
 
-    // DisplayItemClient methods
-    String debugName() const final { return "LocalFrame"; }
-    // TODO(chrishtr): fix this.
-    LayoutRect visualRect() const override { return LayoutRect(); }
-
     bool shouldThrottleRendering() const;
 
     // Returns the frame scheduler, creating one if needed.
@@ -223,7 +217,7 @@
 
     bool m_inViewSourceMode;
 
-    Member<InstrumentingSessions> m_instrumentingSessions;
+    Member<InstrumentingAgents> m_instrumentingAgents;
 
     ServiceRegistry* const m_serviceRegistry;
 };
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp
index 62b9951b..e01e14f 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.cpp
+++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -740,12 +740,7 @@
 void UseCounter::countCrossOriginIframe(const Document& document, Feature feature)
 {
     Frame* frame = document.frame();
-    if (!frame)
-        return;
-    // Check to see if the frame can script into the top level document.
-    SecurityOrigin* securityOrigin = frame->securityContext()->getSecurityOrigin();
-    Frame* top = frame->tree().top();
-    if (top && !securityOrigin->canAccess(top->securityContext()->getSecurityOrigin()))
+    if (frame && frame->isCrossOrigin())
         count(frame, feature);
 }
 
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
index bbfbbe3..80ead25 100644
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
+++ b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
@@ -327,6 +327,10 @@
         && !client().isLegacyViewportType())
         return false;
 
+    // If we require same-origin, then check the origin.
+    if (enabled(IfSameOrigin) && client().isCrossOrigin())
+        return false;
+
     // If we require muted media and this is muted, then it is eligible.
     if (enabled(IfMuted))
         return client().muted();
@@ -394,6 +398,8 @@
         value |= IfMuted;
     if (mode.contains("-ifmobile"))
         value |= IfMobile;
+    if (mode.contains("-ifsameorigin"))
+        value |= IfSameOrigin;
     if (mode.contains("-playmuted"))
         value |= PlayMuted;
 
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h
index 890ee365..ea7a3ed9 100644
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h
+++ b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.h
@@ -124,6 +124,9 @@
         virtual PageVisibilityState pageVisibilityState() const = 0;
         virtual String autoplayExperimentMode() const = 0;
 
+        // Frame
+        virtual bool isCrossOrigin() const = 0;
+
         // LayoutObject
         virtual void setRequestPositionUpdates(bool) = 0;
         virtual IntRect absoluteBoundingBoxRect() const = 0;
@@ -182,9 +185,12 @@
         // Restrict gestureless autoplay to sites which contain the
         // viewport tag.
         IfMobile          = 1 << 6,
+        // Restrict gestureless autoplay to sites which are from the same origin
+        // as the top-level frame.
+        IfSameOrigin      = 1 << 7,
         // If gestureless autoplay is allowed, then mute the media before
         // starting to play.
-        PlayMuted         = 1 << 7,
+        PlayMuted         = 1 << 8,
     };
 
     DEFINE_INLINE_TRACE() { visitor->trace(m_client); }
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentTest.cpp b/third_party/WebKit/Source/core/html/AutoplayExperimentTest.cpp
index 7f92c66..57394e5 100644
--- a/third_party/WebKit/Source/core/html/AutoplayExperimentTest.cpp
+++ b/third_party/WebKit/Source/core/html/AutoplayExperimentTest.cpp
@@ -52,6 +52,8 @@
             .WillByDefault(Return(false));
         ON_CALL(*this, pageVisibilityState())
             .WillByDefault(Return(PageVisibilityStateVisible));
+        ON_CALL(*this, isCrossOrigin())
+            .WillByDefault(Return(false));
         ON_CALL(*this, absoluteBoundingBoxRect())
             .WillByDefault(Return(
                 IntRect(10, 10, 100, 100)));
@@ -85,6 +87,7 @@
     MOCK_METHOD0(isLegacyViewportType, bool());
     MOCK_CONST_METHOD0(pageVisibilityState, PageVisibilityState());
     MOCK_CONST_METHOD0(autoplayExperimentMode, String());
+    MOCK_CONST_METHOD0(isCrossOrigin, bool());
     MOCK_METHOD1(setRequestPositionUpdates, void(bool));
     MOCK_CONST_METHOD0(absoluteBoundingBoxRect, IntRect());
 
@@ -431,4 +434,23 @@
         .Times(1);
     moveIntoViewport();
 }
+
+TEST_F(AutoplayExperimentTest, WithSameOriginTests)
+{
+    setInterface(new NiceMock<MockAutoplayClient>("enabled-forvideo-ifsameorigin", MockAutoplayClient::Video));
+    ON_CALL(*m_client, isCrossOrigin()).WillByDefault(Return(false));
+    EXPECT_TRUE(isEligible());
+    ON_CALL(*m_client, isCrossOrigin()).WillByDefault(Return(true));
+    EXPECT_FALSE(isEligible());
+}
+
+TEST_F(AutoplayExperimentTest, WithoutSameOriginTests)
+{
+    setInterface(new NiceMock<MockAutoplayClient>("enabled-forvideo", MockAutoplayClient::Video));
+    ON_CALL(*m_client, isCrossOrigin()).WillByDefault(Return(false));
+    EXPECT_TRUE(isEligible());
+    ON_CALL(*m_client, isCrossOrigin()).WillByDefault(Return(true));
+    EXPECT_TRUE(isEligible());
+}
+
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 87b1339..0957206 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -317,6 +317,13 @@
     PageVisibilityState pageVisibilityState() const override;
     String autoplayExperimentMode() const override;
 
+    // Frame
+    bool isCrossOrigin() const override
+    {
+        const Frame* frame = m_element->document().frame();
+        return frame && frame->isCrossOrigin();
+    }
+
     // LayoutObject
     void setRequestPositionUpdates(bool) override;
     IntRect absoluteBoundingBoxRect() const override;
@@ -520,6 +527,7 @@
 void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& value)
 {
     if (name == srcAttr) {
+        WTF_LOG(Media, "HTMLMediaElement::parseAttribute(%p, srcAttr, old=%s, new=%s)", this, oldValue.utf8().data(), value.utf8().data());
         // Trigger a reload, as long as the 'src' attribute is present.
         if (!value.isNull()) {
             m_ignorePreloadNone = false;
@@ -659,6 +667,7 @@
 
 void HTMLMediaElement::setSrcObject(MediaStreamDescriptor* srcObject)
 {
+    WTF_LOG(Media, "HTMLMediaElement::setSrcObject(%p)", this);
     m_srcObject = srcObject;
     invokeLoadAlgorithm();
 }
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasDrawListener.h b/third_party/WebKit/Source/core/html/canvas/CanvasDrawListener.h
index 1fd851f..b03a04d 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasDrawListener.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasDrawListener.h
@@ -8,9 +8,10 @@
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
 #include "public/platform/WebCanvasCaptureHandler.h"
-#include "third_party/skia/include/core/SkImage.h"
 #include "wtf/PassRefPtr.h"
 
+class SkImage;
+
 namespace blink {
 
 class CORE_EXPORT CanvasDrawListener : public GarbageCollectedMixin {
diff --git a/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp b/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
index 15a5aaf..19e8b68 100644
--- a/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
@@ -27,8 +27,11 @@
 
 #include "core/html/parser/CSSPreloadScanner.h"
 
+#include "core/fetch/CSSStyleSheetResource.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
 #include "core/html/parser/HTMLParserIdioms.h"
+#include "core/html/parser/HTMLResourcePreloader.h"
+#include "platform/Histogram.h"
 #include "platform/text/SegmentedString.h"
 
 namespace blink {
@@ -233,4 +236,39 @@
     m_ruleValue.clear();
 }
 
+CSSPreloaderResourceClient::CSSPreloaderResourceClient(Resource* resource, HTMLResourcePreloader* preloader)
+    : m_resource(resource)
+    , m_preloader(preloader)
+{
+}
+
+void CSSPreloaderResourceClient::notifyFinished(Resource* resource)
+{
+    resource->removeClient(this);
+    m_resource.clear();
+}
+
+// Only attach for one appendData call, as that's where most imports will likely
+// be (according to spec).
+void CSSPreloaderResourceClient::didAppendFirstData(const CSSStyleSheetResource* resource)
+{
+    const String& chunk = resource->decodedText();
+    if (!chunk.isNull() && m_preloader) {
+        CSSPreloadScanner cssPreloadScanner;
+        PreloadRequestStream preloads;
+        // Passing an empty SegmentedString here results in PreloadRequests
+        // with no file/line information.
+        // TODO(csharrison): If this becomes an issue the CSSPreloadScanner
+        // may be augmented to take care of this case without performing an
+        // additional copy.
+        cssPreloadScanner.scan(chunk, SegmentedString(), preloads, resource->response().url());
+        int currentPreloadCount = m_preloader->countPreloads();
+        m_preloader->takeAndPreload(preloads);
+        DEFINE_STATIC_LOCAL(CustomCountHistogram, cssImportHistogram, ("PreloadScanner.ExternalCSS.PreloadCount", 1, 100, 50));
+        cssImportHistogram.count(m_preloader->countPreloads() - currentPreloadCount);
+    }
+    m_resource->removeClient(this);
+    m_resource.clear();
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h b/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
index b56ef88..9117b08 100644
--- a/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
+++ b/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
@@ -27,13 +27,15 @@
 #ifndef CSSPreloadScanner_h
 #define CSSPreloadScanner_h
 
-#include "core/html/parser/HTMLResourcePreloader.h"
+#include "core/fetch/StyleSheetResourceClient.h"
 #include "core/html/parser/HTMLToken.h"
+#include "core/html/parser/PreloadRequest.h"
 #include "wtf/text/StringBuilder.h"
 
 namespace blink {
 
 class SegmentedString;
+class HTMLResourcePreloader;
 
 class CSSPreloadScanner {
     DISALLOW_NEW();
@@ -80,6 +82,21 @@
     const KURL* m_predictedBaseElementURL = nullptr;
 };
 
+// Each CSSPreloaderResourceClient keeps track of a single CSS resource, and
+// drives a CSSPreloadScanner as raw data arrives for it. This lets us preload
+// @import tags before parsing.
+class CSSPreloaderResourceClient : public StyleSheetResourceClient {
+public:
+    CSSPreloaderResourceClient(Resource*, HTMLResourcePreloader*);
+    void notifyFinished(Resource*) override;
+    void didAppendFirstData(const CSSStyleSheetResource*) override;
+    String debugName() const override { return "CSSPreloaderResourceClient"; }
+
+private:
+    Persistent<Resource> m_resource;
+    WeakPersistent<HTMLResourcePreloader> m_preloader;
+};
+
 } // namespace blink
 
 #endif
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
index 4800977..ab53b92b 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -39,6 +39,7 @@
 #include "core/html/parser/BackgroundHTMLParser.h"
 #include "core/html/parser/HTMLParserScheduler.h"
 #include "core/html/parser/HTMLParserThread.h"
+#include "core/html/parser/HTMLResourcePreloader.h"
 #include "core/html/parser/HTMLScriptRunner.h"
 #include "core/html/parser/HTMLTreeBuilder.h"
 #include "core/inspector/InspectorInstrumentation.h"
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
index 01b52462..4c40ce1 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -44,6 +44,7 @@
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/html/parser/HTMLSrcsetParser.h"
 #include "core/html/parser/HTMLTokenizer.h"
+#include "core/html/parser/ResourcePreloader.h"
 #include "core/loader/LinkLoader.h"
 #include "platform/ContentType.h"
 #include "platform/Histogram.h"
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
index fbbe93b..eaa81cf5 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
+++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
@@ -42,6 +42,7 @@
 
 class HTMLParserOptions;
 class HTMLTokenizer;
+class ResourcePreloader;
 class SegmentedString;
 
 struct ViewportDescriptionWrapper {
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
index e29b24e..88bf5409 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
@@ -26,6 +26,7 @@
 #include "core/html/parser/HTMLResourcePreloader.h"
 
 #include "core/dom/Document.h"
+#include "core/fetch/CSSStyleSheetResource.h"
 #include "core/fetch/FetchInitiatorInfo.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/loader/DocumentLoader.h"
@@ -48,6 +49,13 @@
     visitor->trace(m_document);
 }
 
+int HTMLResourcePreloader::countPreloads()
+{
+    if (m_document->loader())
+        return m_document->loader()->fetcher()->countPreloads();
+    return 0;
+}
+
 static void preconnectHost(PreloadRequest* request, const NetworkHintsInterface& networkHintsInterface)
 {
     ASSERT(request);
@@ -75,7 +83,12 @@
     if (preload->resourceType() == Resource::Script || preload->resourceType() == Resource::CSSStyleSheet || preload->resourceType() == Resource::ImportResource)
         request.setCharset(preload->charset().isEmpty() ? m_document->characterSet().getString() : preload->charset());
     request.setForPreload(true);
-    m_document->loader()->startPreload(preload->resourceType(), request);
+    Resource* resource = m_document->loader()->startPreload(preload->resourceType(), request);
+    if (resource && preload->resourceType() == Resource::CSSStyleSheet && RuntimeEnabledFeatures::cssPreloadImportEnabled()) {
+        OwnPtr<CSSPreloaderResourceClient> client = adoptPtr(new CSSPreloaderResourceClient(resource, this));
+        resource->addClient(client.get());
+        m_cssPreloaders.add(client.release());
+    }
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
index 2d23e7e7..49b57dc 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
+++ b/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
@@ -28,6 +28,7 @@
 
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/Resource.h"
+#include "core/html/parser/CSSPreloadScanner.h"
 #include "core/html/parser/PreloadRequest.h"
 #include "core/html/parser/ResourcePreloader.h"
 #include "core/loader/NetworkHintsInterface.h"
@@ -35,11 +36,12 @@
 
 namespace blink {
 
-class CORE_EXPORT HTMLResourcePreloader final : public GarbageCollected<HTMLResourcePreloader>, public ResourcePreloader {
+class CORE_EXPORT HTMLResourcePreloader final : public GarbageCollectedFinalized<HTMLResourcePreloader>, public ResourcePreloader {
     WTF_MAKE_NONCOPYABLE(HTMLResourcePreloader);
     friend class HTMLResourcePreloaderTest;
 public:
     static HTMLResourcePreloader* create(Document&);
+    int countPreloads();
     DECLARE_TRACE();
 
 protected:
@@ -49,6 +51,7 @@
     explicit HTMLResourcePreloader(Document&);
 
     Member<Document> m_document;
+    HashSet<OwnPtr<CSSPreloaderResourceClient>> m_cssPreloaders;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/track/OWNERS b/third_party/WebKit/Source/core/html/track/OWNERS
index edf74539..b3ac5558 100644
--- a/third_party/WebKit/Source/core/html/track/OWNERS
+++ b/third_party/WebKit/Source/core/html/track/OWNERS
@@ -1,2 +1 @@
 fs@opera.com
-philipj@opera.com
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
index 7b3aea6..6c768b4b 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.h
@@ -40,7 +40,8 @@
 #include "core/imagebitmap/ImageBitmapOptions.h"
 #include "platform/Supplementable.h"
 #include "platform/geometry/IntRect.h"
-#include "third_party/skia/include/core/SkImage.h"
+
+class SkImage;
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py b/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
index 4065ddf..aa4a56f 100755
--- a/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
+++ b/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
@@ -71,16 +71,16 @@
 template_impl = string.Template("""
 ${return_type} ${name}(${params})
 {
-    InstrumentingSessions* sessions = ${sessions_getter};
-    if (!sessions || sessions->isEmpty())
-        ${default_return}
-    for (InspectorSession* session : *sessions) {${impl_lines}
-    }${maybe_default_return}
+    InstrumentingAgents* agents = instrumentingAgentsFor(${first_param_name});
+    if (!agents)
+        ${default_return}${impl_lines}${maybe_default_return}
 }""")
 
 template_agent_call = string.Template("""
-        if (${agent_class}* agent = session->instrumentingAgents()->${agent_getter}())
-            ${maybe_return}agent->${name}(${params_agent});""")
+    if (agents->has${agent_class}s()) {
+        for (${agent_class}* agent : agents->${agent_getter}s())
+            ${maybe_return}agent->${name}(${params_agent});
+    }""")
 
 template_instrumenting_agents_h = string.Template("""// Code generated from InspectorInstrumentation.idl
 
@@ -102,7 +102,6 @@
 public:
     InstrumentingAgents();
     DECLARE_TRACE();
-
 ${accessor_list}
 
 private:
@@ -115,15 +114,31 @@
 """)
 
 template_instrumenting_agent_accessor = string.Template("""
-    ${class_name}* ${getter_name}() const { return ${member_name}; }
-    void set${class_name}(${class_name}* agent) { ${member_name} = agent; }""")
+    bool has${class_name}s() const { return ${has_member_name}; }
+    const HeapHashSet<Member<${class_name}>>& ${getter_name}s() const { return ${member_name}; }
+    void add${class_name}(${class_name}* agent);
+    void remove${class_name}(${class_name}* agent);""")
+
+template_instrumenting_agent_impl = string.Template("""
+void InstrumentingAgents::add${class_name}(${class_name}* agent)
+{
+    ${member_name}.add(agent);
+    ${has_member_name} = true;
+}
+
+void InstrumentingAgents::remove${class_name}(${class_name}* agent)
+{
+    ${member_name}.remove(agent);
+    ${has_member_name} = !${member_name}.isEmpty();
+}
+""")
 
 template_instrumenting_agents_cpp = string.Template("""
 InstrumentingAgents::InstrumentingAgents()
     : $init_list
 {
 }
-
+${impl_list}
 DEFINE_TRACE(InstrumentingAgents)
 {
     $trace_list
@@ -233,8 +248,6 @@
             self.return_type, self.name, ", ".join(map(Parameter.to_str_class, self.params))))
 
     def generate_cpp(self, cpp_lines):
-        sessions_getter = "instrumentingSessionsFor(%s)" % self.params[0].name
-
         default_return = "return;"
         maybe_default_return = ""
         if self.returns_value:
@@ -252,7 +265,7 @@
             default_return=default_return,
             maybe_default_return=maybe_default_return,
             impl_lines="".join(body_lines),
-            sessions_getter=sessions_getter))
+            first_param_name=self.params[0].name))
 
     def generate_agent_call(self, agent):
         agent_class, agent_getter = agent_getter_signature(agent)
@@ -360,32 +373,36 @@
 
 def generate_instrumenting_agents(used_agents):
     agents = list(used_agents)
+    agents.sort()
 
     forward_list = []
     accessor_list = []
     member_list = []
     init_list = []
     trace_list = []
+    impl_list = []
 
     for agent in agents:
         class_name, getter_name = agent_getter_signature(agent)
-        member_name = "m_" + getter_name
+        member_name = "m_" + getter_name + "s"
+        has_member_name = "m_has" + class_name + "s"
 
         forward_list.append("class %s;" % class_name)
         accessor_list.append(template_instrumenting_agent_accessor.substitute(
             None,
             class_name=class_name,
             getter_name=getter_name,
-            member_name=member_name))
-        member_list.append("    Member<%s> %s;" % (class_name, member_name))
-        init_list.append("%s(nullptr)" % member_name)
+            member_name=member_name,
+            has_member_name=has_member_name))
+        member_list.append("    HeapHashSet<Member<%s>> %s;" % (class_name, member_name))
+        member_list.append("    bool %s;" % has_member_name)
+        init_list.append("%s(false)" % has_member_name)
         trace_list.append("visitor->trace(%s);" % member_name)
-
-    forward_list.sort()
-    accessor_list.sort()
-    member_list.sort()
-    init_list.sort()
-    trace_list.sort()
+        impl_list.append(template_instrumenting_agent_impl.substitute(
+            None,
+            class_name=class_name,
+            member_name=member_name,
+            has_member_name=has_member_name))
 
     header_lines = template_instrumenting_agents_h.substitute(
         None,
@@ -396,6 +413,7 @@
     cpp_lines = template_instrumenting_agents_cpp.substitute(
         None,
         init_list="\n    , ".join(init_list),
+        impl_list="".join(impl_list),
         trace_list="\n    ".join(trace_list))
 
     return header_lines, cpp_lines
@@ -420,7 +438,6 @@
         cpp_includes.append(include_inspector_header(agent_class_name(agent)))
     cpp_includes.append(include_header("InstrumentingAgents"))
     cpp_includes.append(include_header("core/CoreExport"))
-    cpp_includes.append(include_header("core/inspector/InspectorSession"))
     cpp_includes.sort()
 
     instrumenting_agents_header, instrumenting_agents_cpp = generate_instrumenting_agents(used_agents)
diff --git a/third_party/WebKit/Source/core/inspector/InspectedFrames.cpp b/third_party/WebKit/Source/core/inspector/InspectedFrames.cpp
index 63bcb99..dbf9886 100644
--- a/third_party/WebKit/Source/core/inspector/InspectedFrames.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectedFrames.cpp
@@ -26,7 +26,7 @@
 
 bool InspectedFrames::contains(LocalFrame* frame) const
 {
-    return frame->instrumentingSessions() == m_root->instrumentingSessions();
+    return frame->instrumentingAgents() == m_root->instrumentingAgents();
 }
 
 LocalFrame* InspectedFrames::frameWithSecurityOrigin(const String& originRawString)
@@ -54,7 +54,7 @@
         if (!frame->isLocalFrame())
             continue;
         LocalFrame* local = toLocalFrame(frame);
-        if (local->instrumentingSessions() == m_root->instrumentingSessions()) {
+        if (local->instrumentingAgents() == m_root->instrumentingAgents()) {
             m_current = local;
             break;
         }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
index 6a3ecbd..d80a4b63d 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
@@ -26,7 +26,7 @@
 #include "core/inspector/InspectorStyleSheet.h"
 #include "platform/Decimal.h"
 #include "platform/animation/TimingFunction.h"
-#include "platform/v8_inspector/public/V8RuntimeAgent.h"
+#include "platform/v8_inspector/public/V8InspectorSession.h"
 #include "wtf/text/Base64.h"
 
 namespace AnimationAgentState {
@@ -36,12 +36,12 @@
 
 namespace blink {
 
-InspectorAnimationAgent::InspectorAnimationAgent(InspectedFrames* inspectedFrames, InspectorDOMAgent* domAgent, InspectorCSSAgent* cssAgent, V8RuntimeAgent* runtimeAgent)
+InspectorAnimationAgent::InspectorAnimationAgent(InspectedFrames* inspectedFrames, InspectorDOMAgent* domAgent, InspectorCSSAgent* cssAgent, V8InspectorSession* v8Session)
     : InspectorBaseAgent<InspectorAnimationAgent, protocol::Frontend::Animation>("Animation")
     , m_inspectedFrames(inspectedFrames)
     , m_domAgent(domAgent)
     , m_cssAgent(cssAgent)
-    , m_runtimeAgent(runtimeAgent)
+    , m_v8Session(v8Session)
     , m_isCloning(false)
 {
 }
@@ -60,7 +60,7 @@
 void InspectorAnimationAgent::enable(ErrorString*)
 {
     m_state->setBoolean(AnimationAgentState::animationAgentEnabled, true);
-    m_instrumentingAgents->setInspectorAnimationAgent(this);
+    m_instrumentingAgents->addInspectorAnimationAgent(this);
 }
 
 void InspectorAnimationAgent::disable(ErrorString*)
@@ -69,7 +69,7 @@
     for (const auto& clone : m_idToAnimationClone.values())
         clone->cancel();
     m_state->setBoolean(AnimationAgentState::animationAgentEnabled, false);
-    m_instrumentingAgents->setInspectorAnimationAgent(nullptr);
+    m_instrumentingAgents->removeInspectorAnimationAgent(this);
     m_idToAnimation.clear();
     m_idToAnimationType.clear();
     m_idToAnimationClone.clear();
@@ -380,8 +380,8 @@
     }
 
     ScriptState::Scope scope(scriptState);
-    m_runtimeAgent->disposeObjectGroup("animation");
-    *result = m_runtimeAgent->wrapObject(scriptState->context(), toV8(animation, scriptState->context()->Global(), scriptState->isolate()), "animation");
+    m_v8Session->releaseObjectGroup("animation");
+    *result = m_v8Session->wrapObject(scriptState->context(), toV8(animation, scriptState->context()->Global(), scriptState->isolate()), "animation");
     if (!*result)
         *errorString = "Element not associated with a document.";
 }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h
index c278704..c562f63b 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.h
@@ -21,15 +21,12 @@
 class InspectorCSSAgent;
 class InspectorDOMAgent;
 class TimingFunction;
-class V8RuntimeAgent;
+class V8InspectorSession;
 
 class CORE_EXPORT InspectorAnimationAgent final : public InspectorBaseAgent<InspectorAnimationAgent, protocol::Frontend::Animation>, public protocol::Backend::Animation {
     WTF_MAKE_NONCOPYABLE(InspectorAnimationAgent);
 public:
-    static InspectorAnimationAgent* create(InspectedFrames* inspectedFrames, InspectorDOMAgent* domAgent, InspectorCSSAgent* cssAgent, V8RuntimeAgent* runtimeAgent)
-    {
-        return new InspectorAnimationAgent(inspectedFrames, domAgent, cssAgent, runtimeAgent);
-    }
+    InspectorAnimationAgent(InspectedFrames*, InspectorDOMAgent*, InspectorCSSAgent*, V8InspectorSession*);
 
     // Base agent methods.
     void restore() override;
@@ -58,8 +55,6 @@
     DECLARE_VIRTUAL_TRACE();
 
 private:
-    InspectorAnimationAgent(InspectedFrames*, InspectorDOMAgent*, InspectorCSSAgent*, V8RuntimeAgent*);
-
     using AnimationType = protocol::Animation::Animation::TypeEnum;
 
     PassOwnPtr<protocol::Animation::Animation> buildObjectForAnimation(blink::Animation&);
@@ -72,7 +67,7 @@
     Member<InspectedFrames> m_inspectedFrames;
     Member<InspectorDOMAgent> m_domAgent;
     Member<InspectorCSSAgent> m_cssAgent;
-    V8RuntimeAgent* m_runtimeAgent;
+    V8InspectorSession* m_v8Session;
     HeapHashMap<String, Member<blink::Animation>> m_idToAnimation;
     HeapHashMap<String, Member<blink::Animation>> m_idToAnimationClone;
     HashMap<String, String> m_idToAnimationType;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
index e916e33..af08d78 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
@@ -56,14 +56,14 @@
 void InspectorApplicationCacheAgent::enable(ErrorString*)
 {
     m_state->setBoolean(ApplicationCacheAgentState::applicationCacheAgentEnabled, true);
-    m_instrumentingAgents->setInspectorApplicationCacheAgent(this);
+    m_instrumentingAgents->addInspectorApplicationCacheAgent(this);
     frontend()->networkStateUpdated(networkStateNotifier().onLine());
 }
 
 void InspectorApplicationCacheAgent::disable(ErrorString*)
 {
     m_state->setBoolean(ApplicationCacheAgentState::applicationCacheAgentEnabled, false);
-    m_instrumentingAgents->setInspectorApplicationCacheAgent(nullptr);
+    m_instrumentingAgents->removeInspectorApplicationCacheAgent(this);
 }
 
 void InspectorApplicationCacheAgent::updateApplicationCacheStatus(LocalFrame* frame)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
index b41cbcf..6f8080d 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -683,7 +683,7 @@
         return;
     }
 
-    m_instrumentingAgents->setInspectorCSSAgent(this);
+    m_instrumentingAgents->addInspectorCSSAgent(this);
     m_domAgent->setDOMListener(this);
     HeapVector<Member<Document>> documents = m_domAgent->documents();
     for (Document* document : documents)
@@ -694,7 +694,7 @@
 {
     reset();
     m_domAgent->setDOMListener(nullptr);
-    m_instrumentingAgents->setInspectorCSSAgent(0);
+    m_instrumentingAgents->removeInspectorCSSAgent(this);
     m_state->setBoolean(CSSAgentState::cssAgentEnabled, false);
     m_resourceContentLoader->cancel(m_resourceContentLoaderClientId);
 }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp
index 86f6e06..b7098339 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp
@@ -31,7 +31,7 @@
 #include "core/inspector/ConsoleMessageStorage.h"
 #include "core/inspector/IdentifiersFactory.h"
 #include "core/inspector/ScriptArguments.h"
-#include "platform/v8_inspector/public/V8RuntimeAgent.h"
+#include "platform/v8_inspector/public/V8InspectorSession.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
@@ -40,9 +40,9 @@
 static const char consoleMessagesEnabled[] = "consoleMessagesEnabled";
 }
 
-InspectorConsoleAgent::InspectorConsoleAgent(V8RuntimeAgent* runtimeAgent)
+InspectorConsoleAgent::InspectorConsoleAgent(V8InspectorSession* v8Session)
     : InspectorBaseAgent<InspectorConsoleAgent, protocol::Frontend::Console>("Console")
-    , m_runtimeAgent(runtimeAgent)
+    , m_v8Session(v8Session)
     , m_enabled(false)
 {
 }
@@ -55,7 +55,7 @@
 {
     if (m_enabled)
         return;
-    m_instrumentingAgents->setInspectorConsoleAgent(this);
+    m_instrumentingAgents->addInspectorConsoleAgent(this);
     m_enabled = true;
     enableStackCapturingIfNeeded();
 
@@ -77,7 +77,7 @@
 {
     if (!m_enabled)
         return;
-    m_instrumentingAgents->setInspectorConsoleAgent(nullptr);
+    m_instrumentingAgents->removeInspectorConsoleAgent(this);
     m_enabled = false;
     disableStackCapturingIfNeeded();
 
@@ -100,7 +100,7 @@
 
 void InspectorConsoleAgent::consoleMessagesCleared()
 {
-    m_runtimeAgent->disposeObjectGroup("console");
+    m_v8Session->releaseObjectGroup("console");
     frontend()->messagesCleared();
 }
 
@@ -184,14 +184,14 @@
         if (consoleMessage->type() == TableMessageType && generatePreview) {
             v8::Local<v8::Value> table = arguments->argumentAt(0).v8Value();
             v8::Local<v8::Value> columns = arguments->argumentCount() > 1 ? arguments->argumentAt(1).v8Value() : v8::Local<v8::Value>();
-            OwnPtr<protocol::Runtime::RemoteObject> inspectorValue = m_runtimeAgent->wrapTable(context, table, columns);
+            OwnPtr<protocol::Runtime::RemoteObject> inspectorValue = m_v8Session->wrapTable(context, table, columns);
             if (inspectorValue)
                 jsonArgs->addItem(inspectorValue.release());
             else
                 jsonArgs = nullptr;
         } else {
             for (unsigned i = 0; i < arguments->argumentCount(); ++i) {
-                OwnPtr<protocol::Runtime::RemoteObject> inspectorValue = m_runtimeAgent->wrapObject(context, arguments->argumentAt(i).v8Value(), "console", generatePreview);
+                OwnPtr<protocol::Runtime::RemoteObject> inspectorValue = m_v8Session->wrapObject(context, arguments->argumentAt(i).v8Value(), "console", generatePreview);
                 if (!inspectorValue) {
                     jsonArgs = nullptr;
                     break;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h b/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h
index c63eade..5587c46 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h
@@ -34,12 +34,11 @@
 
 class ConsoleMessage;
 class ConsoleMessageStorage;
-class V8RuntimeAgent;
+class V8InspectorSession;
 
 class CORE_EXPORT InspectorConsoleAgent : public InspectorBaseAgent<InspectorConsoleAgent, protocol::Frontend::Console>, public protocol::Backend::Console {
     WTF_MAKE_NONCOPYABLE(InspectorConsoleAgent);
 public:
-    InspectorConsoleAgent(V8RuntimeAgent*);
     ~InspectorConsoleAgent() override;
 
     void enable(ErrorString*) override;
@@ -52,13 +51,14 @@
     virtual void consoleMessagesCleared();
 
 protected:
+    explicit InspectorConsoleAgent(V8InspectorSession*);
     void sendConsoleMessageToFrontend(ConsoleMessage*, bool generatePreview);
     virtual ConsoleMessageStorage* messageStorage() = 0;
 
     virtual void enableStackCapturingIfNeeded() = 0;
     virtual void disableStackCapturingIfNeeded() = 0;
 
-    V8RuntimeAgent* m_runtimeAgent;
+    V8InspectorSession* m_v8Session;
     bool m_enabled;
 };
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index 8812e24d..16a0517b 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -78,7 +78,7 @@
 #include "platform/PlatformGestureEvent.h"
 #include "platform/PlatformMouseEvent.h"
 #include "platform/PlatformTouchEvent.h"
-#include "platform/v8_inspector/public/V8RuntimeAgent.h"
+#include "platform/v8_inspector/public/V8InspectorSession.h"
 #include "wtf/ListHashSet.h"
 #include "wtf/text/CString.h"
 #include "wtf/text/WTFString.h"
@@ -243,11 +243,11 @@
     }
 }
 
-InspectorDOMAgent::InspectorDOMAgent(v8::Isolate* isolate, InspectedFrames* inspectedFrames, V8RuntimeAgent* runtimeAgent, Client* client)
+InspectorDOMAgent::InspectorDOMAgent(v8::Isolate* isolate, InspectedFrames* inspectedFrames, V8InspectorSession* v8Session, Client* client)
     : InspectorBaseAgent<InspectorDOMAgent, protocol::Frontend::DOM>("DOM")
     , m_isolate(isolate)
     , m_inspectedFrames(inspectedFrames)
-    , m_runtimeAgent(runtimeAgent)
+    , m_v8Session(v8Session)
     , m_client(client)
     , m_domListener(nullptr)
     , m_documentNodeToIdMap(new NodeToIdMap())
@@ -483,7 +483,7 @@
     m_history = new InspectorHistory();
     m_domEditor = new DOMEditor(m_history.get());
     m_document = m_inspectedFrames->root()->document();
-    m_instrumentingAgents->setInspectorDOMAgent(this);
+    m_instrumentingAgents->addInspectorDOMAgent(this);
     if (m_backendNodeIdToInspect)
         frontend()->inspectNodeRequested(m_backendNodeIdToInspect);
     m_backendNodeIdToInspect = 0;
@@ -510,7 +510,7 @@
     }
     m_state->setBoolean(DOMAgentState::domAgentEnabled, false);
     setSearchingForNode(errorString, NotSearching, Maybe<protocol::DOM::HighlightConfig>());
-    m_instrumentingAgents->setInspectorDOMAgent(nullptr);
+    m_instrumentingAgents->removeInspectorDOMAgent(this);
     m_history.clear();
     m_domEditor.clear();
     setDocument(nullptr);
@@ -1167,7 +1167,7 @@
 Node* InspectorDOMAgent::nodeForRemoteId(ErrorString* errorString, const String& objectId)
 {
     v8::HandleScope handles(m_isolate);
-    v8::Local<v8::Value> value = m_runtimeAgent->findObject(errorString, objectId);
+    v8::Local<v8::Value> value = m_v8Session->findObject(errorString, objectId);
     if (value.IsEmpty()) {
         *errorString = "Node for given objectId not found";
         return nullptr;
@@ -1997,7 +1997,7 @@
     }
 }
 
-class InspectableNode final : public V8RuntimeAgent::Inspectable {
+class InspectableNode final : public V8InspectorSession::Inspectable {
 public:
     explicit InspectableNode(Node* node) : m_nodeId(DOMNodeIds::idForNode(node)) { }
 
@@ -2014,7 +2014,7 @@
     Node* node = assertNode(errorString, nodeId);
     if (!node)
         return;
-    m_runtimeAgent->addInspectedObject(adoptPtr(new InspectableNode(node)));
+    m_v8Session->addInspectedObject(adoptPtr(new InspectableNode(node)));
     if (m_client)
         m_client->setInspectedNode(node);
 }
@@ -2056,7 +2056,7 @@
         return nullptr;
 
     ScriptState::Scope scope(scriptState);
-    return m_runtimeAgent->wrapObject(scriptState->context(), nodeV8Value(scriptState->context(), node), objectGroup);
+    return m_v8Session->wrapObject(scriptState->context(), nodeV8Value(scriptState->context(), node), objectGroup);
 }
 
 bool InspectorDOMAgent::pushDocumentUponHandlelessOperation(ErrorString* errorString)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
index 2bfea6f..6e069e8 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
@@ -37,7 +37,7 @@
 #include "core/style/ComputedStyleConstants.h"
 #include "platform/geometry/FloatQuad.h"
 #include "platform/inspector_protocol/Values.h"
-#include "platform/v8_inspector/public/V8RuntimeAgent.h"
+#include "platform/v8_inspector/public/V8InspectorSession.h"
 
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
@@ -94,15 +94,11 @@
         virtual void setInspectedNode(Node*) { }
     };
 
-    static InspectorDOMAgent* create(v8::Isolate* isolate, InspectedFrames* inspectedFrames, V8RuntimeAgent* runtimeAgent, Client* client)
-    {
-        return new InspectorDOMAgent(isolate, inspectedFrames, runtimeAgent, client);
-    }
-
     static String toErrorString(ExceptionState&);
     static bool getPseudoElementType(PseudoId, String*);
     static ShadowRoot* userAgentShadowRoot(Node*);
 
+    InspectorDOMAgent(v8::Isolate*, InspectedFrames*, V8InspectorSession*, Client*);
     ~InspectorDOMAgent() override;
     DECLARE_VIRTUAL_TRACE();
 
@@ -200,8 +196,6 @@
     Document* assertDocument(ErrorString*, int nodeId);
 
 private:
-    InspectorDOMAgent(v8::Isolate*, InspectedFrames*, V8RuntimeAgent*, Client*);
-
     void setDocument(Document*);
     void innerEnable();
 
@@ -242,7 +236,7 @@
 
     v8::Isolate* m_isolate;
     Member<InspectedFrames> m_inspectedFrames;
-    V8RuntimeAgent* m_runtimeAgent;
+    V8InspectorSession* m_v8Session;
     Client* m_client;
     Member<DOMListener> m_domListener;
     Member<NodeToIdMap> m_documentNodeToIdMap;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
index add15bb..743c452 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
@@ -41,7 +41,6 @@
 #include "platform/inspector_protocol/Values.h"
 #include "platform/v8_inspector/public/V8EventListenerInfo.h"
 #include "platform/v8_inspector/public/V8InspectorSession.h"
-#include "platform/v8_inspector/public/V8RuntimeAgent.h"
 
 namespace {
 
@@ -112,11 +111,10 @@
     }
 }
 
-InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(v8::Isolate* isolate, InspectorDOMAgent* domAgent, V8RuntimeAgent* runtimeAgent, V8InspectorSession* v8Session)
+InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(v8::Isolate* isolate, InspectorDOMAgent* domAgent, V8InspectorSession* v8Session)
     : InspectorBaseAgent<InspectorDOMDebuggerAgent, protocol::Frontend::DOMDebugger>("DOMDebugger")
     , m_isolate(isolate)
     , m_domAgent(domAgent)
-    , m_runtimeAgent(runtimeAgent)
     , m_v8Session(v8Session)
 {
 }
@@ -144,7 +142,7 @@
 void InspectorDOMDebuggerAgent::restore()
 {
     if (m_state->booleanProperty(DOMDebuggerAgentState::enabled, false))
-        m_instrumentingAgents->setInspectorDOMDebuggerAgent(this);
+        m_instrumentingAgents->addInspectorDOMDebuggerAgent(this);
 }
 
 void InspectorDOMDebuggerAgent::setEventListenerBreakpoint(ErrorString* error, const String& eventName, const Maybe<String>& targetName)
@@ -339,7 +337,7 @@
 
     v8::Local<v8::Context> context;
     String16 objectGroup;
-    v8::Local<v8::Value> value = m_runtimeAgent->findObject(errorString, objectId, &context, &objectGroup);
+    v8::Local<v8::Value> value = m_v8Session->findObject(errorString, objectId, &context, &objectGroup);
     if (value.IsEmpty())
         return;
     v8::Context::Scope scope(context);
@@ -392,8 +390,8 @@
         .setPassive(info.passive)
         .setLocation(location.release()).build();
     if (!objectGroupId.isEmpty()) {
-        value->setHandler(m_runtimeAgent->wrapObject(context, function, objectGroupId));
-        value->setOriginalHandler(m_runtimeAgent->wrapObject(context, info.handler, objectGroupId));
+        value->setHandler(m_v8Session->wrapObject(context, function, objectGroupId));
+        value->setOriginalHandler(m_v8Session->wrapObject(context, info.handler, objectGroupId));
     }
     return value.release();
 }
@@ -621,11 +619,11 @@
 void InspectorDOMDebuggerAgent::setEnabled(bool enabled)
 {
     if (enabled) {
-        m_instrumentingAgents->setInspectorDOMDebuggerAgent(this);
+        m_instrumentingAgents->addInspectorDOMDebuggerAgent(this);
         m_state->setBoolean(DOMDebuggerAgentState::enabled, true);
     } else {
         m_state->remove(DOMDebuggerAgentState::enabled);
-        m_instrumentingAgents->setInspectorDOMDebuggerAgent(nullptr);
+        m_instrumentingAgents->removeInspectorDOMDebuggerAgent(this);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
index 82ff766b7..4582713 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
@@ -48,7 +48,6 @@
 class InspectorDOMAgent;
 class Node;
 class V8InspectorSession;
-class V8RuntimeAgent;
 
 namespace protocol {
 class DictionaryValue;
@@ -61,7 +60,7 @@
 public:
     static void eventListenersInfoForTarget(v8::Isolate*, v8::Local<v8::Value>, V8EventListenerInfoList& listeners);
 
-    InspectorDOMDebuggerAgent(v8::Isolate*, InspectorDOMAgent*, V8RuntimeAgent*, V8InspectorSession*);
+    InspectorDOMDebuggerAgent(v8::Isolate*, InspectorDOMAgent*, V8InspectorSession*);
     ~InspectorDOMDebuggerAgent() override;
     DECLARE_VIRTUAL_TRACE();
 
@@ -116,7 +115,6 @@
 
     v8::Isolate* m_isolate;
     Member<InspectorDOMAgent> m_domAgent;
-    V8RuntimeAgent* m_runtimeAgent;
     V8InspectorSession* m_v8Session;
     HeapHashMap<Member<Node>, uint32_t> m_domBreakpoints;
 };
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
index 83795ea..288a75a 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
@@ -53,10 +53,10 @@
 
 namespace {
 
-PersistentHeapHashSet<WeakMember<InstrumentingSessions>>& instrumentingSessionsSet()
+PersistentHeapHashSet<WeakMember<InstrumentingAgents>>& instrumentingAgentsSet()
 {
-    DEFINE_STATIC_LOCAL(PersistentHeapHashSet<WeakMember<InstrumentingSessions>>, instrumentingSessionsSet, ());
-    return instrumentingSessionsSet;
+    DEFINE_STATIC_LOCAL(PersistentHeapHashSet<WeakMember<InstrumentingAgents>>, instrumentingAgentsSet, ());
+    return instrumentingAgentsSet;
 }
 
 }
@@ -68,96 +68,84 @@
 }
 
 AsyncTask::AsyncTask(ExecutionContext* context, void* task, bool enabled)
-    : m_instrumentingSessions(enabled ? instrumentingSessionsFor(context) : nullptr)
+    : m_instrumentingAgents(enabled ? instrumentingAgentsFor(context) : nullptr)
     , m_task(task)
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents || !m_instrumentingAgents->hasInspectorSessions())
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorSession())
-            session->instrumentingAgents()->inspectorSession()->asyncTaskStarted(m_task);
-    }
+    for (InspectorSession* session : m_instrumentingAgents->inspectorSessions())
+        session->asyncTaskStarted(m_task);
 }
 
 AsyncTask::~AsyncTask()
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents || !m_instrumentingAgents->hasInspectorSessions())
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorSession())
-            session->instrumentingAgents()->inspectorSession()->asyncTaskFinished(m_task);
-    }
+    for (InspectorSession* session : m_instrumentingAgents->inspectorSessions())
+        session->asyncTaskFinished(m_task);
 }
 
 NativeBreakpoint::NativeBreakpoint(ExecutionContext* context, const String& name, bool sync)
-    : m_instrumentingSessions(instrumentingSessionsFor(context))
+    : m_instrumentingAgents(instrumentingAgentsFor(context))
     , m_sync(sync)
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents || !m_instrumentingAgents->hasInspectorDOMDebuggerAgents())
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorDOMDebuggerAgent())
-            session->instrumentingAgents()->inspectorDOMDebuggerAgent()->allowNativeBreakpoint(name, nullptr, m_sync);
-    }
+    for (InspectorDOMDebuggerAgent* domDebuggerAgent : m_instrumentingAgents->inspectorDOMDebuggerAgents())
+        domDebuggerAgent->allowNativeBreakpoint(name, nullptr, m_sync);
 }
 
 NativeBreakpoint::NativeBreakpoint(ExecutionContext* context, EventTarget* eventTarget, Event* event)
-    : m_instrumentingSessions(instrumentingSessionsFor(context))
+    : m_instrumentingAgents(instrumentingAgentsFor(context))
     , m_sync(false)
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents || !m_instrumentingAgents->hasInspectorDOMDebuggerAgents())
         return;
     Node* node = eventTarget->toNode();
     String targetName = node ? node->nodeName() : eventTarget->interfaceName();
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorDOMDebuggerAgent())
-            session->instrumentingAgents()->inspectorDOMDebuggerAgent()->allowNativeBreakpoint(event->type(), &targetName, m_sync);
-    }
+    for (InspectorDOMDebuggerAgent* domDebuggerAgent : m_instrumentingAgents->inspectorDOMDebuggerAgents())
+        domDebuggerAgent->allowNativeBreakpoint(event->type(), &targetName, m_sync);
 }
 
 NativeBreakpoint::~NativeBreakpoint()
 {
-    if (m_sync || !m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (m_sync || !m_instrumentingAgents || !m_instrumentingAgents->hasInspectorDOMDebuggerAgents())
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorDOMDebuggerAgent())
-            session->instrumentingAgents()->inspectorDOMDebuggerAgent()->cancelNativeBreakpoint();
-    }
+    for (InspectorDOMDebuggerAgent* domDebuggerAgent : m_instrumentingAgents->inspectorDOMDebuggerAgents())
+        domDebuggerAgent->cancelNativeBreakpoint();
 }
 
 StyleRecalc::StyleRecalc(Document* document)
-    : m_instrumentingSessions(instrumentingSessionsFor(document))
+    : m_instrumentingAgents(instrumentingAgentsFor(document))
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents || m_instrumentingAgents->hasInspectorResourceAgents())
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorResourceAgent())
-            session->instrumentingAgents()->inspectorResourceAgent()->willRecalculateStyle(document);
-    }
+    for (InspectorResourceAgent* resourceAgent : m_instrumentingAgents->inspectorResourceAgents())
+        resourceAgent->willRecalculateStyle(document);
 }
 
 StyleRecalc::~StyleRecalc()
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents)
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorResourceAgent())
-            session->instrumentingAgents()->inspectorResourceAgent()->didRecalculateStyle();
-        if (session->instrumentingAgents()->inspectorPageAgent())
-            session->instrumentingAgents()->inspectorPageAgent()->didRecalculateStyle();
+    if (m_instrumentingAgents->hasInspectorResourceAgents()) {
+        for (InspectorResourceAgent* resourceAgent : m_instrumentingAgents->inspectorResourceAgents())
+            resourceAgent->didRecalculateStyle();
+    }
+    if (m_instrumentingAgents->hasInspectorPageAgents()) {
+        for (InspectorPageAgent* pageAgent : m_instrumentingAgents->inspectorPageAgents())
+            pageAgent->didRecalculateStyle();
     }
 }
 
 JavaScriptDialog::JavaScriptDialog(LocalFrame* frame, const String& message, ChromeClient::DialogType dialogType)
-    : m_instrumentingSessions(instrumentingSessionsFor(frame))
+    : m_instrumentingAgents(instrumentingAgentsFor(frame))
     , m_result(false)
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents || !m_instrumentingAgents->hasInspectorPageAgents())
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorPageAgent())
-            session->instrumentingAgents()->inspectorPageAgent()->willRunJavaScriptDialog(message, dialogType);
-    }
+    for (InspectorPageAgent* pageAgent : m_instrumentingAgents->inspectorPageAgents())
+        pageAgent->willRunJavaScriptDialog(message, dialogType);
 }
 
 void JavaScriptDialog::setResult(bool result)
@@ -167,12 +155,10 @@
 
 JavaScriptDialog::~JavaScriptDialog()
 {
-    if (!m_instrumentingSessions || m_instrumentingSessions->isEmpty())
+    if (!m_instrumentingAgents || !m_instrumentingAgents->hasInspectorPageAgents())
         return;
-    for (InspectorSession* session : *m_instrumentingSessions) {
-        if (session->instrumentingAgents()->inspectorPageAgent())
-            session->instrumentingAgents()->inspectorPageAgent()->didRunJavaScriptDialog(m_result);
-    }
+    for (InspectorPageAgent* pageAgent : m_instrumentingAgents->inspectorPageAgents())
+        pageAgent->didRunJavaScriptDialog(m_result);
 }
 
 int FrontendCounter::s_frontendCounter = 0;
@@ -203,66 +189,62 @@
 void removedResourceFromMemoryCache(Resource* cachedResource)
 {
     ASSERT(isMainThread());
-    for (InstrumentingSessions* instrumentingSessions: instrumentingSessionsSet()) {
-        if (instrumentingSessions->isEmpty())
+    for (InstrumentingAgents* instrumentingAgents: instrumentingAgentsSet()) {
+        if (!instrumentingAgents->hasInspectorResourceAgents())
             continue;
-        for (InspectorSession* session : *instrumentingSessions) {
-            if (InspectorResourceAgent* inspectorResourceAgent = session->instrumentingAgents()->inspectorResourceAgent())
-                inspectorResourceAgent->removedResourceFromMemoryCache(cachedResource);
-        }
+        for (InspectorResourceAgent* resourceAgent : instrumentingAgents->inspectorResourceAgents())
+            resourceAgent->removedResourceFromMemoryCache(cachedResource);
     }
 }
 
 bool collectingHTMLParseErrors(Document* document)
 {
     ASSERT(isMainThread());
-    if (InstrumentingSessions* instrumentingSessions = instrumentingSessionsFor(document))
-        return instrumentingSessionsSet().contains(instrumentingSessions);
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(document))
+        return instrumentingAgentsSet().contains(instrumentingAgents);
     return false;
 }
 
 bool consoleAgentEnabled(ExecutionContext* executionContext)
 {
-    InstrumentingSessions* instrumentingSessions = instrumentingSessionsFor(executionContext);
-    if (!instrumentingSessions || instrumentingSessions->isEmpty())
+    InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(executionContext);
+    if (!instrumentingAgents || !instrumentingAgents->hasInspectorConsoleAgents())
         return false;
-    for (InspectorSession* session : *instrumentingSessions) {
-        if (InspectorConsoleAgent* consoleAgent = session->instrumentingAgents()->inspectorConsoleAgent()) {
-            if (consoleAgent->enabled())
-                return true;
-        }
+    for (InspectorConsoleAgent* consoleAgent: instrumentingAgents->inspectorConsoleAgents()) {
+        if (consoleAgent->enabled())
+            return true;
     }
     return false;
 }
 
-void registerInstrumentingSessions(InstrumentingSessions* instrumentingSessions)
+void registerInstrumentingAgents(InstrumentingAgents* instrumentingAgents)
 {
     ASSERT(isMainThread());
-    instrumentingSessionsSet().add(instrumentingSessions);
+    instrumentingAgentsSet().add(instrumentingAgents);
 }
 
-void unregisterInstrumentingSessions(InstrumentingSessions* instrumentingSessions)
+void unregisterInstrumentingAgents(InstrumentingAgents* instrumentingAgents)
 {
     ASSERT(isMainThread());
-    ASSERT(instrumentingSessionsSet().contains(instrumentingSessions));
-    instrumentingSessionsSet().remove(instrumentingSessions);
+    ASSERT(instrumentingAgentsSet().contains(instrumentingAgents));
+    instrumentingAgentsSet().remove(instrumentingAgents);
 }
 
-InstrumentingSessions* instrumentingSessionsFor(WorkerGlobalScope* workerGlobalScope)
+InstrumentingAgents* instrumentingAgentsFor(WorkerGlobalScope* workerGlobalScope)
 {
     if (!workerGlobalScope)
         return nullptr;
     if (WorkerInspectorController* controller = workerGlobalScope->workerInspectorController())
-        return controller->instrumentingSessions();
+        return controller->instrumentingAgents();
     return nullptr;
 }
 
-InstrumentingSessions* instrumentingSessionsForNonDocumentContext(ExecutionContext* context)
+InstrumentingAgents* instrumentingAgentsForNonDocumentContext(ExecutionContext* context)
 {
     if (context->isWorkerGlobalScope())
-        return instrumentingSessionsFor(toWorkerGlobalScope(context));
+        return instrumentingAgentsFor(toWorkerGlobalScope(context));
     if (context->isWorkletGlobalScope())
-        return instrumentingSessionsFor(toMainThreadWorkletGlobalScope(context)->frame());
+        return instrumentingAgentsFor(toMainThreadWorkletGlobalScope(context)->frame());
     return nullptr;
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h
index e4e8c84..33d82cf 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h
@@ -35,11 +35,11 @@
 #include "core/dom/Document.h"
 #include "core/dom/Node.h"
 #include "core/frame/LocalFrame.h"
-#include "core/inspector/InstrumentingSessions.h"
 #include "core/page/ChromeClient.h"
 
 namespace blink {
 
+class InstrumentingAgents;
 class WorkerGlobalScope;
 
 namespace InspectorInstrumentation {
@@ -52,7 +52,7 @@
     ~AsyncTask();
 
 private:
-    Member<InstrumentingSessions> m_instrumentingSessions;
+    Member<InstrumentingAgents> m_instrumentingAgents;
     void* m_task;
 };
 
@@ -64,7 +64,7 @@
     ~NativeBreakpoint();
 
 private:
-    Member<InstrumentingSessions> m_instrumentingSessions;
+    Member<InstrumentingAgents> m_instrumentingAgents;
     bool m_sync;
 };
 
@@ -74,7 +74,7 @@
     StyleRecalc(Document*);
     ~StyleRecalc();
 private:
-    Member<InstrumentingSessions> m_instrumentingSessions;
+    Member<InstrumentingAgents> m_instrumentingAgents;
 };
 
 class CORE_EXPORT JavaScriptDialog {
@@ -84,7 +84,7 @@
     void setResult(bool);
     ~JavaScriptDialog();
 private:
-    Member<InstrumentingSessions> m_instrumentingSessions;
+    Member<InstrumentingAgents> m_instrumentingAgents;
     bool m_result;
 };
 
@@ -101,48 +101,48 @@
 inline void frontendDeleted() { atomicDecrement(&FrontendCounter::s_frontendCounter); }
 inline bool hasFrontends() { return acquireLoad(&FrontendCounter::s_frontendCounter); }
 
-CORE_EXPORT void registerInstrumentingSessions(InstrumentingSessions*);
-CORE_EXPORT void unregisterInstrumentingSessions(InstrumentingSessions*);
+CORE_EXPORT void registerInstrumentingAgents(InstrumentingAgents*);
+CORE_EXPORT void unregisterInstrumentingAgents(InstrumentingAgents*);
 
 CORE_EXPORT extern const char kInspectorEmulateNetworkConditionsClientId[];
 
 // Called from generated instrumentation code.
-CORE_EXPORT InstrumentingSessions* instrumentingSessionsFor(WorkerGlobalScope*);
-CORE_EXPORT InstrumentingSessions* instrumentingSessionsForNonDocumentContext(ExecutionContext*);
+CORE_EXPORT InstrumentingAgents* instrumentingAgentsFor(WorkerGlobalScope*);
+CORE_EXPORT InstrumentingAgents* instrumentingAgentsForNonDocumentContext(ExecutionContext*);
 
-inline InstrumentingSessions* instrumentingSessionsFor(LocalFrame* frame)
+inline InstrumentingAgents* instrumentingAgentsFor(LocalFrame* frame)
 {
-    return frame ? frame->instrumentingSessions() : nullptr;
+    return frame ? frame->instrumentingAgents() : nullptr;
 }
 
-inline InstrumentingSessions* instrumentingSessionsFor(Document& document)
+inline InstrumentingAgents* instrumentingAgentsFor(Document& document)
 {
     LocalFrame* frame = document.frame();
     if (!frame && document.templateDocumentHost())
         frame = document.templateDocumentHost()->frame();
-    return instrumentingSessionsFor(frame);
+    return instrumentingAgentsFor(frame);
 }
 
-inline InstrumentingSessions* instrumentingSessionsFor(Document* document)
+inline InstrumentingAgents* instrumentingAgentsFor(Document* document)
 {
-    return document ? instrumentingSessionsFor(*document) : nullptr;
+    return document ? instrumentingAgentsFor(*document) : nullptr;
 }
 
-inline InstrumentingSessions* instrumentingSessionsFor(ExecutionContext* context)
+inline InstrumentingAgents* instrumentingAgentsFor(ExecutionContext* context)
 {
     if (!context)
         return nullptr;
-    return context->isDocument() ? instrumentingSessionsFor(*toDocument(context)) : instrumentingSessionsForNonDocumentContext(context);
+    return context->isDocument() ? instrumentingAgentsFor(*toDocument(context)) : instrumentingAgentsForNonDocumentContext(context);
 }
 
-inline InstrumentingSessions* instrumentingSessionsFor(Node* node)
+inline InstrumentingAgents* instrumentingAgentsFor(Node* node)
 {
-    return node ? instrumentingSessionsFor(node->document()) : nullptr;
+    return node ? instrumentingAgentsFor(node->document()) : nullptr;
 }
 
-inline InstrumentingSessions* instrumentingSessionsFor(EventTarget* eventTarget)
+inline InstrumentingAgents* instrumentingAgentsFor(EventTarget* eventTarget)
 {
-    return eventTarget ? instrumentingSessionsFor(eventTarget->getExecutionContext()) : nullptr;
+    return eventTarget ? instrumentingAgentsFor(eventTarget->getExecutionContext()) : nullptr;
 }
 
 } // namespace InspectorInstrumentation
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
index 8bc834ab..33a91929 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -171,7 +171,7 @@
 
 void InspectorLayerTreeAgent::enable(ErrorString*)
 {
-    m_instrumentingAgents->setInspectorLayerTreeAgent(this);
+    m_instrumentingAgents->addInspectorLayerTreeAgent(this);
     Document* document = m_inspectedFrames->root()->document();
     if (document && document->lifecycle().state() >= DocumentLifecycle::CompositingClean)
         layerTreeDidChange();
@@ -179,7 +179,7 @@
 
 void InspectorLayerTreeAgent::disable(ErrorString*)
 {
-    m_instrumentingAgents->setInspectorLayerTreeAgent(0);
+    m_instrumentingAgents->removeInspectorLayerTreeAgent(this);
     m_snapshotById.clear();
     ErrorString unused;
 }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
index c4f685f..0861831 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -369,7 +369,7 @@
 {
     m_enabled = true;
     m_state->setBoolean(PageAgentState::pageAgentEnabled, true);
-    m_instrumentingAgents->setInspectorPageAgent(this);
+    m_instrumentingAgents->addInspectorPageAgent(this);
 }
 
 void InspectorPageAgent::disable(ErrorString*)
@@ -379,7 +379,7 @@
     m_state->remove(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
     m_scriptToEvaluateOnLoadOnce = String();
     m_pendingScriptToEvaluateOnLoadOnce = String();
-    m_instrumentingAgents->setInspectorPageAgent(0);
+    m_instrumentingAgents->removeInspectorPageAgent(this);
     m_inspectorResourceContentLoader->cancel(m_resourceContentLoaderClientId);
 
     stopScreencast(0);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
index 5e2c53b0..795bb92 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
@@ -900,7 +900,7 @@
     m_state->setBoolean(ResourceAgentState::resourceAgentEnabled, true);
     m_state->setNumber(ResourceAgentState::totalBufferSize, totalBufferSize);
     m_state->setNumber(ResourceAgentState::resourceBufferSize, resourceBufferSize);
-    m_instrumentingAgents->setInspectorResourceAgent(this);
+    m_instrumentingAgents->addInspectorResourceAgent(this);
 }
 
 void InspectorResourceAgent::disable(ErrorString*)
@@ -908,7 +908,7 @@
     ASSERT(!m_pendingRequest);
     m_state->setBoolean(ResourceAgentState::resourceAgentEnabled, false);
     m_state->setString(ResourceAgentState::userAgentOverride, "");
-    m_instrumentingAgents->setInspectorResourceAgent(0);
+    m_instrumentingAgents->removeInspectorResourceAgent(this);
     m_resourcesData->clear();
     m_knownRequestIdMap.clear();
 }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorSession.cpp b/third_party/WebKit/Source/core/inspector/InspectorSession.cpp
index 43b349d9..587a916 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorSession.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorSession.cpp
@@ -5,7 +5,6 @@
 #include "core/inspector/InspectorSession.h"
 
 #include "bindings/core/v8/ScriptController.h"
-#include "core/InstrumentingAgents.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
 #include "core/inspector/InspectedFrames.h"
@@ -21,14 +20,14 @@
 
 namespace blink {
 
-InspectorSession::InspectorSession(Client* client, InspectedFrames* inspectedFrames, int sessionId, bool autoFlush)
+InspectorSession::InspectorSession(Client* client, InspectedFrames* inspectedFrames, InstrumentingAgents* instrumentingAgents, int sessionId, bool autoFlush)
     : m_client(client)
     , m_v8Session(nullptr)
     , m_sessionId(sessionId)
     , m_autoFlush(autoFlush)
     , m_attached(false)
     , m_inspectedFrames(inspectedFrames)
-    , m_instrumentingAgents(new InstrumentingAgents())
+    , m_instrumentingAgents(instrumentingAgents)
     , m_inspectorFrontend(adoptPtr(new protocol::Frontend(this)))
     , m_inspectorBackendDispatcher(protocol::Dispatcher::create(this))
 {
@@ -220,14 +219,14 @@
 void InspectorSession::startInstrumenting()
 {
     ASSERT(!isInstrumenting());
-    m_instrumentingAgents->setInspectorSession(this);
+    m_instrumentingAgents->addInspectorSession(this);
     forceContextsInAllFrames();
 }
 
 void InspectorSession::stopInstrumenting()
 {
     ASSERT(isInstrumenting());
-    m_instrumentingAgents->setInspectorSession(nullptr);
+    m_instrumentingAgents->removeInspectorSession(this);
 }
 
 void InspectorSession::forceContextsInAllFrames()
@@ -243,7 +242,7 @@
 #if ENABLE(ASSERT)
 bool InspectorSession::isInstrumenting()
 {
-    return m_instrumentingAgents->inspectorSession() == this;
+    return m_instrumentingAgents->inspectorSessions().contains(this);
 }
 #endif
 
diff --git a/third_party/WebKit/Source/core/inspector/InspectorSession.h b/third_party/WebKit/Source/core/inspector/InspectorSession.h
index 7688829..28b8ff2 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorSession.h
+++ b/third_party/WebKit/Source/core/inspector/InspectorSession.h
@@ -38,9 +38,8 @@
         virtual ~Client() {}
     };
 
-    InspectorSession(Client*, InspectedFrames*, int sessionId, bool autoFlush);
+    InspectorSession(Client*, InspectedFrames*, InstrumentingAgents*, int sessionId, bool autoFlush);
     int sessionId() { return m_sessionId; }
-    InstrumentingAgents* instrumentingAgents() { return m_instrumentingAgents.get(); }
 
     void append(InspectorAgent*);
     void attach(V8InspectorSession*, const String* savedState);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
index d5615589..3bd8ca0 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
@@ -65,7 +65,7 @@
 {
     if (!enabled())
         return;
-    m_instrumentingAgents->setInspectorWorkerAgent(this);
+    m_instrumentingAgents->addInspectorWorkerAgent(this);
     connectToAllProxies();
 }
 
@@ -74,7 +74,7 @@
     if (enabled())
         return;
     m_state->setBoolean(WorkerAgentState::workerInspectionEnabled, true);
-    m_instrumentingAgents->setInspectorWorkerAgent(this);
+    m_instrumentingAgents->addInspectorWorkerAgent(this);
     connectToAllProxies();
 }
 
@@ -84,7 +84,7 @@
         return;
     m_state->setBoolean(WorkerAgentState::workerInspectionEnabled, false);
     m_state->setBoolean(WorkerAgentState::waitForDebuggerOnStart, false);
-    m_instrumentingAgents->setInspectorWorkerAgent(nullptr);
+    m_instrumentingAgents->removeInspectorWorkerAgent(this);
     for (auto& idProxy : m_connectedProxies)
         idProxy.value->disconnectFromInspector(this);
     m_connectedProxies.clear();
diff --git a/third_party/WebKit/Source/core/inspector/InstrumentingSessions.h b/third_party/WebKit/Source/core/inspector/InstrumentingSessions.h
deleted file mode 100644
index cd7d3b3..0000000
--- a/third_party/WebKit/Source/core/inspector/InstrumentingSessions.h
+++ /dev/null
@@ -1,18 +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 InstrumentingSessions_h
-#define InstrumentingSessions_h
-
-#include "platform/heap/Handle.h"
-#include "wtf/HashSet.h"
-
-namespace blink {
-
-class InspectorSession;
-using InstrumentingSessions = HeapHashSet<Member<InspectorSession>>;
-
-} // namespace blink
-
-#endif // !defined(InstrumentingSessions_h)
diff --git a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp
index e2aaf7c44..1191466 100644
--- a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp
@@ -45,8 +45,8 @@
 
 int PageConsoleAgent::s_enabledAgentCount = 0;
 
-PageConsoleAgent::PageConsoleAgent(V8RuntimeAgent* runtimeAgent, InspectorDOMAgent* domAgent, InspectedFrames* inspectedFrames)
-    : InspectorConsoleAgent(runtimeAgent)
+PageConsoleAgent::PageConsoleAgent(V8InspectorSession* v8Session, InspectorDOMAgent* domAgent, InspectedFrames* inspectedFrames)
+    : InspectorConsoleAgent(v8Session)
     , m_inspectorDOMAgent(domAgent)
     , m_inspectedFrames(inspectedFrames)
 {
@@ -68,12 +68,12 @@
 {
     InspectorConsoleAgent::enable(errorString);
     m_workersWithEnabledConsole.clear();
-    m_instrumentingAgents->setPageConsoleAgent(this);
+    m_instrumentingAgents->addPageConsoleAgent(this);
 }
 
 void PageConsoleAgent::disable(ErrorString* errorString)
 {
-    m_instrumentingAgents->setPageConsoleAgent(nullptr);
+    m_instrumentingAgents->removePageConsoleAgent(this);
     InspectorConsoleAgent::disable(errorString);
     m_workersWithEnabledConsole.clear();
 }
diff --git a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h
index 1fe4e41..666eb8a 100644
--- a/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h
+++ b/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h
@@ -47,10 +47,7 @@
 class CORE_EXPORT PageConsoleAgent final : public InspectorConsoleAgent {
     WTF_MAKE_NONCOPYABLE(PageConsoleAgent);
 public:
-    static PageConsoleAgent* create(V8RuntimeAgent* runtimeAgent, InspectorDOMAgent* domAgent, InspectedFrames* inspectedFrames)
-    {
-        return new PageConsoleAgent(runtimeAgent, domAgent, inspectedFrames);
-    }
+    PageConsoleAgent(V8InspectorSession*, InspectorDOMAgent*, InspectedFrames*);
     ~PageConsoleAgent() override;
     DECLARE_VIRTUAL_TRACE();
 
@@ -69,7 +66,6 @@
     void disableStackCapturingIfNeeded() override;
 
 private:
-    PageConsoleAgent(V8RuntimeAgent*, InspectorDOMAgent*, InspectedFrames*);
     void clearMessages(ErrorString*) override;
 
     Member<InspectorDOMAgent> m_inspectorDOMAgent;
diff --git a/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp b/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp
index ce789006..1bb13c0 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp
@@ -38,8 +38,8 @@
 
 namespace blink {
 
-WorkerConsoleAgent::WorkerConsoleAgent(V8RuntimeAgent* runtimeAgent, WorkerGlobalScope* workerGlobalScope)
-    : InspectorConsoleAgent(runtimeAgent)
+WorkerConsoleAgent::WorkerConsoleAgent(V8InspectorSession* v8Session, WorkerGlobalScope* workerGlobalScope)
+    : InspectorConsoleAgent(v8Session)
     , m_workerGlobalScope(workerGlobalScope)
 {
 }
diff --git a/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h b/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h
index 74bf170..309f9736 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h
+++ b/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h
@@ -41,10 +41,7 @@
 class WorkerConsoleAgent final : public InspectorConsoleAgent {
     WTF_MAKE_NONCOPYABLE(WorkerConsoleAgent);
 public:
-    static WorkerConsoleAgent* create(V8RuntimeAgent* runtimeAgent, WorkerGlobalScope* workerGlobalScope)
-    {
-        return new WorkerConsoleAgent(runtimeAgent, workerGlobalScope);
-    }
+    WorkerConsoleAgent(V8InspectorSession*, WorkerGlobalScope*);
     ~WorkerConsoleAgent() override;
     DECLARE_VIRTUAL_TRACE();
 
@@ -58,8 +55,6 @@
     void disableStackCapturingIfNeeded() override;
 
 private:
-    WorkerConsoleAgent(V8RuntimeAgent*, WorkerGlobalScope*);
-
     Member<WorkerGlobalScope> m_workerGlobalScope;
 };
 
diff --git a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
index 91001cbe..3922f60 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
+++ b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
@@ -30,11 +30,11 @@
 
 #include "core/inspector/WorkerInspectorController.h"
 
+#include "core/InstrumentingAgents.h"
 #include "core/inspector/InspectorConsoleAgent.h"
 #include "core/inspector/InspectorHeapProfilerAgent.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/inspector/InspectorProfilerAgent.h"
-#include "core/inspector/InspectorTaskRunner.h"
 #include "core/inspector/WorkerConsoleAgent.h"
 #include "core/inspector/WorkerDebuggerAgent.h"
 #include "core/inspector/WorkerRuntimeAgent.h"
@@ -60,7 +60,7 @@
 WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope* workerGlobalScope, WorkerThreadDebugger* debugger)
     : m_debugger(debugger)
     , m_workerGlobalScope(workerGlobalScope)
-    , m_instrumentingSessions(new InstrumentingSessions())
+    , m_instrumentingAgents(new InstrumentingAgents())
 {
 }
 
@@ -74,16 +74,15 @@
         return;
 
     // sessionId will be overwritten by WebDevToolsAgent::sendProtocolNotifications call.
-    m_session = new InspectorSession(this, nullptr, 0, true /* autoFlush */);
+    m_session = new InspectorSession(this, nullptr, m_instrumentingAgents.get(), 0, true /* autoFlush */);
     m_v8Session = m_debugger->debugger()->connect(m_debugger->contextGroupId());
 
     m_session->append(WorkerRuntimeAgent::create(m_v8Session->runtimeAgent(), m_workerGlobalScope, this));
     m_session->append(WorkerDebuggerAgent::create(m_v8Session->debuggerAgent(), m_workerGlobalScope));
     m_session->append(InspectorProfilerAgent::create(m_v8Session->profilerAgent(), nullptr));
     m_session->append(InspectorHeapProfilerAgent::create(m_v8Session->heapProfilerAgent()));
-    m_session->append(WorkerConsoleAgent::create(m_v8Session->runtimeAgent(), m_workerGlobalScope));
+    m_session->append(new WorkerConsoleAgent(m_v8Session.get(), m_workerGlobalScope));
 
-    m_instrumentingSessions->add(m_session);
     m_session->attach(m_v8Session.get(), nullptr);
 }
 
@@ -92,7 +91,6 @@
     if (!m_session)
         return;
     m_session->detach();
-    m_instrumentingSessions->remove(m_session);
     m_v8Session.clear();
     m_session.clear();
 }
@@ -122,7 +120,7 @@
 DEFINE_TRACE(WorkerInspectorController)
 {
     visitor->trace(m_workerGlobalScope);
-    visitor->trace(m_instrumentingSessions);
+    visitor->trace(m_instrumentingAgents);
     visitor->trace(m_session);
 }
 
diff --git a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h
index d7532d9..95dc8a4 100644
--- a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h
+++ b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.h
@@ -34,7 +34,6 @@
 #include "core/inspector/InspectorRuntimeAgent.h"
 #include "core/inspector/InspectorSession.h"
 #include "core/inspector/InspectorTaskRunner.h"
-#include "core/inspector/InstrumentingSessions.h"
 #include "wtf/Allocator.h"
 #include "wtf/Forward.h"
 #include "wtf/Noncopyable.h"
@@ -62,7 +61,7 @@
     ~WorkerInspectorController();
     DECLARE_TRACE();
 
-    InstrumentingSessions* instrumentingSessions() const { return m_instrumentingSessions.get(); }
+    InstrumentingAgents* instrumentingAgents() const { return m_instrumentingAgents.get(); }
 
     void connectFrontend();
     void disconnectFrontend();
@@ -80,7 +79,7 @@
 
     WorkerThreadDebugger* m_debugger;
     Member<WorkerGlobalScope> m_workerGlobalScope;
-    Member<InstrumentingSessions> m_instrumentingSessions;
+    Member<InstrumentingAgents> m_instrumentingAgents;
     OwnPtr<V8InspectorSession> m_v8Session;
     Member<InspectorSession> m_session;
 };
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index 375d4a4..3e1360d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -367,9 +367,6 @@
     if (shouldClipOverflow != hasOverflowClip()) {
         if (!shouldClipOverflow)
             getScrollableArea()->invalidateAllStickyConstraints();
-
-        // FIXME: This shouldn't be required if we tracked the visual overflow
-        // generated by positioned children or self painting layers. crbug.com/345403
         for (LayoutObject* child = firstChild(); child; child = child->nextSibling())
             child->setMayNeedPaintInvalidation();
     }
@@ -983,7 +980,7 @@
 
     IntRect inflatedRect = pixelSnappedBorderBoxRect();
     LayoutTheme::theme().addVisualOverflow(*this, inflatedRect);
-    addVisualOverflow(LayoutRect(inflatedRect));
+    addSelfVisualOverflow(LayoutRect(inflatedRect));
 }
 
 bool LayoutBlock::createsNewFormattingContext() const
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
index ec62c97..24d2466 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -1825,7 +1825,11 @@
     // See if any floats end in the range along which we want to shift the lines vertically.
     LayoutUnit logicalTop = std::min(logicalHeight(), layoutState.endLineLogicalTop());
 
-    LayoutUnit logicalBottom = lastRootBox()->lineBottomWithLeading() + absoluteValue(lineDelta);
+    RootInlineBox* lastLine = layoutState.endLine();
+    while (RootInlineBox* nextLine = lastLine->nextRootBox())
+        lastLine = nextLine;
+
+    LayoutUnit logicalBottom = lastLine->lineBottomWithLeading() + absoluteValue(lineDelta);
 
     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
     FloatingObjectSetIterator end = floatingObjectSet.end();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index ffbe2f1..70e2509 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -4013,7 +4013,7 @@
     // Add in the final overflow with shadows, outsets and outline combined.
     LayoutRect visualEffectOverflow = borderBoxRect();
     visualEffectOverflow.expand(computeVisualEffectOverflowOutsets());
-    addVisualOverflow(visualEffectOverflow);
+    addSelfVisualOverflow(visualEffectOverflow);
 }
 
 LayoutRectOutsets LayoutBox::computeVisualEffectOverflowOutsets() const
@@ -4086,8 +4086,11 @@
 
 void LayoutBox::addLayoutOverflow(const LayoutRect& rect)
 {
+    if (rect.isEmpty())
+        return;
+
     LayoutRect clientBox = noOverflowRect();
-    if (clientBox.contains(rect) || rect.isEmpty())
+    if (clientBox.contains(rect))
         return;
 
     // For overflow clip objects, we don't want to propagate overflow into unreachable areas.
@@ -4122,32 +4125,40 @@
     }
 
     if (!m_overflow)
-        m_overflow = adoptPtr(new OverflowModel(clientBox, borderBoxRect()));
+        m_overflow = adoptPtr(new BoxOverflowModel(clientBox, borderBoxRect()));
 
     m_overflow->addLayoutOverflow(overflowRect);
 }
 
-void LayoutBox::addVisualOverflow(const LayoutRect& rect)
+void LayoutBox::addSelfVisualOverflow(const LayoutRect& rect)
 {
+    if (rect.isEmpty())
+        return;
+
     LayoutRect borderBox = borderBoxRect();
-    if (borderBox.contains(rect) || rect.isEmpty())
+    if (borderBox.contains(rect))
         return;
 
     if (!m_overflow)
-        m_overflow = adoptPtr(new OverflowModel(noOverflowRect(), borderBox));
+        m_overflow = adoptPtr(new BoxOverflowModel(noOverflowRect(), borderBox));
 
-    m_overflow->addVisualOverflow(rect);
+    m_overflow->addSelfVisualOverflow(rect);
 }
 
 void LayoutBox::addContentsVisualOverflow(const LayoutRect& rect)
 {
-    if (!hasOverflowClip()) {
-        addVisualOverflow(rect);
+    if (rect.isEmpty())
         return;
-    }
+
+    // If hasOverflowClip() we always save contents visual overflow because we need it
+    // e.g. to determine whether to apply rounded corner clip on contents.
+    // Otherwise we save contents visual overflow only if it overflows the border box.
+    LayoutRect borderBox = borderBoxRect();
+    if (!hasOverflowClip() && borderBox.contains(rect))
+        return;
 
     if (!m_overflow)
-        m_overflow = adoptPtr(new OverflowModel(noOverflowRect(), borderBoxRect()));
+        m_overflow = adoptPtr(new BoxOverflowModel(noOverflowRect(), borderBox));
     m_overflow->addContentsVisualOverflow(rect);
 }
 
@@ -4156,7 +4167,7 @@
     if (!m_overflow)
         return;
 
-    if (!hasVisualOverflow() && contentsVisualOverflowRect().isEmpty()) {
+    if (!hasSelfVisualOverflow() && contentsVisualOverflowRect().isEmpty()) {
         clearAllOverflows();
         return;
     }
@@ -4384,6 +4395,16 @@
     return rect;
 }
 
+LayoutRect LayoutBox::visualOverflowRect() const
+{
+    if (!m_overflow)
+        return borderBoxRect();
+    if (hasOverflowClip())
+        return m_overflow->selfVisualOverflowRect();
+    // TODO(wangxianzhu): We should use normal unionRect() which ignores empty rects.
+    return unionRectEvenIfEmpty(m_overflow->selfVisualOverflowRect(), m_overflow->contentsVisualOverflowRect());
+}
+
 LayoutUnit LayoutBox::offsetLeft() const
 {
     return adjustedPositionRelativeToOffsetParent(topLeftLocation()).x();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h
index 05af5b1..f4f09e0 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -373,16 +373,15 @@
     LayoutUnit logicalLeftLayoutOverflow() const { return style()->isHorizontalWritingMode() ? layoutOverflowRect().x() : layoutOverflowRect().y(); }
     LayoutUnit logicalRightLayoutOverflow() const { return style()->isHorizontalWritingMode() ? layoutOverflowRect().maxX() : layoutOverflowRect().maxY(); }
 
-    LayoutRect visualOverflowRect() const override { return m_overflow ? m_overflow->visualOverflowRect() : borderBoxRect(); }
+    LayoutRect visualOverflowRect() const override;
     LayoutUnit logicalLeftVisualOverflow() const { return style()->isHorizontalWritingMode() ? visualOverflowRect().x() : visualOverflowRect().y(); }
     LayoutUnit logicalRightVisualOverflow() const { return style()->isHorizontalWritingMode() ? visualOverflowRect().maxX() : visualOverflowRect().maxY(); }
 
+    LayoutRect selfVisualOverflowRect() const { return m_overflow ? m_overflow->selfVisualOverflowRect() : borderBoxRect(); }
     LayoutRect contentsVisualOverflowRect() const { return m_overflow ? m_overflow->contentsVisualOverflowRect() : LayoutRect(); }
 
     void addLayoutOverflow(const LayoutRect&);
-    void addVisualOverflow(const LayoutRect&);
-
-    // Clipped by the contents clip, if one exists.
+    void addSelfVisualOverflow(const LayoutRect&);
     void addContentsVisualOverflow(const LayoutRect&);
 
     void addVisualEffectOverflow();
@@ -853,7 +852,8 @@
     LayoutRect layoutOverflowRectForPropagation(const ComputedStyle&) const;
 
     bool hasOverflowModel() const { return m_overflow.get(); }
-    bool hasVisualOverflow() const { return m_overflow && !borderBoxRect().contains(m_overflow->visualOverflowRect()); }
+    bool hasSelfVisualOverflow() const { return m_overflow && !borderBoxRect().contains(m_overflow->selfVisualOverflowRect()); }
+    bool hasVisualOverflow() const { return m_overflow && !borderBoxRect().contains(visualOverflowRect()); }
 
     virtual bool needsPreferredWidthsRecalculation() const;
 
@@ -1075,7 +1075,7 @@
     LayoutUnit m_maxPreferredLogicalWidth;
 
     // Our overflow information.
-    OwnPtr<OverflowModel> m_overflow;
+    OwnPtr<BoxOverflowModel> m_overflow;
 
 private:
     // The inline box containing this LayoutBox, for atomic inline elements.
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
index 1476461..bfad057 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
@@ -436,8 +436,7 @@
         overflowRect.unite(rect);
     }
     addLayoutOverflow(overflowRect);
-    if (!hasOverflowClip())
-        addVisualOverflow(overflowRect);
+    addContentsVisualOverflow(overflowRect);
 }
 
 void LayoutMultiColumnSet::insertedIntoTree()
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp
index b67e840..7b46b2a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSpannerPlaceholder.cpp
@@ -105,7 +105,7 @@
     // Take the overflow from the spanner, so that it gets
     // propagated to the multicol container and beyond.
     m_overflow.clear();
-    addVisualOverflow(m_layoutObjectInFlowThread->visualOverflowRect());
+    addContentsVisualOverflow(m_layoutObjectInFlowThread->visualOverflowRect());
     addLayoutOverflow(m_layoutObjectInFlowThread->layoutOverflowRect());
 
     clearNeedsLayout();
diff --git a/third_party/WebKit/Source/core/layout/LayoutReplica.cpp b/third_party/WebKit/Source/core/layout/LayoutReplica.cpp
index c484f150..de5fc7c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutReplica.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutReplica.cpp
@@ -56,7 +56,7 @@
 void LayoutReplica::layout()
 {
     setFrameRect(parentBox()->borderBoxRect());
-    addVisualOverflow(parentBox()->visualOverflowRect());
+    addSelfVisualOverflow(parentBox()->visualOverflowRect());
     updateLayerTransformAfterLayout();
     clearNeedsLayout();
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 09029ec3..134171a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -653,7 +653,7 @@
         if (borderOverflowRect != pixelSnappedBorderBoxRect()) {
             LayoutRect borderLayoutRect(borderOverflowRect);
             addLayoutOverflow(borderLayoutRect);
-            addVisualOverflow(borderLayoutRect);
+            addContentsVisualOverflow(borderLayoutRect);
         }
     }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
index 3f7335a2..1dbe48f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
@@ -261,7 +261,7 @@
     LayoutUnit cellOffsetLogicalTopDifference = cell->location().y() - location().y();
     cellVisualOverflowRect.move(LayoutUnit(), cellOffsetLogicalTopDifference);
 
-    addVisualOverflow(cellVisualOverflowRect);
+    addContentsVisualOverflow(cellVisualOverflowRect);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/OWNERS b/third_party/WebKit/Source/core/layout/OWNERS
index ef47915..068d3cf 100644
--- a/third_party/WebKit/Source/core/layout/OWNERS
+++ b/third_party/WebKit/Source/core/layout/OWNERS
@@ -12,7 +12,6 @@
 mstensho@opera.com
 ojan@chromium.org
 pdr@chromium.org
-philipj@opera.com
 rob.buis@samsung.com
 schenney@chromium.org
 senorblanco@chromium.org
diff --git a/third_party/WebKit/Source/core/layout/OverflowModel.h b/third_party/WebKit/Source/core/layout/OverflowModel.h
index 08a8215..318fbfb 100644
--- a/third_party/WebKit/Source/core/layout/OverflowModel.h
+++ b/third_party/WebKit/Source/core/layout/OverflowModel.h
@@ -25,16 +25,34 @@
 
 namespace blink {
 
-// OverflowModel is a class for tracking content that spills out of an object.
-// This class is used by LayoutBox and InlineFlowBox.
+inline void uniteLayoutOverflowRect(LayoutRect& layoutOverflow, const LayoutRect& rect)
+{
+    LayoutUnit maxX = std::max(rect.maxX(), layoutOverflow.maxX());
+    LayoutUnit maxY = std::max(rect.maxY(), layoutOverflow.maxY());
+    LayoutUnit minX = std::min(rect.x(), layoutOverflow.x());
+    LayoutUnit minY = std::min(rect.y(), layoutOverflow.y());
+    // In case the width/height is larger than LayoutUnit can represent, fix the right/bottom edge and shift the top/left ones.
+    layoutOverflow.setWidth(maxX - minX);
+    layoutOverflow.setHeight(maxY - minY);
+    layoutOverflow.setX(maxX - layoutOverflow.width());
+    layoutOverflow.setY(maxY - layoutOverflow.height());
+}
+
+// OverflowModel classes track content that spills out of an object.
+// SimpleOverflowModel is used by InlineFlowBox, and BoxOverflowModel is
+// used by LayoutBox.
 //
-// There are 3 types of overflows that we store: layout, visual overflow and
-// content visual overflows.
-// All overflows are in logical coordinates.
+// SimpleOverflowModel tracks 2 types of overflows: layout and visual
+// overflows. BoxOverflowModel separates visual overflow into self visual
+// overflow and contents visual overflow.
 //
-// This class models the overflows as rectangles that unite all the sources of
+// All overflows are in the coordinate space of the object (i.e. physical
+// coordinates with flipped block-flow direction). See documentation of
+// LayoutBoxModelObject and LayoutBox::noOverflowRect() for more details.
+//
+// The classes model the overflows as rectangles that unite all the sources of
 // overflow. This is the natural choice for layout overflow (scrollbars are
-// linear in nature, thus are modelled by rectangles in 2D). For visual overflow
+// linear in nature, thus are modeled by rectangles in 2D). For visual overflow
 // and content visual overflow, this is a first order simplification though as
 // they can be thought of as a collection of (potentially overlapping)
 // rectangles.
@@ -53,8 +71,48 @@
 //
 // Visual overflow covers all the effects that visually bleed out of the box.
 // Its primary use is to determine the area to invalidate.
-// Visual overflow includes shadows ('text-shadow' / 'box-shadow'), text stroke,
-// 'outline' and 'border-image'.
+// Visual overflow includes ('text-shadow' / 'box-shadow'), text stroke,
+// 'outline', 'border-image', etc.
+//
+// An overflow model object is allocated only when some of these fields have
+// non-default values in the owning object. Care should be taken to use adder
+// functions (addLayoutOverflow, addVisualOverflow, etc.) to keep this invariant.
+
+class SimpleOverflowModel {
+    WTF_MAKE_NONCOPYABLE(SimpleOverflowModel);
+    USING_FAST_MALLOC(SimpleOverflowModel);
+public:
+    SimpleOverflowModel(const LayoutRect& layoutRect, const LayoutRect& visualRect)
+        : m_layoutOverflow(layoutRect)
+        , m_visualOverflow(visualRect)
+    {
+    }
+
+    const LayoutRect& layoutOverflowRect() const { return m_layoutOverflow; }
+    void setLayoutOverflow(const LayoutRect& rect) { m_layoutOverflow = rect; }
+    void addLayoutOverflow(const LayoutRect& rect) { uniteLayoutOverflowRect(m_layoutOverflow, rect); }
+
+    const LayoutRect& visualOverflowRect() const { return m_visualOverflow; }
+    void setVisualOverflow(const LayoutRect& rect) { m_visualOverflow = rect; }
+    // TODO(wangxianzhu): Should use normal LayoutRect::unite() which ignores empty rects.
+    void addVisualOverflow(const LayoutRect& rect) { m_visualOverflow.uniteEvenIfEmpty(rect); }
+
+    void move(LayoutUnit dx, LayoutUnit dy)
+    {
+        m_layoutOverflow.move(dx, dy);
+        m_visualOverflow.move(dx, dy);
+    }
+
+private:
+    LayoutRect m_layoutOverflow;
+    LayoutRect m_visualOverflow;
+};
+
+// BoxModelOverflow tracks overflows of a LayoutBox. It separates visual overflow
+// into self visual overflow and contents visual overflow.
+//
+// Self visual overflow covers all the effects of the object itself that visually
+// bleed out of the box.
 //
 // Content visual overflow includes anything that would bleed out of the box and
 // would be clipped by the overflow clip ('overflow' != visible). This
@@ -70,89 +128,49 @@
 // self-painting layer is handled by PaintLayerPainter, which relies on
 // PaintLayerClipper and thus ignores this optimization.
 //
-// This object is allocated only when some of these fields have non-default
-// values in the owning box. Care should be taken to use LayoutBox adder
-// functions (addLayoutOverflow, addVisualOverflow, addContentsVisualOverflow)
-// to keep this invariant.
-class OverflowModel {
-    WTF_MAKE_NONCOPYABLE(OverflowModel);
-    USING_FAST_MALLOC(OverflowModel);
+// Visual overflow covers self visual overflow, and if the box doesn't clip
+// overflow, also content visual overflow. OverflowModel doesn't keep visual
+// overflow, but keeps self visual overflow and contents visual overflow
+// separately. The box should use self visual overflow as visual overflow if
+// it clips overflow, otherwise union of self visual overflow and contents
+// visual overflow.
+
+class BoxOverflowModel {
 public:
-    OverflowModel(const LayoutRect& layoutRect, const LayoutRect& visualRect)
+    BoxOverflowModel(const LayoutRect& layoutRect, const LayoutRect& selfVisualOverflowRect)
         : m_layoutOverflow(layoutRect)
-        , m_visualOverflow(visualRect)
+        , m_selfVisualOverflow(selfVisualOverflowRect)
     {
     }
 
     const LayoutRect& layoutOverflowRect() const { return m_layoutOverflow; }
-    const LayoutRect& visualOverflowRect() const { return m_visualOverflow; }
-    LayoutRect contentsVisualOverflowRect() const { return m_contentsVisualOverflow; }
+    void setLayoutOverflow(const LayoutRect& rect) { m_layoutOverflow = rect; }
+    void addLayoutOverflow(const LayoutRect& rect) { uniteLayoutOverflowRect(m_layoutOverflow, rect); }
 
-    void move(LayoutUnit dx, LayoutUnit dy);
+    const LayoutRect& selfVisualOverflowRect() const { return m_selfVisualOverflow; }
+    // TODO(wangxianzhu): Should use normal LayoutRect::unite() which ignores empty rects.
+    void addSelfVisualOverflow(const LayoutRect& rect) { m_selfVisualOverflow.uniteEvenIfEmpty(rect); }
 
-    void addLayoutOverflow(const LayoutRect&);
-    void addVisualOverflow(const LayoutRect&);
+    const LayoutRect& contentsVisualOverflowRect() const { return m_contentsVisualOverflow; }
     void addContentsVisualOverflow(const LayoutRect& rect) { m_contentsVisualOverflow.unite(rect); }
 
-    void setLayoutOverflow(const LayoutRect&);
-    void setVisualOverflow(const LayoutRect&);
+    void move(LayoutUnit dx, LayoutUnit dy)
+    {
+        m_layoutOverflow.move(dx, dy);
+        m_selfVisualOverflow.move(dx, dy);
+        m_contentsVisualOverflow.move(dx, dy);
+    }
 
     LayoutUnit layoutClientAfterEdge() const { return m_layoutClientAfterEdge; }
     void setLayoutClientAfterEdge(LayoutUnit clientAfterEdge) { m_layoutClientAfterEdge = clientAfterEdge; }
 
 private:
-    // The layout overflow rectangle. See class description for details.
     LayoutRect m_layoutOverflow;
-
-    // The visual overflow rectangle. See class description for details.
-    LayoutRect m_visualOverflow;
-
-    // The content visual overflow rectangle. See class description for details.
+    LayoutRect m_selfVisualOverflow;
     LayoutRect m_contentsVisualOverflow;
-
     LayoutUnit m_layoutClientAfterEdge;
 };
 
-inline void OverflowModel::move(LayoutUnit dx, LayoutUnit dy)
-{
-    m_layoutOverflow.move(dx, dy);
-    m_visualOverflow.move(dx, dy);
-    m_contentsVisualOverflow.move(dx, dy);
-}
-
-inline void OverflowModel::addLayoutOverflow(const LayoutRect& rect)
-{
-    LayoutUnit maxX = std::max(rect.maxX(), m_layoutOverflow.maxX());
-    LayoutUnit maxY = std::max(rect.maxY(), m_layoutOverflow.maxY());
-    LayoutUnit minX = std::min(rect.x(), m_layoutOverflow.x());
-    LayoutUnit minY = std::min(rect.y(), m_layoutOverflow.y());
-    // In case the width/height is larger than LayoutUnit can represent, fix the right/bottom edge and shift the top/left ones
-    m_layoutOverflow.setWidth(maxX - minX);
-    m_layoutOverflow.setHeight(maxY - minY);
-    m_layoutOverflow.setX(maxX - m_layoutOverflow.width());
-    m_layoutOverflow.setY(maxY - m_layoutOverflow.height());
-}
-
-inline void OverflowModel::addVisualOverflow(const LayoutRect& rect)
-{
-    LayoutUnit maxX = std::max(rect.maxX(), m_visualOverflow.maxX());
-    LayoutUnit maxY = std::max(rect.maxY(), m_visualOverflow.maxY());
-    m_visualOverflow.setX(std::min(rect.x(), m_visualOverflow.x()));
-    m_visualOverflow.setY(std::min(rect.y(), m_visualOverflow.y()));
-    m_visualOverflow.setWidth(maxX - m_visualOverflow.x());
-    m_visualOverflow.setHeight(maxY - m_visualOverflow.y());
-}
-
-inline void OverflowModel::setLayoutOverflow(const LayoutRect& rect)
-{
-    m_layoutOverflow = rect;
-}
-
-inline void OverflowModel::setVisualOverflow(const LayoutRect& rect)
-{
-    m_visualOverflow = rect;
-}
-
 } // namespace blink
 
 #endif // OverflowModel_h
diff --git a/third_party/WebKit/Source/core/layout/OverflowModelTest.cpp b/third_party/WebKit/Source/core/layout/OverflowModelTest.cpp
index 27f0877..c2f9554 100644
--- a/third_party/WebKit/Source/core/layout/OverflowModelTest.cpp
+++ b/third_party/WebKit/Source/core/layout/OverflowModelTest.cpp
@@ -49,13 +49,13 @@
 class OverflowModelTest : public testing::Test {
 protected:
     OverflowModelTest() : m_overflow(initialLayoutOverflow(), initialVisualOverflow()) { }
-    OverflowModel m_overflow;
+    BoxOverflowModel m_overflow;
 };
 
 TEST_F(OverflowModelTest, InitialOverflowRects)
 {
     EXPECT_EQ(initialLayoutOverflow(), m_overflow.layoutOverflowRect());
-    EXPECT_EQ(initialVisualOverflow(), m_overflow.visualOverflowRect());
+    EXPECT_EQ(initialVisualOverflow(), m_overflow.selfVisualOverflowRect());
     EXPECT_TRUE(m_overflow.contentsVisualOverflowRect().isEmpty());
 }
 
@@ -83,7 +83,7 @@
 TEST_F(OverflowModelTest, AddLayoutOverflowDoesNotAffectVisualOverflow)
 {
     m_overflow.addLayoutOverflow(LayoutRect(300, 300, 300, 300));
-    EXPECT_EQ(initialVisualOverflow(), m_overflow.visualOverflowRect());
+    EXPECT_EQ(initialVisualOverflow(), m_overflow.selfVisualOverflowRect());
 }
 
 TEST_F(OverflowModelTest, AddLayoutOverflowDoesNotAffectContentsVisualOverflow)
@@ -94,14 +94,14 @@
 
 TEST_F(OverflowModelTest, AddVisualOverflowOutsideExpandsRect)
 {
-    m_overflow.addVisualOverflow(LayoutRect(150, -50, 10, 10));
-    EXPECT_EQ(LayoutRect(0, -50, 160, 150), m_overflow.visualOverflowRect());
+    m_overflow.addSelfVisualOverflow(LayoutRect(150, -50, 10, 10));
+    EXPECT_EQ(LayoutRect(0, -50, 160, 150), m_overflow.selfVisualOverflowRect());
 }
 
 TEST_F(OverflowModelTest, AddVisualOverflowInsideDoesNotAffectRect)
 {
-    m_overflow.addVisualOverflow(LayoutRect(0, 10, 90, 90));
-    EXPECT_EQ(initialVisualOverflow(), m_overflow.visualOverflowRect());
+    m_overflow.addSelfVisualOverflow(LayoutRect(0, 10, 90, 90));
+    EXPECT_EQ(initialVisualOverflow(), m_overflow.selfVisualOverflowRect());
 }
 
 TEST_F(OverflowModelTest, AddVisualOverflowEmpty)
@@ -109,19 +109,19 @@
     // This test documents the existing behavior so that we are aware when/if
     // it changes. It would also be reasonable for addVisualOverflow to be
     // a no-op in this situation.
-    m_overflow.addVisualOverflow(LayoutRect(200, 200, 0, 0));
-    EXPECT_EQ(LayoutRect(0, 0, 200, 200), m_overflow.visualOverflowRect());
+    m_overflow.addSelfVisualOverflow(LayoutRect(200, 200, 0, 0));
+    EXPECT_EQ(LayoutRect(0, 0, 200, 200), m_overflow.selfVisualOverflowRect());
 }
 
 TEST_F(OverflowModelTest, AddVisualOverflowDoesNotAffectLayoutOverflow)
 {
-    m_overflow.addVisualOverflow(LayoutRect(300, 300, 300, 300));
+    m_overflow.addSelfVisualOverflow(LayoutRect(300, 300, 300, 300));
     EXPECT_EQ(initialLayoutOverflow(), m_overflow.layoutOverflowRect());
 }
 
 TEST_F(OverflowModelTest, AddVisualOverflowDoesNotAffectContentsVisualOverflow)
 {
-    m_overflow.addVisualOverflow(LayoutRect(300, 300, 300, 300));
+    m_overflow.addSelfVisualOverflow(LayoutRect(300, 300, 300, 300));
     EXPECT_TRUE(m_overflow.contentsVisualOverflowRect().isEmpty());
 }
 
@@ -164,7 +164,7 @@
 TEST_F(OverflowModelTest, MoveAffectsVisualOverflow)
 {
     m_overflow.move(LayoutUnit(500), LayoutUnit(100));
-    EXPECT_EQ(LayoutRect(500, 100, 100, 100), m_overflow.visualOverflowRect());
+    EXPECT_EQ(LayoutRect(500, 100, 100, 100), m_overflow.selfVisualOverflowRect());
 }
 
 TEST_F(OverflowModelTest, MoveAffectsContentsVisualOverflow)
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index d702f4d7..fd0887da 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -264,7 +264,8 @@
 {
     ASSERT(updateType != CompositingUpdateNone);
     m_pendingUpdateType = std::max(m_pendingUpdateType, updateType);
-    page()->animator().scheduleVisualUpdate(m_layoutView.frame());
+    if (Page* page = this->page())
+        page->animator().scheduleVisualUpdate(m_layoutView.frame());
     lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean);
 }
 
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index 18e3783..a1430388 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -952,7 +952,7 @@
         return;
 
     if (!m_overflow)
-        m_overflow = adoptPtr(new OverflowModel(frameBox, frameBox));
+        m_overflow = adoptPtr(new SimpleOverflowModel(frameBox, frameBox));
 
     m_overflow->setLayoutOverflow(rect);
 }
@@ -964,7 +964,7 @@
         return;
 
     if (!m_overflow)
-        m_overflow = adoptPtr(new OverflowModel(frameBox, frameBox));
+        m_overflow = adoptPtr(new SimpleOverflowModel(frameBox, frameBox));
 
     m_overflow->setVisualOverflow(rect);
 }
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
index 73fe8b8..c024ac0 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.h
@@ -310,7 +310,7 @@
     void setOverflowFromLogicalRects(const LayoutRect& logicalLayoutOverflow, const LayoutRect& logicalVisualOverflow, LayoutUnit lineTop, LayoutUnit lineBottom);
 
 protected:
-    OwnPtr<OverflowModel> m_overflow;
+    OwnPtr<SimpleOverflowModel> m_overflow;
 
     bool isInlineFlowBox() const final { return true; }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
index 510baa3d..be19897 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
@@ -141,7 +141,7 @@
     if (it == m_layoutAttributes.characterDataMap().end())
         return false;
 
-    return !SVGTextLayoutAttributes::isEmptyValue(it->value.x) || !SVGTextLayoutAttributes::isEmptyValue(it->value.y);
+    return it->value.hasX() || it->value.hasY();
 }
 
 PositionWithAffinity LayoutSVGInlineText::positionForPoint(const LayoutPoint& point)
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
index 01734e2..dad021b 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
@@ -86,7 +86,7 @@
             continue;
 
         const ComputedStyle* style = childLayoutObject->style();
-        if (!style || style->display() == NONE || style->visibility() != VISIBLE)
+        if (!style || style->display() == NONE || (style->visibility() != VISIBLE && !isSVGUseElement(*childElement)))
             continue;
 
         // Current shape in clip-path gets clipped too. Fallback to masking.
@@ -177,12 +177,12 @@
             continue;
 
         const ComputedStyle* style = layoutObject->style();
-        if (!style || style->display() == NONE || style->visibility() != VISIBLE)
+        if (!style || style->display() == NONE || (style->visibility() != VISIBLE && !isSVGUseElement(*childElement)))
             continue;
 
         bool isUseElement = isSVGUseElement(*childElement);
         if (isUseElement) {
-            const SVGGraphicsElement* clippingElement = toSVGUseElement(*childElement).targetGraphicsElementForClipping();
+            const SVGGraphicsElement* clippingElement = toSVGUseElement(*childElement).visibleTargetGraphicsElementForClipping();
             if (!clippingElement)
                 continue;
 
@@ -221,8 +221,11 @@
         if (!layoutObject->isSVGShape() && !layoutObject->isSVGText() && !isSVGUseElement(*childElement))
             continue;
         const ComputedStyle* style = layoutObject->style();
-        if (!style || style->display() == NONE || style->visibility() != VISIBLE)
+        if (!style || style->display() == NONE || (style->visibility() != VISIBLE && !isSVGUseElement(*childElement)))
             continue;
+        if (isSVGUseElement(*childElement) && !toSVGUseElement(*childElement).visibleTargetGraphicsElementForClipping())
+            continue;
+
         m_clipBoundaries.unite(layoutObject->localToSVGParentTransform().mapRect(layoutObject->paintInvalidationRectInLocalSVGCoordinates()));
     }
     m_clipBoundaries = toSVGClipPathElement(element())->calculateAnimatedLocalTransform().mapRect(m_clipBoundaries);
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
index d89246f7..59ac0f3 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
@@ -172,7 +172,7 @@
     if (!shouldApplyViewportClip()) {
         FloatRect contentPaintInvalidationRect = paintInvalidationRectInLocalSVGCoordinates();
         contentPaintInvalidationRect = m_localToBorderBoxTransform.mapRect(contentPaintInvalidationRect);
-        addVisualOverflow(enclosingLayoutRect(contentPaintInvalidationRect));
+        addContentsVisualOverflow(enclosingLayoutRect(contentPaintInvalidationRect));
     }
 
     updateLayerTransformAfterLayout();
@@ -193,6 +193,14 @@
         || this->isDocumentElement();
 }
 
+LayoutRect LayoutSVGRoot::visualOverflowRect() const
+{
+    LayoutRect rect = LayoutReplaced::selfVisualOverflowRect();
+    if (!shouldApplyViewportClip())
+        rect.unite(contentsVisualOverflowRect());
+    return rect;
+}
+
 void LayoutSVGRoot::paintReplaced(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const
 {
     SVGRootPainter(*this).paint(paintInfo, paintOffset);
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h
index 105137f..ab81ec28 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h
@@ -66,6 +66,8 @@
     const AffineTransform& localToBorderBoxTransform() const { return m_localToBorderBoxTransform; }
     bool shouldApplyViewportClip() const;
 
+    LayoutRect visualOverflowRect() const override;
+
     bool hasNonIsolatedBlendingDescendants() const final;
 
     const char* name() const override { return "LayoutSVGRoot"; }
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
index ae83ffc..723159ad 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp
@@ -186,51 +186,45 @@
     ASSERT(needsLayout());
     LayoutAnalyzer::Scope analyzer(*this);
 
-    bool updateCachedBoundariesInParents = false;
+    bool updateParentBoundaries = false;
     if (m_needsTransformUpdate) {
         m_localTransform = toSVGTextElement(node())->calculateAnimatedLocalTransform();
         m_needsTransformUpdate = false;
-        updateCachedBoundariesInParents = true;
+        updateParentBoundaries = true;
     }
 
+    // This flag is set and reset as needed only within this function.
+    ASSERT(!m_needsReordering);
+
+    // When laying out initially, build the character data map and propagate
+    // resulting layout attributes to all LayoutSVGInlineText children in the
+    // subtree.
     if (!everHadLayout()) {
-        // When laying out initially, collect all layout attributes, build the character data map,
-        // and propogate resulting SVGLayoutAttributes to all LayoutSVGInlineText children in the subtree.
-        ASSERT(m_layoutAttributes.isEmpty());
-        collectLayoutAttributes(this, m_layoutAttributes);
+        m_needsPositioningValuesUpdate = true;
+        m_needsTextMetricsUpdate = true;
+    }
+
+    // If the root layout size changed (eg. window size changes), or the screen
+    // scale factor has changed, then recompute the on-screen font size. Since
+    // the computation of layout attributes uses the text metrics, we need to
+    // update them before updating the layout attributes.
+    if (m_needsTextMetricsUpdate || SVGLayoutSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
         updateFontAndMetrics(*this);
-
-        SVGTextLayoutAttributesBuilder(*this).buildLayoutAttributes();
-
-        m_needsReordering = true;
         m_needsTextMetricsUpdate = false;
-        m_needsPositioningValuesUpdate = false;
-        updateCachedBoundariesInParents = true;
-    } else if (m_needsPositioningValuesUpdate) {
-        // When the x/y/dx/dy/rotate lists change, recompute the layout attributes, and eventually
-        // update the on-screen font objects as well in all descendants.
-        if (m_needsTextMetricsUpdate) {
-            updateFontAndMetrics(*this);
-            m_needsTextMetricsUpdate = false;
-        }
+        updateParentBoundaries = true;
+    }
 
+    // When the x/y/dx/dy/rotate lists change, we need to recompute the layout
+    // attributes.
+    if (m_needsPositioningValuesUpdate) {
         m_layoutAttributes.clear();
         collectLayoutAttributes(this, m_layoutAttributes);
 
         SVGTextLayoutAttributesBuilder(*this).buildLayoutAttributes();
 
-        m_needsReordering = true;
         m_needsPositioningValuesUpdate = false;
-        updateCachedBoundariesInParents = true;
-    } else if (m_needsTextMetricsUpdate || SVGLayoutSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
-        // If the root layout size changed (eg. window size changes), or the screen scale factor has
-        // changed, then recompute the on-screen font size.
-        updateFontAndMetrics(*this);
-
-        ASSERT(!m_needsReordering);
-        ASSERT(!m_needsPositioningValuesUpdate);
-        m_needsTextMetricsUpdate = false;
-        updateCachedBoundariesInParents = true;
+        m_needsReordering = true;
+        updateParentBoundaries = true;
     }
 
     checkLayoutAttributesConsistency(this, m_layoutAttributes);
@@ -272,17 +266,21 @@
     m_overflow.clear();
     addVisualEffectOverflow();
 
-    if (!updateCachedBoundariesInParents)
-        updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox();
+    if (!updateParentBoundaries)
+        updateParentBoundaries = oldBoundaries != objectBoundingBox();
 
     // Invalidate all resources of this client if our layout changed.
     if (everHadLayout() && selfNeedsLayout())
         SVGResourcesCache::clientLayoutChanged(this);
 
     // If our bounds changed, notify the parents.
-    if (updateCachedBoundariesInParents)
+    if (updateParentBoundaries)
         LayoutSVGBlock::setNeedsBoundariesUpdate();
 
+    ASSERT(!m_needsReordering);
+    ASSERT(!m_needsTransformUpdate);
+    ASSERT(!m_needsTextMetricsUpdate);
+    ASSERT(!m_needsPositioningValuesUpdate);
     clearNeedsLayout();
 }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributes.h b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributes.h
index 88c419ef..27d81c76 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributes.h
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributes.h
@@ -33,6 +33,15 @@
     DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
     SVGCharacterData();
 
+    static float emptyValue() { return std::numeric_limits<float>::quiet_NaN(); }
+    static bool isEmptyValue(float value) { return std::isnan(value); }
+
+    bool hasX() const { return !isEmptyValue(x); }
+    bool hasY() const { return !isEmptyValue(y); }
+    bool hasDx() const { return !isEmptyValue(dx); }
+    bool hasDy() const { return !isEmptyValue(dy); }
+    bool hasRotate() const { return !isEmptyValue(rotate); }
+
     float x;
     float y;
     float dx;
@@ -63,11 +72,11 @@
 };
 
 inline SVGCharacterData::SVGCharacterData()
-    : x(SVGTextLayoutAttributes::emptyValue())
-    , y(SVGTextLayoutAttributes::emptyValue())
-    , dx(SVGTextLayoutAttributes::emptyValue())
-    , dy(SVGTextLayoutAttributes::emptyValue())
-    , rotate(SVGTextLayoutAttributes::emptyValue())
+    : x(emptyValue())
+    , y(emptyValue())
+    , dx(emptyValue())
+    , dy(emptyValue())
+    , rotate(emptyValue())
 {
 }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp
index becc390e..5c248811 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutAttributesBuilder.cpp
@@ -147,9 +147,9 @@
 
     // Handle x/y default attributes.
     SVGCharacterData& data = m_characterDataMap.add(1, SVGCharacterData()).storedValue->value;
-    if (SVGTextLayoutAttributes::isEmptyValue(data.x))
+    if (!data.hasX())
         data.x = 0;
-    if (SVGTextLayoutAttributes::isEmptyValue(data.y))
+    if (!data.hasY())
         data.y = 0;
 }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
index 0f22482..4e1b635d 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
@@ -54,11 +54,11 @@
 
 bool SVGTextLayoutEngine::setCurrentTextPosition(const SVGCharacterData& data)
 {
-    bool hasX = !SVGTextLayoutAttributes::isEmptyValue(data.x);
+    bool hasX = data.hasX();
     if (hasX)
         m_textPosition.setX(data.x);
 
-    bool hasY = !SVGTextLayoutAttributes::isEmptyValue(data.y);
+    bool hasY = data.hasY();
     if (hasY)
         m_textPosition.setY(data.y);
 
@@ -93,11 +93,11 @@
 bool SVGTextLayoutEngine::applyRelativePositionAdjustmentsIfNeeded(const SVGCharacterData& data)
 {
     FloatPoint delta;
-    bool hasDx = !SVGTextLayoutAttributes::isEmptyValue(data.dx);
+    bool hasDx = data.hasDx();
     if (hasDx)
         delta.setX(data.dx);
 
-    bool hasDy = !SVGTextLayoutAttributes::isEmptyValue(data.dy);
+    bool hasDy = data.hasDy();
     if (hasDy)
         delta.setY(data.dy);
 
@@ -449,7 +449,7 @@
             position += baselineShift;
         }
 
-        if (!SVGTextLayoutAttributes::isEmptyValue(data.rotate))
+        if (data.hasRotate())
             angle += data.rotate;
 
         // Determine whether we have to start a new fragment.
diff --git a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
index 195d5f7d..017d880 100644
--- a/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
@@ -482,9 +482,9 @@
 {
     ASSERT(path.isEmpty());
 
-    const SVGGraphicsElement* element = targetGraphicsElementForClipping();
+    const SVGGraphicsElement* element = visibleTargetGraphicsElementForClipping();
 
-    if (!element || !element->layoutObject())
+    if (!element)
         return;
 
     if (element->isSVGGeometryElement()) {
@@ -496,7 +496,7 @@
     }
 }
 
-SVGGraphicsElement* SVGUseElement::targetGraphicsElementForClipping() const
+SVGGraphicsElement* SVGUseElement::visibleTargetGraphicsElementForClipping() const
 {
     Node* n = userAgentShadowRoot()->firstChild();
     if (!n || !n->isSVGElement())
@@ -507,13 +507,19 @@
     if (!element.isSVGGraphicsElement())
         return nullptr;
 
+    if (!element.layoutObject())
+        return nullptr;
+
+    const ComputedStyle* style = element.layoutObject()->style();
+    if (!style || style->visibility() != VISIBLE)
+        return nullptr;
+
     // Spec: "If a <use> element is a child of a clipPath element, it must directly
     // reference <path>, <text> or basic shapes elements. Indirect references are an
     // error and the clipPath element must be ignored."
     // http://dev.w3.org/fxtf/css-masking-1/#the-clip-path
     if (!isDirectReference(element)) {
         // Spec: Indirect references are an error (14.3.5)
-        document().accessSVGExtensions().reportError("Not allowed to use indirect reference in <clip-path>");
         return nullptr;
     }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGUseElement.h b/third_party/WebKit/Source/core/svg/SVGUseElement.h
index f743dc0..e54a8b95 100644
--- a/third_party/WebKit/Source/core/svg/SVGUseElement.h
+++ b/third_party/WebKit/Source/core/svg/SVGUseElement.h
@@ -48,7 +48,7 @@
 
     // Return the element that should be used for clipping,
     // or null if a valid clip element is not directly referenced.
-    SVGGraphicsElement* targetGraphicsElementForClipping() const;
+    SVGGraphicsElement* visibleTargetGraphicsElementForClipping() const;
 
     SVGAnimatedLength* x() const { return m_x.get(); }
     SVGAnimatedLength* y() const { return m_y.get(); }
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index e31906f..525ee8c 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -79,12 +79,6 @@
     ASSERT(!m_chromeClient || !m_chromeClient->image());
 }
 
-LayoutRect SVGImage::visualRect() const
-{
-    // TODO(chrishtr): fix this.
-    return LayoutRect();
-}
-
 bool SVGImage::isInSVGImage(const Node* node)
 {
     ASSERT(node);
@@ -283,8 +277,8 @@
     spacedTile.expand(FloatSize(repeatSpacing));
 
     SkPictureBuilder patternPicture(spacedTile, nullptr, &context);
-    if (!DrawingRecorder::useCachedDrawingIfPossible(patternPicture.context(), *this, DisplayItem::Type::SVGImage)) {
-        DrawingRecorder patternPictureRecorder(patternPicture.context(), *this, DisplayItem::Type::SVGImage, spacedTile);
+    {
+        DrawingRecorder patternPictureRecorder(patternPicture.context(), patternPicture, DisplayItem::Type::SVGImage, spacedTile);
         // When generating an expanded tile, make sure we don't draw into the spacing area.
         if (tile != spacedTile)
             patternPicture.context().clip(tile);
@@ -352,7 +346,7 @@
 
     SkPictureBuilder imagePicture(dstRect);
     {
-        ClipRecorder clipRecorder(imagePicture.context(), *this, DisplayItem::ClipNodeImage, LayoutRect(enclosingIntRect(dstRect)));
+        ClipRecorder clipRecorder(imagePicture.context(), imagePicture, DisplayItem::ClipNodeImage, LayoutRect(enclosingIntRect(dstRect)));
 
         // We can only draw the entire frame, clipped to the rect we want. So compute where the top left
         // of the image would be if we were drawing without clipping, and translate accordingly.
@@ -361,7 +355,7 @@
         FloatPoint destOffset = dstRect.location() - topLeftOffset;
         AffineTransform transform = AffineTransform::translation(destOffset.x(), destOffset.y());
         transform.scale(scale.width(), scale.height());
-        TransformRecorder transformRecorder(imagePicture.context(), *this, transform);
+        TransformRecorder transformRecorder(imagePicture.context(), imagePicture, transform);
 
         view->updateAllLifecyclePhasesExceptPaint();
         view->paint(imagePicture.context(), CullRect(enclosingIntRect(srcRect)));
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
index bc718d09..ea98cf2 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
@@ -28,7 +28,6 @@
 #define SVGImage_h
 
 #include "platform/graphics/Image.h"
-#include "platform/graphics/paint/DisplayItemClient.h"
 #include "platform/heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/Allocator.h"
@@ -42,7 +41,7 @@
 class SVGImageChromeClient;
 class SVGImageForContainer;
 
-class SVGImage final : public Image, public DisplayItemClient {
+class SVGImage final : public Image {
 public:
     static PassRefPtr<SVGImage> create(ImageObserver* observer)
     {
@@ -82,10 +81,6 @@
     // thus also independent of current zoom level.
     FloatSize concreteObjectSize(const FloatSize& defaultObjectSize) const;
 
-    // DisplayItemClient methods.
-    String debugName() const final { return "SVGImage"; }
-    LayoutRect visualRect() const override;
-
     bool hasIntrinsicDimensions() const;
 
 private:
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index c405aaf9..8ca4b03 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -33,10 +33,13 @@
     gypi_values.devtools_cm_modes_js_files +
     gypi_values.devtools_components_lazy_js_files +
     gypi_values.devtools_console_js_files +
-    gypi_values.devtools_devices_js_files + gypi_values.devtools_diff_js_files +
+    gypi_values.devtools_devices_js_files +
+    gypi_values.devtools_diff_js_files +
     gypi_values.devtools_elements_js_files +
     gypi_values.devtools_emulated_devices_js_files +
-    gypi_values.devtools_es_tree_js_files + devtools_extensions_js_files +
+    gypi_values.devtools_es_tree_js_files +
+                devtools_extensions_js_files +
+    gypi_values.devtools_gonzales_js_files +
     gypi_values.devtools_heap_snapshot_worker_js_files +
     gypi_values.devtools_layers_js_files +
     gypi_values.devtools_network_js_files +
@@ -269,8 +272,8 @@
       resources_out_dir + "heap_snapshot_worker.js",
       resources_out_dir + "temp_storage_shared_worker.js",
       resources_out_dir + "accessibility_module.js",
-      resources_out_dir + "audits_module.js",
       resources_out_dir + "animation_module.js",
+      resources_out_dir + "audits_module.js",
       resources_out_dir + "cm_modes_module.js",
       resources_out_dir + "components_lazy_module.js",
       resources_out_dir + "console_module.js",
@@ -279,13 +282,14 @@
       resources_out_dir + "elements_module.js",
       resources_out_dir + "emulated_devices_module.js",
       resources_out_dir + "es_tree_module.js",
+      resources_out_dir + "gonzales_module.js",
       resources_out_dir + "layers_module.js",
       resources_out_dir + "network_module.js",
       resources_out_dir + "profiler_module.js",
       resources_out_dir + "resources_module.js",
       resources_out_dir + "sass_module.js",
-      resources_out_dir + "security_module.js",
       resources_out_dir + "screencast_module.js",
+      resources_out_dir + "security_module.js",
       resources_out_dir + "settings_module.js",
       resources_out_dir + "snippets_module.js",
       resources_out_dir + "source_frame_module.js",
diff --git a/third_party/WebKit/Source/devtools/devtools.gyp b/third_party/WebKit/Source/devtools/devtools.gyp
index 7842b6c8..0cb75614 100644
--- a/third_party/WebKit/Source/devtools/devtools.gyp
+++ b/third_party/WebKit/Source/devtools/devtools.gyp
@@ -281,6 +281,7 @@
                             '<(_output_path)/elements_module.js',
                             '<(_output_path)/emulated_devices_module.js',
                             '<(_output_path)/es_tree_module.js',
+                            '<(_output_path)/gonzales_module.js',
                             '<(_output_path)/layers_module.js',
                             '<(_output_path)/network_module.js',
                             '<(_output_path)/profiler_module.js',
diff --git a/third_party/WebKit/Source/devtools/devtools.gypi b/third_party/WebKit/Source/devtools/devtools.gypi
index 0ebbfb4a..396d7d5 100644
--- a/third_party/WebKit/Source/devtools/devtools.gypi
+++ b/third_party/WebKit/Source/devtools/devtools.gypi
@@ -338,6 +338,7 @@
             'front_end/emulation/module.json',
             'front_end/es_tree/module.json',
             'front_end/extensions/module.json',
+            'front_end/gonzales/module.json',
             'front_end/heap_snapshot_worker/module.json',
             'front_end/host/module.json',
             'front_end/layers/module.json',
@@ -517,6 +518,10 @@
             'front_end/extensions/ExtensionView.js',
             '<@(devtools_extension_api_files)',
         ],
+        'devtools_gonzales_js_files': [
+            'front_end/gonzales/gonzales-scss.js',
+            'front_end/gonzales/SCSSParser.js',
+        ],
         'devtools_heap_snapshot_worker_js_files': [
             'front_end/common/TextUtils.js',
             'front_end/common/UIString.js',
@@ -789,6 +794,7 @@
             '<@(devtools_emulated_devices_js_files)',
             '<@(devtools_es_tree_js_files)',
             '<@(devtools_extensions_js_files)',
+            '<@(devtools_gonzales_js_files)',
             '<@(devtools_heap_snapshot_worker_js_files)',
             '<@(devtools_layers_js_files)',
             '<@(devtools_network_js_files)',
diff --git a/third_party/WebKit/Source/devtools/front_end/.eslintignore b/third_party/WebKit/Source/devtools/front_end/.eslintignore
index 976a78d..61ade28 100644
--- a/third_party/WebKit/Source/devtools/front_end/.eslintignore
+++ b/third_party/WebKit/Source/devtools/front_end/.eslintignore
@@ -1,5 +1,5 @@
-diff/diff_match_patch.js
-cm_modes/
-cm/
-acorn/
+diff_match_patch.js
+cm_modes
+cm
+acorn
 protocol_externs.js
diff --git a/third_party/WebKit/Source/devtools/front_end/common/FormatterWorkerPool.js b/third_party/WebKit/Source/devtools/front_end/common/FormatterWorkerPool.js
index 08f7697..b562b722 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/FormatterWorkerPool.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/FormatterWorkerPool.js
@@ -59,7 +59,7 @@
 
         this._workerTasks.set(worker, null);
         this._processNextTask();
-        task.callback(event);
+        task.callback(event.data ? event : null);
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Worker.js b/third_party/WebKit/Source/devtools/front_end/common/Worker.js
index 5cbb08f1..bf3ceeb 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/Worker.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/Worker.js
@@ -35,26 +35,24 @@
  */
 WebInspector.Worker = function(appName, workerName)
 {
-    var isSharedWorker = !!workerName;
-
     var url = appName + ".js";
     var remoteBase = Runtime.queryParam("remoteBase");
     if (remoteBase)
         url += "?remoteBase=" + remoteBase;
 
+    var callback;
+    /** @type {!Promise<!Worker|!SharedWorker>} */
+    this._workerPromise = new Promise(fulfill => callback = fulfill);
+
     /** @type {!Worker|!SharedWorker} */
     var worker;
-    var callback;
-    try {
-        if (isSharedWorker) {
-            worker = new SharedWorker(url, workerName);
-            worker.port.onmessage = onMessage;
-        } else {
-            worker = new Worker(url);
-            worker.onmessage = onMessage;
-        }
-    } catch(e) {
-        return Promise.reject(e);
+    var isSharedWorker = !!workerName;
+    if (isSharedWorker) {
+        worker = new SharedWorker(url, workerName);
+        worker.port.onmessage = onMessage;
+    } else {
+        worker = new Worker(url);
+        worker.onmessage = onMessage;
     }
 
     /**
@@ -69,9 +67,6 @@
             worker.onmessage = null;
         callback(worker);
     }
-
-    /** @type {!Promise<!Worker|!SharedWorker>} */
-    this._workerPromise = new Promise(fulfill => callback = fulfill);
 }
 
 WebInspector.Worker.prototype = {
diff --git a/third_party/WebKit/Source/devtools/front_end/externs.js b/third_party/WebKit/Source/devtools/front_end/externs.js
index dd0737e..beb0b81 100644
--- a/third_party/WebKit/Source/devtools/front_end/externs.js
+++ b/third_party/WebKit/Source/devtools/front_end/externs.js
@@ -702,3 +702,41 @@
     /** @type {!Array.<!ESTree.Node>} */
     this.expressions;
 }
+
+var Gonzales = {}
+var gonzales = {
+    /**
+     * @param {string} text
+     * @param {!Object=} options
+     * @return {!Gonzales.Node}
+     */
+    parse: function(text, options) { },
+}
+
+/**
+ * @constructor
+ */
+Gonzales.Location = function()
+{
+    /** @type {number} */
+    this.line;
+    /** @type {number} */
+    this.column;
+}
+
+/**
+ * @constructor
+ */
+Gonzales.Node = function()
+{
+    /** @type {string} */
+    this.type;
+    /** @type {string} */
+    this.syntax;
+    /** @type {!Gonzales.Location} */
+    this.start;
+    /** @type {!Gonzales.Location} */
+    this.end;
+    /** @type {(string|!Array<!Gonzales.Node>)} */
+    this.content;
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker.json b/third_party/WebKit/Source/devtools/front_end/formatter_worker.json
index 5ebcb4e..a9fd165 100644
--- a/third_party/WebKit/Source/devtools/front_end/formatter_worker.json
+++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker.json
@@ -1,6 +1,7 @@
 {
     "modules": [
-        { "name": "formatter_worker", "type": "autostart" }
+        { "name": "formatter_worker", "type": "autostart" },
+        { "name": "gonzales", "type": "remote" }
     ],
 
     "has_html": false
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker/FormatterWorker.js b/third_party/WebKit/Source/devtools/front_end/formatter_worker/FormatterWorker.js
index b7c5227..bd7e5d5 100644
--- a/third_party/WebKit/Source/devtools/front_end/formatter_worker/FormatterWorker.js
+++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker/FormatterWorker.js
@@ -69,6 +69,9 @@
     case "parseCSS":
         WebInspector.parseCSS(params.content);
         break;
+    case "parseSCSS":
+        WebInspector.FormatterWorkerContentParser.parse(params.content, "text/x-scss");
+        break;
     case "javaScriptOutline":
         WebInspector.javaScriptOutline(params.content);
         break;
@@ -228,3 +231,35 @@
     }
     postMessage(result);
 }
+
+/**
+ * @interface
+ */
+WebInspector.FormatterWorkerContentParser = function() { }
+
+WebInspector.FormatterWorkerContentParser.prototype = {
+    /**
+     * @param {string} content
+     * @return {!Object}
+     */
+    parse: function(content) { }
+}
+
+WebInspector.FormatterWorkerContentParser.parse = function(content, mimeType)
+{
+    var extension = self.runtime.extensions(WebInspector.FormatterWorkerContentParser).find(findExtension);
+    console.assert(extension);
+    extension.instancePromise()
+        .then(instance => instance.parse(content))
+        .catchException(null)
+        .then(postMessage);
+
+    /**
+     * @param {!Runtime.Extension} extension
+     * @return {boolean}
+     */
+    function findExtension(extension)
+    {
+        return extension.descriptor()["mimeType"] === mimeType;
+    }
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker/module.json b/third_party/WebKit/Source/devtools/front_end/formatter_worker/module.json
index 4c12baa..05c0ea2 100644
--- a/third_party/WebKit/Source/devtools/front_end/formatter_worker/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker/module.json
@@ -5,6 +5,8 @@
         "../cm/css.js",
         "../cm/xml.js",
         "../common/WebInspector.js",
+        "../common/Text.js",
+        "../common/TextRange.js",
         "../es_tree/ESTreeWalker.js",
         "FormatterWorker.js",
         "../acorn/acorn.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/gonzales/MIT-LICENSE.txt b/third_party/WebKit/Source/devtools/front_end/gonzales/MIT-LICENSE.txt
new file mode 100644
index 0000000..18113b1
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/gonzales/MIT-LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (C) 2012 by Sergey Kryzhanovsky
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/gonzales/SCSSParser.js b/third_party/WebKit/Source/devtools/front_end/gonzales/SCSSParser.js
new file mode 100644
index 0000000..04cd9eb
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/gonzales/SCSSParser.js
@@ -0,0 +1,197 @@
+// 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.
+
+/**
+ * @constructor
+ * @implements {WebInspector.FormatterWorkerContentParser}
+ */
+WebInspector.SCSSParser = function()
+{
+}
+
+/**
+ * @constructor
+ */
+WebInspector.SCSSParser.Result = function()
+{
+    this.properties = [];
+    this.variables = [];
+    this.mixins = [];
+}
+
+WebInspector.SCSSParser.prototype = {
+    /**
+     * @override
+     * @param {string} content
+     * @return {!WebInspector.SCSSParser.Result}
+     */
+    parse: function(content)
+    {
+        var result = new WebInspector.SCSSParser.Result();
+        var ast = null;
+        try {
+            ast = gonzales.parse(content, {syntax: "scss"});
+        } catch (e) {
+            return result;
+        }
+
+        var extractedNodes = [];
+        WebInspector.SCSSParser.extractNodes(ast, extractedNodes);
+
+        for (var node of extractedNodes) {
+            if (node.type === "declaration")
+                this._handleDeclaration(node, result);
+            else if (node.type === "include")
+                this._handleInclude(node, result);
+            else if (node.type === "multilineComment" && node.start.line === node.end.line)
+                this._handleComment(node, result);
+        }
+        return result;
+    },
+
+    /**
+     * @param {!Gonzales.Node} node
+     * @param {!WebInspector.SCSSParser.Result} result
+     */
+    _handleDeclaration: function(node, result)
+    {
+        var propertyNode = node.content.find(node => node.type === "property");
+        var delimeterNode = node.content.find(node => node.type === "propertyDelimiter");
+        var valueNode = node.content.find(node => node.type === "value");
+        if (!propertyNode || !delimeterNode || !valueNode)
+            return;
+
+        var nameRange = new WebInspector.TextRange(propertyNode.start.line - 1, propertyNode.start.column - 1, delimeterNode.start.line - 1, delimeterNode.start.column - 1);
+        var valueRange = new WebInspector.TextRange(delimeterNode.end.line - 1, delimeterNode.end.column, valueNode.end.line - 1, valueNode.end.column);
+        var range = /** @type {!WebInspector.TextRange} */(node.declarationRange);
+
+        var property = new WebInspector.SCSSParser.Property(range, nameRange, valueRange, false);
+        var isVariable = !!propertyNode.content.find(node => node.type === "variable");
+        if (isVariable)
+            result.variables.push(property);
+        else
+            result.properties.push(property);
+    },
+
+    /**
+     * @param {!Gonzales.Node} node
+     * @param {!WebInspector.SCSSParser.Result} result
+     */
+    _handleInclude: function(node, result)
+    {
+        var mixinName = node.content.find(node => node.type === "ident");
+        if (!mixinName)
+            return;
+        var nameRange = WebInspector.SCSSParser.rangeFromNode(mixinName);
+        var mixinArguments = node.content.find(node => node.type === "arguments");
+        if (!mixinArguments)
+            return;
+        var parameters = mixinArguments.content.filter(node => node.type !== "delimiter" && node.type !== "space");
+        for (var parameter of parameters) {
+            var range = WebInspector.SCSSParser.rangeFromNode(node);
+            var valueRange = WebInspector.SCSSParser.rangeFromNode(parameter);
+            var property = new WebInspector.SCSSParser.Property(range, nameRange, valueRange, false);
+            result.mixins.push(property);
+        }
+    },
+
+    /**
+     * @param {!Gonzales.Node} node
+     * @param {!WebInspector.SCSSParser.Result} result
+     */
+    _handleComment: function(node, result)
+    {
+        if (node.start.line !== node.end.line)
+            return;
+        var innerText = /** @type {string} */(node.content);
+        var innerResult = this.parse(innerText);
+        if (innerResult.properties.length !== 1 || innerResult.variables.length !== 0 || innerResult.mixins.length !== 0)
+            return;
+        var property = innerResult.properties[0];
+        var disabledProperty = property.rebaseInsideOneLineComment(node);
+        result.properties.push(disabledProperty);
+    },
+}
+
+/**
+ * @param {!Gonzales.Node} node
+ * @return {!WebInspector.TextRange}
+ */
+WebInspector.SCSSParser.rangeFromNode = function(node)
+{
+    return new WebInspector.TextRange(node.start.line - 1, node.start.column - 1, node.end.line - 1, node.end.column);
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.TextRange} range
+ * @param {!WebInspector.TextRange} nameRange
+ * @param {!WebInspector.TextRange} valueRange
+ * @param {boolean} disabled
+ */
+WebInspector.SCSSParser.Property = function(range, nameRange, valueRange, disabled)
+{
+    this.range = range;
+    this.name = nameRange;
+    this.value = valueRange;
+    this.disabled = disabled;
+}
+
+WebInspector.SCSSParser.Property.prototype = {
+    /**
+     * @param {!Gonzales.Node} commentNode
+     * @return {!WebInspector.SCSSParser.Property}
+     */
+    rebaseInsideOneLineComment: function(commentNode)
+    {
+        var lineOffset = commentNode.start.line - 1;
+        // Account for the "/*".
+        var columnOffset = commentNode.start.column - 1 + 2;
+        var range = WebInspector.SCSSParser.rangeFromNode(commentNode);
+        var name = rebaseRange(this.name, lineOffset, columnOffset);
+        var value = rebaseRange(this.value, lineOffset, columnOffset);
+        return new WebInspector.SCSSParser.Property(range, name, value, true);
+
+        /**
+         * @param {!WebInspector.TextRange} range
+         * @param {number} lineOffset
+         * @param {number} columnOffset
+         * @return {!WebInspector.TextRange}
+         */
+        function rebaseRange(range, lineOffset, columnOffset)
+        {
+            return new WebInspector.TextRange(range.startLine + lineOffset, range.startColumn + columnOffset, range.endLine + lineOffset, range.endColumn + columnOffset);
+        }
+    }
+}
+
+/**
+ * @param {!Gonzales.Node} node
+ * @param {!Array<!Gonzales.Node>} output
+ */
+WebInspector.SCSSParser.extractNodes = function(node, output)
+{
+    if (!Array.isArray(node.content))
+        return;
+    var lastDeclaration = null;
+    for (var i = 0; i < node.content.length; ++i) {
+        var child = node.content[i];
+        if (child.type === "declarationDelimiter" && lastDeclaration) {
+            lastDeclaration.declarationRange.endLine = child.end.line - 1;
+            lastDeclaration.declarationRange.endColumn = child.end.column;
+            lastDeclaration = null;
+        }
+        if (child.type === "include" || child.type === "declaration" || child.type === "multilineComment")
+            output.push(child);
+        if (child.type === "declaration") {
+            lastDeclaration = child;
+            lastDeclaration.declarationRange = WebInspector.TextRange.createFromLocation(child.start.line - 1, child.start.column - 1);
+        }
+        WebInspector.SCSSParser.extractNodes(child, output);
+    }
+    if (lastDeclaration) {
+        lastDeclaration.declarationRange.endLine = node.end.line - 1;
+        lastDeclaration.declarationRange.endColumn = node.end.column - 1;
+    }
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/gonzales/gonzales-scss.js b/third_party/WebKit/Source/devtools/front_end/gonzales/gonzales-scss.js
new file mode 100644
index 0000000..6ad1dbc
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/gonzales/gonzales-scss.js
@@ -0,0 +1,2191 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define([], factory);
+	else if(typeof exports === 'object')
+		exports["gonzales"] = factory();
+	else
+		root["gonzales"] = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ 	// The module cache
+/******/ 	var installedModules = {};
+
+/******/ 	// The require function
+/******/ 	function __webpack_require__(moduleId) {
+
+/******/ 		// Check if module is in cache
+/******/ 		if(installedModules[moduleId])
+/******/ 			return installedModules[moduleId].exports;
+
+/******/ 		// Create a new module (and put it into the cache)
+/******/ 		var module = installedModules[moduleId] = {
+/******/ 			exports: {},
+/******/ 			id: moduleId,
+/******/ 			loaded: false
+/******/ 		};
+
+/******/ 		// Execute the module function
+/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+
+/******/ 		// Flag the module as loaded
+/******/ 		module.loaded = true;
+
+/******/ 		// Return the exports of the module
+/******/ 		return module.exports;
+/******/ 	}
+
+
+/******/ 	// expose the modules object (__webpack_modules__)
+/******/ 	__webpack_require__.m = modules;
+
+/******/ 	// expose the module cache
+/******/ 	__webpack_require__.c = installedModules;
+
+/******/ 	// __webpack_public_path__
+/******/ 	__webpack_require__.p = "";
+
+/******/ 	// Load entry module and return exports
+/******/ 	return __webpack_require__(0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	var Node = __webpack_require__(1);
+	var parse = __webpack_require__(7);
+
+	module.exports = {
+	  createNode: function (options) {
+	    return new Node(options);
+	  },
+	  parse: parse
+	};
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	/**
+	 * @param {string} type
+	 * @param {array|string} content
+	 * @param {number} line
+	 * @param {number} column
+	 * @constructor
+	 */
+
+	var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+	var Node = (function () {
+	  function Node(options) {
+	    _classCallCheck(this, Node);
+
+	    this.type = options.type;
+	    this.content = options.content;
+	    this.syntax = options.syntax;
+
+	    if (options.start) this.start = options.start;
+	    if (options.end) this.end = options.end;
+	  }
+
+	  /**
+	   * @param {String} type Node type
+	   * @return {Boolean} Whether there is a child node of given type
+	   */
+
+	  Node.prototype.contains = function contains(type) {
+	    return this.content.some(function (node) {
+	      return node.type === type;
+	    });
+	  };
+
+	  /**
+	   * @param {String} type Node type
+	   * @param {Function} callback Function to call for every found node
+	   */
+
+	  Node.prototype.eachFor = function eachFor(type, callback) {
+	    if (!Array.isArray(this.content)) return;
+
+	    if (typeof type !== 'string') {
+	      callback = type;
+	      type = null;
+	    }
+
+	    var l = this.content.length;
+	    var breakLoop;
+
+	    for (var i = l; i--;) {
+	      if (breakLoop === null) break;
+
+	      if (!type || this.content[i] && this.content[i].type === type) breakLoop = callback(this.content[i], i, this);
+	    }
+
+	    if (breakLoop === null) return null;
+	  };
+
+	  /**
+	   * @param {String} type
+	   * @return {?Node} First child node or `null` if nothing's been found.
+	   */
+
+	  Node.prototype.first = function first(type) {
+	    if (!Array.isArray(this.content)) return null;
+
+	    if (!type) return this.content[0];
+
+	    var i = 0;
+	    var l = this.content.length;
+
+	    for (; i < l; i++) {
+	      if (this.content[i].type === type) return this.content[i];
+	    }
+
+	    return null;
+	  };
+
+	  /**
+	   * @param {String} type Node type
+	   * @param {Function} callback Function to call for every found node
+	   */
+
+	  Node.prototype.forEach = function forEach(type, callback) {
+	    if (!Array.isArray(this.content)) return;
+
+	    if (typeof type !== 'string') {
+	      callback = type;
+	      type = null;
+	    }
+
+	    var i = 0;
+	    var l = this.content.length;
+	    var breakLoop;
+
+	    for (; i < l; i++) {
+	      if (breakLoop === null) break;
+
+	      if (!type || this.content[i] && this.content[i].type === type) breakLoop = callback(this.content[i], i, this);
+	    }
+
+	    if (breakLoop === null) return null;
+	  };
+
+	  /**
+	   * @param {Number} index
+	   * @return {?Node}
+	   */
+
+	  Node.prototype.get = function get(index) {
+	    if (!Array.isArray(this.content)) return null;
+
+	    var node = this.content[index];
+	    return node ? node : null;
+	  };
+
+	  /**
+	   * @param {Number} index
+	   * @param {Node} node
+	   */
+
+	  Node.prototype.insert = function insert(index, node) {
+	    if (!Array.isArray(this.content)) return;
+
+	    this.content.splice(index, 0, node);
+	  };
+
+	  /**
+	   * @param {String} type
+	   * @return {Boolean} Whether the node is of given type
+	   */
+
+	  Node.prototype.is = function is(type) {
+	    return this.type === type;
+	  };
+
+	  /**
+	   * @param {String} type
+	   * @return {?Node} Last child node or `null` if nothing's been found.
+	   */
+
+	  Node.prototype.last = function last(type) {
+	    if (!Array.isArray(this.content)) return null;
+
+	    var i = this.content.length - 1;
+	    if (!type) return this.content[i];
+
+	    for (;; i--) {
+	      if (this.content[i].type === type) return this.content[i];
+	    }
+
+	    return null;
+	  };
+
+	  /**
+	   * Number of child nodes.
+	   * @type {number}
+	   */
+
+	  /**
+	   * @param {Number} index
+	   * @return {Node}
+	   */
+
+	  Node.prototype.removeChild = function removeChild(index) {
+	    if (!Array.isArray(this.content)) return;
+
+	    var removedChild = this.content.splice(index, 1);
+
+	    return removedChild;
+	  };
+
+	  Node.prototype.toJson = function toJson() {
+	    return JSON.stringify(this, false, 2);
+	  };
+
+	  Node.prototype.toString = function toString() {
+	    var stringify = undefined;
+
+	    try {
+	      stringify = __webpack_require__(2)("./" + this.syntax + '/stringify');
+	    } catch (e) {
+	      var message = 'Syntax "' + this.syntax + '" is not supported yet, sorry';
+	      return console.error(message);
+	    }
+
+	    return stringify(this);
+	  };
+
+	  /**
+	   * @param {Function} callback
+	   */
+
+	  Node.prototype.traverse = function traverse(callback, index) {
+	    var level = arguments.length <= 2 || arguments[2] === undefined ? 0 : arguments[2];
+	    var parent = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3];
+
+	    var breakLoop;
+	    var x;
+
+	    level++;
+
+	    callback(this, index, parent, level);
+
+	    if (!Array.isArray(this.content)) return;
+
+	    for (var i = 0, l = this.content.length; i < l; i++) {
+	      breakLoop = this.content[i].traverse(callback, i, level, this);
+	      if (breakLoop === null) break;
+
+	      // If some nodes were removed or added:
+	      if (x = this.content.length - l) {
+	        l += x;
+	        i += x;
+	      }
+	    }
+
+	    if (breakLoop === null) return null;
+	  };
+
+	  Node.prototype.traverseByType = function traverseByType(type, callback) {
+	    this.traverse(function (node) {
+	      if (node.type === type) callback.apply(node, arguments);
+	    });
+	  };
+
+	  Node.prototype.traverseByTypes = function traverseByTypes(types, callback) {
+	    this.traverse(function (node) {
+	      if (types.indexOf(node.type) !== -1) callback.apply(node, arguments);
+	    });
+	  };
+
+	  _createClass(Node, [{
+	    key: 'length',
+	    get: function () {
+	      if (!Array.isArray(this.content)) return 0;
+	      return this.content.length;
+	    }
+	  }]);
+
+	  return Node;
+	})();
+
+	module.exports = Node;
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var map = {
+		"./css/stringify": 3,
+		"./less/stringify": 4,
+		"./sass/stringify": 5,
+		"./scss/stringify": 6
+	};
+	function webpackContext(req) {
+		return __webpack_require__(webpackContextResolve(req));
+	};
+	function webpackContextResolve(req) {
+		return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }());
+	};
+	webpackContext.keys = function webpackContextKeys() {
+		return Object.keys(map);
+	};
+	webpackContext.resolve = webpackContextResolve;
+	module.exports = webpackContext;
+	webpackContext.id = 2;
+
+
+/***/ },
+/* 3 */
+/***/ function(module, exports) {
+
+	// jscs:disable maximumLineLength
+
+	'use strict';
+
+	module.exports = function stringify(tree) {
+	  // TODO: Better error message
+	  if (!tree) throw new Error('We need tree to translate');
+
+	  function _t(tree) {
+	    var type = tree.type;
+	    if (_unique[type]) return _unique[type](tree);
+	    if (typeof tree.content === 'string') return tree.content;
+	    if (Array.isArray(tree.content)) return _composite(tree.content);
+	    return '';
+	  }
+
+	  function _composite(t, i) {
+	    if (!t) return '';
+
+	    var s = '';
+	    i = i || 0;
+	    for (; i < t.length; i++) s += _t(t[i]);
+	    return s;
+	  }
+
+	  var _unique = {
+	    'arguments': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'atkeyword': function (t) {
+	      return '@' + _composite(t.content);
+	    },
+	    'attributeSelector': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'block': function (t) {
+	      return '{' + _composite(t.content) + '}';
+	    },
+	    'brackets': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'class': function (t) {
+	      return '.' + _composite(t.content);
+	    },
+	    'color': function (t) {
+	      return '#' + t.content;
+	    },
+	    'expression': function (t) {
+	      return 'expression(' + t.content + ')';
+	    },
+	    'id': function (t) {
+	      return '#' + _composite(t.content);
+	    },
+	    'multilineComment': function (t) {
+	      return '/*' + t.content + '*/';
+	    },
+	    'nthSelector': function (t) {
+	      return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
+	    },
+	    'parentheses': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'percentage': function (t) {
+	      return _composite(t.content) + '%';
+	    },
+	    'pseudoClass': function (t) {
+	      return ':' + _composite(t.content);
+	    },
+	    'pseudoElement': function (t) {
+	      return '::' + _composite(t.content);
+	    },
+	    'uri': function (t) {
+	      return 'url(' + _composite(t.content) + ')';
+	    }
+	  };
+
+	  return _t(tree);
+	};
+
+/***/ },
+/* 4 */
+/***/ function(module, exports) {
+
+	// jscs:disable maximumLineLength
+
+	'use strict';
+
+	module.exports = function stringify(tree) {
+	  // TODO: Better error message
+	  if (!tree) throw new Error('We need tree to translate');
+
+	  function _t(tree) {
+	    var type = tree.type;
+	    if (_unique[type]) return _unique[type](tree);
+	    if (typeof tree.content === 'string') return tree.content;
+	    if (Array.isArray(tree.content)) return _composite(tree.content);
+	    return '';
+	  }
+
+	  function _composite(t, i) {
+	    if (!t) return '';
+
+	    var s = '';
+	    i = i || 0;
+	    for (; i < t.length; i++) s += _t(t[i]);
+	    return s;
+	  }
+
+	  var _unique = {
+	    'arguments': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'atkeyword': function (t) {
+	      return '@' + _composite(t.content);
+	    },
+	    'attributeSelector': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'block': function (t) {
+	      return '{' + _composite(t.content) + '}';
+	    },
+	    'brackets': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'class': function (t) {
+	      return '.' + _composite(t.content);
+	    },
+	    'color': function (t) {
+	      return '#' + t.content;
+	    },
+	    'escapedString': function (t) {
+	      return '~' + t.content;
+	    },
+	    'expression': function (t) {
+	      return 'expression(' + t.content + ')';
+	    },
+	    'id': function (t) {
+	      return '#' + _composite(t.content);
+	    },
+	    'interpolatedVariable': function (t) {
+	      return '@{' + _composite(t.content) + '}';
+	    },
+	    'multilineComment': function (t) {
+	      return '/*' + t.content + '*/';
+	    },
+	    'nthSelector': function (t) {
+	      return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
+	    },
+	    'parentheses': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'percentage': function (t) {
+	      return _composite(t.content) + '%';
+	    },
+	    'pseudoClass': function (t) {
+	      return ':' + _composite(t.content);
+	    },
+	    'pseudoElement': function (t) {
+	      return '::' + _composite(t.content);
+	    },
+	    'singlelineComment': function (t) {
+	      return '/' + '/' + t.content;
+	    },
+	    'uri': function (t) {
+	      return 'url(' + _composite(t.content) + ')';
+	    },
+	    'variable': function (t) {
+	      return '@' + _composite(t.content);
+	    },
+	    'variablesList': function (t) {
+	      return _composite(t.content) + '...';
+	    }
+	  };
+
+	  return _t(tree);
+	};
+
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
+	// jscs:disable maximumLineLength
+
+	'use strict';
+
+	module.exports = function stringify(tree) {
+	  // TODO: Better error message
+	  if (!tree) throw new Error('We need tree to translate');
+
+	  function _t(tree) {
+	    var type = tree.type;
+	    if (_unique[type]) return _unique[type](tree);
+	    if (typeof tree.content === 'string') return tree.content;
+	    if (Array.isArray(tree.content)) return _composite(tree.content);
+	    return '';
+	  }
+
+	  function _composite(t, i) {
+	    if (!t) return '';
+
+	    var s = '';
+	    i = i || 0;
+	    for (; i < t.length; i++) s += _t(t[i]);
+	    return s;
+	  }
+
+	  var _unique = {
+	    'arguments': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'atkeyword': function (t) {
+	      return '@' + _composite(t.content);
+	    },
+	    'attributeSelector': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'block': function (t) {
+	      return _composite(t.content);
+	    },
+	    'brackets': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'class': function (t) {
+	      return '.' + _composite(t.content);
+	    },
+	    'color': function (t) {
+	      return '#' + t.content;
+	    },
+	    'expression': function (t) {
+	      return 'expression(' + t.content + ')';
+	    },
+	    'id': function (t) {
+	      return '#' + _composite(t.content);
+	    },
+	    'interpolation': function (t) {
+	      return '#{' + _composite(t.content) + '}';
+	    },
+	    'multilineComment': function (t) {
+	      return '/*' + t.content;
+	    },
+	    'nthSelector': function (t) {
+	      return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
+	    },
+	    'parentheses': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'percentage': function (t) {
+	      return _composite(t.content) + '%';
+	    },
+	    'placeholder': function (t) {
+	      return '%' + _composite(t.content);
+	    },
+	    'pseudoClass': function (t) {
+	      return ':' + _composite(t.content);
+	    },
+	    'pseudoElement': function (t) {
+	      return '::' + _composite(t.content);
+	    },
+	    'singlelineComment': function (t) {
+	      return '/' + '/' + t.content;
+	    },
+	    'uri': function (t) {
+	      return 'url(' + _composite(t.content) + ')';
+	    },
+	    'variable': function (t) {
+	      return '$' + _composite(t.content);
+	    },
+	    'variablesList': function (t) {
+	      return _composite(t.content) + '...';
+	    }
+	  };
+
+	  return _t(tree);
+	};
+
+/***/ },
+/* 6 */
+/***/ function(module, exports) {
+
+	// jscs:disable maximumLineLength
+
+	'use strict';
+
+	module.exports = function stringify(tree) {
+	  // TODO: Better error message
+	  if (!tree) throw new Error('We need tree to translate');
+
+	  function _t(tree) {
+	    var type = tree.type;
+	    if (_unique[type]) return _unique[type](tree);
+	    if (typeof tree.content === 'string') return tree.content;
+	    if (Array.isArray(tree.content)) return _composite(tree.content);
+	    return '';
+	  }
+
+	  function _composite(t, i) {
+	    if (!t) return '';
+
+	    var s = '';
+	    i = i || 0;
+	    for (; i < t.length; i++) s += _t(t[i]);
+	    return s;
+	  }
+
+	  var _unique = {
+	    'arguments': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'atkeyword': function (t) {
+	      return '@' + _composite(t.content);
+	    },
+	    'attributeSelector': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'block': function (t) {
+	      return '{' + _composite(t.content) + '}';
+	    },
+	    'brackets': function (t) {
+	      return '[' + _composite(t.content) + ']';
+	    },
+	    'class': function (t) {
+	      return '.' + _composite(t.content);
+	    },
+	    'color': function (t) {
+	      return '#' + t.content;
+	    },
+	    'expression': function (t) {
+	      return 'expression(' + t.content + ')';
+	    },
+	    'id': function (t) {
+	      return '#' + _composite(t.content);
+	    },
+	    'interpolation': function (t) {
+	      return '#{' + _composite(t.content) + '}';
+	    },
+	    'multilineComment': function (t) {
+	      return '/*' + t.content + '*/';
+	    },
+	    'nthSelector': function (t) {
+	      return ':' + _t(t.content[0]) + '(' + _composite(t.content.slice(1)) + ')';
+	    },
+	    'parentheses': function (t) {
+	      return '(' + _composite(t.content) + ')';
+	    },
+	    'percentage': function (t) {
+	      return _composite(t.content) + '%';
+	    },
+	    'placeholder': function (t) {
+	      return '%' + _composite(t.content);
+	    },
+	    'pseudoClass': function (t) {
+	      return ':' + _composite(t.content);
+	    },
+	    'pseudoElement': function (t) {
+	      return '::' + _composite(t.content);
+	    },
+	    'singlelineComment': function (t) {
+	      return '/' + '/' + t.content;
+	    },
+	    'uri': function (t) {
+	      return 'url(' + _composite(t.content) + ')';
+	    },
+	    'variable': function (t) {
+	      return '$' + _composite(t.content);
+	    },
+	    'variablesList': function (t) {
+	      return _composite(t.content) + '...';
+	    }
+	  };
+
+	  return _t(tree);
+	};
+
+/***/ },
+/* 7 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	var ParsingError = __webpack_require__(8);
+	var syntaxes = __webpack_require__(10);
+
+	var isInteger = Number.isInteger || function (value) {
+	  return typeof value === 'number' && Math.floor(value) === value;
+	};
+
+	/**
+	 * @param {String} css
+	 * @param {Object} options
+	 * @return {Object} AST
+	 */
+	function parser(css, options) {
+	  if (typeof css !== 'string') throw new Error('Please, pass a string to parse');else if (!css) return __webpack_require__(16)();
+
+	  var syntax = options && options.syntax || 'css';
+	  var context = options && options.context || 'stylesheet';
+	  var tabSize = options && options.tabSize;
+	  if (!isInteger(tabSize) || tabSize < 1) tabSize = 1;
+
+	  var syntaxParser = undefined;
+	  if (syntaxes[syntax]) {
+	    syntaxParser = syntaxes[syntax];
+	  } else {
+	    syntaxParser = syntaxes;
+	  }
+
+	  if (!syntaxParser) {
+	    var message = 'Syntax "' + syntax + '" is not supported yet, sorry';
+	    return console.error(message);
+	  }
+
+	  var getTokens = syntaxParser.tokenizer;
+	  var mark = syntaxParser.mark;
+	  var parse = syntaxParser.parse;
+
+	  var tokens = getTokens(css, tabSize);
+	  mark(tokens);
+
+	  var ast;
+	  try {
+	    ast = parse(tokens, context);
+	  } catch (e) {
+	    if (!e.syntax) throw e;
+	    throw new ParsingError(e, css);
+	  }
+
+	  return ast;
+	}
+
+	module.exports = parser;
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	var parserPackage = __webpack_require__(9);
+
+	/**
+	 * @param {Error} e
+	 * @param {String} css
+	 */
+	function ParsingError(e, css) {
+	  this.line = e.line;
+	  this.syntax = e.syntax;
+	  this.css_ = css;
+	}
+
+	ParsingError.prototype = Object.defineProperties({
+	  /**
+	   * @type {String}
+	   * @private
+	   */
+	  customMessage_: '',
+
+	  /**
+	   * @type {Number}
+	   */
+	  line: null,
+
+	  /**
+	   * @type {String}
+	   */
+	  name: 'Parsing error',
+
+	  /**
+	   * @type {String}
+	   */
+	  syntax: null,
+
+	  /**
+	   * @type {String}
+	   */
+	  version: parserPackage.version,
+
+	  /**
+	   * @return {String}
+	   */
+	  toString: function () {
+	    return [this.name + ': ' + this.message, '', this.context, '', 'Syntax: ' + this.syntax, 'Gonzales PE version: ' + this.version].join('\n');
+	  }
+	}, {
+	  context: { /**
+	              * @type {String}
+	              */
+
+	    get: function () {
+	      var LINES_AROUND = 2;
+
+	      var result = [];
+	      var currentLineNumber = this.line;
+	      var start = currentLineNumber - 1 - LINES_AROUND;
+	      var end = currentLineNumber + LINES_AROUND;
+	      var lines = this.css_.split(/\r\n|\r|\n/);
+
+	      for (var i = start; i < end; i++) {
+	        var line = lines[i];
+	        if (!line) continue;
+	        var ln = i + 1;
+	        var mark = ln === currentLineNumber ? '*' : ' ';
+	        result.push(ln + mark + '| ' + line);
+	      }
+
+	      return result.join('\n');
+	    },
+	    configurable: true,
+	    enumerable: true
+	  },
+	  message: {
+
+	    /**
+	     * @type {String}
+	     */
+
+	    get: function () {
+	      if (this.customMessage_) {
+	        return this.customMessage_;
+	      } else {
+	        var message = 'Please check validity of the block';
+	        if (typeof this.line === 'number') message += ' starting from line #' + this.line;
+	        return message;
+	      }
+	    },
+	    set: function (message) {
+	      this.customMessage_ = message;
+	    },
+	    configurable: true,
+	    enumerable: true
+	  }
+	});
+
+	module.exports = ParsingError;
+
+/***/ },
+/* 9 */
+/***/ function(module, exports) {
+
+	module.exports = {
+		"name": "gonzales-pe",
+		"description": "Gonzales Preprocessor Edition (fast CSS parser)",
+		"version": "3.3.1",
+		"homepage": "http://github.com/tonyganch/gonzales-pe",
+		"bugs": "http://github.com/tonyganch/gonzales-pe/issues",
+		"license": "MIT",
+		"author": {
+			"name": "Tony Ganch",
+			"email": "tonyganch+github@gmail.com",
+			"url": "http://tonyganch.com"
+		},
+		"main": "./lib/gonzales",
+		"repository": {
+			"type": "git",
+			"url": "http://github.com/tonyganch/gonzales-pe.git"
+		},
+		"scripts": {
+			"autofix-tests": "bash ./scripts/build.sh && bash ./scripts/autofix-tests.sh",
+			"build": "bash ./scripts/build.sh",
+			"init": "bash ./scripts/init.sh",
+			"log": "bash ./scripts/log.sh",
+			"prepublish": "bash ./scripts/prepublish.sh",
+			"postpublish": "bash ./scripts/postpublish.sh",
+			"test": "bash ./scripts/build.sh && bash ./scripts/test.sh",
+			"watch": "bash ./scripts/watch.sh"
+		},
+		"bin": {
+			"gonzales": "./bin/gonzales.js"
+		},
+		"dependencies": {
+			"minimist": "1.1.x"
+		},
+		"devDependencies": {
+			"babel-loader": "^5.3.2",
+			"coffee-script": "~1.7.1",
+			"jscs": "2.1.0",
+			"jshint": "2.8.0",
+			"json-loader": "^0.5.3",
+			"mocha": "2.2.x",
+			"webpack": "^1.12.2"
+		},
+		"engines": {
+			"node": ">=0.6.0"
+		}
+	};
+
+/***/ },
+/* 10 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	exports.__esModule = true;
+	exports['default'] = {
+	  mark: __webpack_require__(11),
+	  parse: __webpack_require__(13),
+	  stringify: __webpack_require__(6),
+	  tokenizer: __webpack_require__(15)
+	};
+	module.exports = exports['default'];
+
+/***/ },
+/* 11 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	var TokenType = __webpack_require__(12);
+
+	module.exports = (function () {
+	  /**
+	  * Mark whitespaces and comments
+	  */
+	  function markSC(tokens) {
+	    var tokensLength = tokens.length;
+	    var ws = -1; // Flag for whitespaces
+	    var sc = -1; // Flag for whitespaces and comments
+	    var t = undefined; // Current token
+
+	    // For every token in the token list, mark spaces and line breaks
+	    // as spaces (set both `ws` and `sc` flags). Mark multiline comments
+	    // with `sc` flag.
+	    // If there are several spaces or tabs or line breaks or multiline
+	    // comments in a row, group them: take the last one's index number
+	    // and save it to the first token in the group as a reference:
+	    // e.g., `ws_last = 7` for a group of whitespaces or `sc_last = 9`
+	    // for a group of whitespaces and comments.
+	    for (var i = 0; i < tokensLength; i++) {
+	      t = tokens[i];
+	      switch (t.type) {
+	        case TokenType.Space:
+	        case TokenType.Tab:
+	        case TokenType.Newline:
+	          t.ws = true;
+	          t.sc = true;
+
+	          if (ws === -1) ws = i;
+	          if (sc === -1) sc = i;
+
+	          break;
+	        case TokenType.CommentML:
+	        case TokenType.CommentSL:
+	          if (ws !== -1) {
+	            tokens[ws].ws_last = i - 1;
+	            ws = -1;
+	          }
+
+	          t.sc = true;
+
+	          break;
+	        default:
+	          if (ws !== -1) {
+	            tokens[ws].ws_last = i - 1;
+	            ws = -1;
+	          }
+
+	          if (sc !== -1) {
+	            tokens[sc].sc_last = i - 1;
+	            sc = -1;
+	          }
+	      }
+	    }
+
+	    if (ws !== -1) tokens[ws].ws_last = i - 1;
+	    if (sc !== -1) tokens[sc].sc_last = i - 1;
+	  }
+
+	  /**
+	  * Pair brackets
+	  */
+	  function markBrackets(tokens) {
+	    var tokensLength = tokens.length;
+	    var ps = []; // Parentheses
+	    var sbs = []; // Square brackets
+	    var cbs = []; // Curly brackets
+	    var t = undefined; // Current token
+
+	    // For every token in the token list, if we meet an opening (left)
+	    // bracket, push its index number to a corresponding array.
+	    // If we then meet a closing (right) bracket, look at the corresponding
+	    // array. If there are any elements (records about previously met
+	    // left brackets), take a token of the last left bracket (take
+	    // the last index number from the array and find a token with
+	    // this index number) and save right bracket's index as a reference:
+	    for (var i = 0; i < tokensLength; i++) {
+	      t = tokens[i];
+	      switch (t.type) {
+	        case TokenType.LeftParenthesis:
+	          ps.push(i);
+	          break;
+	        case TokenType.RightParenthesis:
+	          if (ps.length) {
+	            t.left = ps.pop();
+	            tokens[t.left].right = i;
+	          }
+	          break;
+	        case TokenType.LeftSquareBracket:
+	          sbs.push(i);
+	          break;
+	        case TokenType.RightSquareBracket:
+	          if (sbs.length) {
+	            t.left = sbs.pop();
+	            tokens[t.left].right = i;
+	          }
+	          break;
+	        case TokenType.LeftCurlyBracket:
+	          cbs.push(i);
+	          break;
+	        case TokenType.RightCurlyBracket:
+	          if (cbs.length) {
+	            t.left = cbs.pop();
+	            tokens[t.left].right = i;
+	          }
+	          break;
+	      }
+	    }
+	  }
+
+	  return function (tokens) {
+	    markBrackets(tokens);
+	    markSC(tokens);
+	  };
+	})();
+
+/***/ },
+/* 12 */
+/***/ function(module, exports) {
+
+	// jscs:disable
+
+	'use strict';
+
+	module.exports = {
+	    StringSQ: 'StringSQ',
+	    StringDQ: 'StringDQ',
+	    CommentML: 'CommentML',
+	    CommentSL: 'CommentSL',
+
+	    Newline: 'Newline',
+	    Space: 'Space',
+	    Tab: 'Tab',
+
+	    ExclamationMark: 'ExclamationMark', // !
+	    QuotationMark: 'QuotationMark', // "
+	    NumberSign: 'NumberSign', // #
+	    DollarSign: 'DollarSign', // $
+	    PercentSign: 'PercentSign', // %
+	    Ampersand: 'Ampersand', // &
+	    Apostrophe: 'Apostrophe', // '
+	    LeftParenthesis: 'LeftParenthesis', // (
+	    RightParenthesis: 'RightParenthesis', // )
+	    Asterisk: 'Asterisk', // *
+	    PlusSign: 'PlusSign', // +
+	    Comma: 'Comma', // ,
+	    HyphenMinus: 'HyphenMinus', // -
+	    FullStop: 'FullStop', // .
+	    Solidus: 'Solidus', // /
+	    Colon: 'Colon', // :
+	    Semicolon: 'Semicolon', // ;
+	    LessThanSign: 'LessThanSign', // <
+	    EqualsSign: 'EqualsSign', // =
+	    EqualitySign: 'EqualitySign', // ==
+	    InequalitySign: 'InequalitySign', // !=
+	    GreaterThanSign: 'GreaterThanSign', // >
+	    QuestionMark: 'QuestionMark', // ?
+	    CommercialAt: 'CommercialAt', // @
+	    LeftSquareBracket: 'LeftSquareBracket', // [
+	    ReverseSolidus: 'ReverseSolidus', // \
+	    RightSquareBracket: 'RightSquareBracket', // ]
+	    CircumflexAccent: 'CircumflexAccent', // ^
+	    LowLine: 'LowLine', // _
+	    LeftCurlyBracket: 'LeftCurlyBracket', // {
+	    VerticalLine: 'VerticalLine', // |
+	    RightCurlyBracket: 'RightCurlyBracket', // }
+	    Tilde: 'Tilde', // ~
+
+	    Identifier: 'Identifier',
+	    DecimalNumber: 'DecimalNumber'
+	};
+
+/***/ },
+/* 13 */
+/***/ function(module, exports, __webpack_require__) {
+
+	// jscs:disable maximumLineLength
+	'use strict';var Node=__webpack_require__(1);var NodeType=__webpack_require__(14);var TokenType=__webpack_require__(12);var tokens=undefined;var tokensLength=undefined;var pos=undefined;var contexts={'arguments':function(){return checkArguments(pos) && getArguments();},'atkeyword':function(){return checkAtkeyword(pos) && getAtkeyword();},'atrule':function(){return checkAtrule(pos) && getAtrule();},'block':function(){return checkBlock(pos) && getBlock();},'brackets':function(){return checkBrackets(pos) && getBrackets();},'class':function(){return checkClass(pos) && getClass();},'combinator':function(){return checkCombinator(pos) && getCombinator();},'commentML':function(){return checkCommentML(pos) && getCommentML();},'commentSL':function(){return checkCommentSL(pos) && getCommentSL();},'condition':function(){return checkCondition(pos) && getCondition();},'conditionalStatement':function(){return checkConditionalStatement(pos) && getConditionalStatement();},'declaration':function(){return checkDeclaration(pos) && getDeclaration();},'declDelim':function(){return checkDeclDelim(pos) && getDeclDelim();},'default':function(){return checkDefault(pos) && getDefault();},'delim':function(){return checkDelim(pos) && getDelim();},'dimension':function(){return checkDimension(pos) && getDimension();},'expression':function(){return checkExpression(pos) && getExpression();},'extend':function(){return checkExtend(pos) && getExtend();},'function':function(){return checkFunction(pos) && getFunction();},'global':function(){return checkGlobal(pos) && getGlobal();},'ident':function(){return checkIdent(pos) && getIdent();},'important':function(){return checkImportant(pos) && getImportant();},'include':function(){return checkInclude(pos) && getInclude();},'interpolation':function(){return checkInterpolation(pos) && getInterpolation();},'loop':function(){return checkLoop(pos) && getLoop();},'mixin':function(){return checkMixin(pos) && getMixin();},'namespace':function(){return checkNamespace(pos) && getNamespace();},'number':function(){return checkNumber(pos) && getNumber();},'operator':function(){return checkOperator(pos) && getOperator();},'optional':function(){return checkOptional(pos) && getOptional();},'parentheses':function(){return checkParentheses(pos) && getParentheses();},'parentselector':function(){return checkParentSelector(pos) && getParentSelector();},'percentage':function(){return checkPercentage(pos) && getPercentage();},'placeholder':function(){return checkPlaceholder(pos) && getPlaceholder();},'progid':function(){return checkProgid(pos) && getProgid();},'property':function(){return checkProperty(pos) && getProperty();},'propertyDelim':function(){return checkPropertyDelim(pos) && getPropertyDelim();},'pseudoc':function(){return checkPseudoc(pos) && getPseudoc();},'pseudoe':function(){return checkPseudoe(pos) && getPseudoe();},'ruleset':function(){return checkRuleset(pos) && getRuleset();},'s':function(){return checkS(pos) && getS();},'selector':function(){return checkSelector(pos) && getSelector();},'shash':function(){return checkShash(pos) && getShash();},'string':function(){return checkString(pos) && getString();},'stylesheet':function(){return checkStylesheet(pos) && getStylesheet();},'unary':function(){return checkUnary(pos) && getUnary();},'uri':function(){return checkUri(pos) && getUri();},'value':function(){return checkValue(pos) && getValue();},'variable':function(){return checkVariable(pos) && getVariable();},'variableslist':function(){return checkVariablesList(pos) && getVariablesList();},'vhash':function(){return checkVhash(pos) && getVhash();}}; /**
+	 * Stop parsing and display error
+	 * @param {Number=} i Token's index number
+	 */function throwError(i){var ln=i?tokens[i].ln:tokens[pos].ln;throw {line:ln,syntax:'scss'};} /**
+	 * @param {Object} exclude
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkExcluding(exclude,i){var start=i;while(i < tokensLength) {if(exclude[tokens[i++].type])break;}return i - start - 2;} /**
+	 * @param {Number} start
+	 * @param {Number} finish
+	 * @returns {String}
+	 */function joinValues(start,finish){var s='';for(var i=start;i < finish + 1;i++) {s += tokens[i].value;}return s;} /**
+	 * @param {Number} start
+	 * @param {Number} num
+	 * @returns {String}
+	 */function joinValues2(start,num){if(start + num - 1 >= tokensLength)return;var s='';for(var i=0;i < num;i++) {s += tokens[start + i].value;}return s;}function getLastPosition(content,line,column,colOffset){return typeof content === 'string'?getLastPositionForString(content,line,column,colOffset):getLastPositionForArray(content,line,column,colOffset);}function getLastPositionForString(content,line,column,colOffset){var position=[];if(!content){position = [line,column];if(colOffset)position[1] += colOffset - 1;return position;}var lastLinebreak=content.lastIndexOf('\n');var endsWithLinebreak=lastLinebreak === content.length - 1;var splitContent=content.split('\n');var linebreaksCount=splitContent.length - 1;var prevLinebreak=linebreaksCount === 0 || linebreaksCount === 1?-1:content.length - splitContent[linebreaksCount - 1].length - 2; // Line:
+	var offset=endsWithLinebreak?linebreaksCount - 1:linebreaksCount;position[0] = line + offset; // Column:
+	if(endsWithLinebreak){offset = prevLinebreak !== -1?content.length - prevLinebreak:content.length - 1;}else {offset = linebreaksCount !== 0?content.length - lastLinebreak - column - 1:content.length - 1;}position[1] = column + offset;if(!colOffset)return position;if(endsWithLinebreak){position[0]++;position[1] = colOffset;}else {position[1] += colOffset;}return position;}function getLastPositionForArray(content,line,column,colOffset){var position;if(content.length === 0){position = [line,column];}else {var c=content[content.length - 1];if(c.hasOwnProperty('end')){position = [c.end.line,c.end.column];}else {position = getLastPosition(c.content,line,column);}}if(!colOffset)return position;if(tokens[pos - 1].type !== 'Newline'){position[1] += colOffset;}else {position[0]++;position[1] = 1;}return position;}function newNode(type,content,line,column,end){if(!end)end = getLastPosition(content,line,column);return new Node({type:type,content:content,start:{line:line,column:column},end:{line:end[0],column:end[1]},syntax:'scss'});} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkAny(i){return checkBrackets(i) || checkParentheses(i) || checkString(i) || checkVariablesList(i) || checkVariable(i) || checkPlaceholder(i) || checkPercentage(i) || checkDimension(i) || checkNumber(i) || checkUri(i) || checkExpression(i) || checkFunction(i) || checkInterpolation(i) || checkIdent(i) || checkClass(i) || checkUnary(i);} /**
+	 * @returns {Array}
+	 */function getAny(){if(checkBrackets(pos))return getBrackets();else if(checkParentheses(pos))return getParentheses();else if(checkString(pos))return getString();else if(checkVariablesList(pos))return getVariablesList();else if(checkVariable(pos))return getVariable();else if(checkPlaceholder(pos))return getPlaceholder();else if(checkPercentage(pos))return getPercentage();else if(checkDimension(pos))return getDimension();else if(checkNumber(pos))return getNumber();else if(checkUri(pos))return getUri();else if(checkExpression(pos))return getExpression();else if(checkFunction(pos))return getFunction();else if(checkInterpolation(pos))return getInterpolation();else if(checkIdent(pos))return getIdent();else if(checkClass(pos))return getClass();else if(checkUnary(pos))return getUnary();} /**
+	 * Check if token is part of mixin's arguments.
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of arguments
+	 */function checkArguments(i){var start=i;var l=undefined;if(i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis)return 0;i++;while(i < tokens[start].right) {if(l = checkArgument(i))i += l;else return 0;}return tokens[start].right - start + 1;} /**
+	 * Check if token is valid to be part of arguments list
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of argument
+	 */function checkArgument(i){return checkBrackets(i) || checkParentheses(i) || checkDeclaration(i) || checkFunction(i) || checkVariablesList(i) || checkVariable(i) || checkSC(i) || checkDelim(i) || checkDeclDelim(i) || checkString(i) || checkPercentage(i) || checkDimension(i) || checkNumber(i) || checkUri(i) || checkInterpolation(i) || checkIdent(i) || checkVhash(i) || checkOperator(i) || checkUnary(i);} /**
+	 * @returns {Array} Node that is part of arguments list
+	 */function getArgument(){if(checkBrackets(pos))return getBrackets();else if(checkParentheses(pos))return getParentheses();else if(checkDeclaration(pos))return getDeclaration();else if(checkFunction(pos))return getFunction();else if(checkVariablesList(pos))return getVariablesList();else if(checkVariable(pos))return getVariable();else if(checkSC(pos))return getSC();else if(checkDelim(pos))return getDelim();else if(checkDeclDelim(pos))return getDeclDelim();else if(checkString(pos))return getString();else if(checkPercentage(pos))return getPercentage();else if(checkDimension(pos))return getDimension();else if(checkNumber(pos))return getNumber();else if(checkUri(pos))return getUri();else if(checkInterpolation(pos))return getInterpolation();else if(checkIdent(pos))return getIdent();else if(checkVhash(pos))return getVhash();else if(checkOperator(pos))return getOperator();else if(checkUnary(pos))return getUnary();} /**
+	 * Check if token is part of an @-word (e.g. `@import`, `@include`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkAtkeyword(i){var l; // Check that token is `@`:
+	if(i >= tokensLength || tokens[i++].type !== TokenType.CommercialAt)return 0;return (l = checkIdentOrInterpolation(i))?l + 1:0;} /**
+	 * Get node with @-word
+	 * @returns {Array} `['atkeyword', ['ident', x]]` where `x` is
+	 *      an identifier without
+	 *      `@` (e.g. `import`, `include`)
+	 */function getAtkeyword(){var startPos=pos;var x=undefined;pos++;x = getIdentOrInterpolation();var token=tokens[startPos];return newNode(NodeType.AtkeywordType,x,token.ln,token.col);} /**
+	 * Check if token is a part of an @-rule
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of @-rule
+	 */function checkAtrule(i){var l;if(i >= tokensLength)return 0; // If token already has a record of being part of an @-rule,
+	// return the @-rule's length:
+	if(tokens[i].atrule_l !== undefined)return tokens[i].atrule_l; // If token is part of an @-rule, save the rule's type to token:
+	if(l = checkKeyframesRule(i))tokens[i].atrule_type = 4;else if(l = checkAtruler(i))tokens[i].atrule_type = 1; // @-rule with ruleset
+	else if(l = checkAtruleb(i))tokens[i].atrule_type = 2; // Block @-rule
+	else if(l = checkAtrules(i))tokens[i].atrule_type = 3; // Single-line @-rule
+	else return 0; // If token is part of an @-rule, save the rule's length to token:
+	tokens[i].atrule_l = l;return l;} /**
+	 * Get node with @-rule
+	 * @returns {Array}
+	 */function getAtrule(){switch(tokens[pos].atrule_type){case 1:return getAtruler(); // @-rule with ruleset
+	case 2:return getAtruleb(); // Block @-rule
+	case 3:return getAtrules(); // Single-line @-rule
+	case 4:return getKeyframesRule();}} /**
+	 * Check if token is part of a block @-rule
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the @-rule
+	 */function checkAtruleb(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;if(l = checkTsets(i))i += l;if(l = checkBlock(i))i += l;else return 0;return i - start;} /**
+	 * Get node with a block @-rule
+	 * @returns {Array} `['atruleb', ['atkeyword', x], y, ['block', z]]`
+	 */function getAtruleb(){var startPos=pos;var x=undefined;x = [getAtkeyword()].concat(getTsets()).concat([getBlock()]);var token=tokens[startPos];return newNode(NodeType.AtruleType,x,token.ln,token.col);} /**
+	 * Check if token is part of an @-rule with ruleset
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the @-rule
+	 */function checkAtruler(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;if(l = checkTsets(i))i += l;if(i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket)i++;else return 0;if(l = checkAtrulers(i))i += l;if(i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket)i++;else return 0;return i - start;} /**
+	 * Get node with an @-rule with ruleset
+	 * @returns {Array} ['atruler', ['atkeyword', x], y, z]
+	 */function getAtruler(){var startPos=pos;var x=undefined;x = [getAtkeyword()].concat(getTsets());x.push(getAtrulers());var token=tokens[startPos];return newNode(NodeType.AtruleType,x,token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkAtrulers(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;while(l = checkRuleset(i) || checkAtrule(i) || checkSC(i)) {i += l;}if(i < tokensLength)tokens[i].atrulers_end = 1;return i - start;} /**
+	 * @returns {Array} `['atrulers', x]`
+	 */function getAtrulers(){var startPos=pos;var x=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;x = getSC();while(!tokens[pos].atrulers_end) {if(checkSC(pos))x = x.concat(getSC());else if(checkAtrule(pos))x.push(getAtrule());else if(checkRuleset(pos))x.push(getRuleset());}x = x.concat(getSC());var end=getLastPosition(x,line,column,1);pos++;return newNode(NodeType.BlockType,x,token.ln,token.col,end);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkAtrules(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;if(l = checkTsets(i))i += l;return i - start;} /**
+	 * @returns {Array} `['atrules', ['atkeyword', x], y]`
+	 */function getAtrules(){var startPos=pos;var x=undefined;x = [getAtkeyword()].concat(getTsets());var token=tokens[startPos];return newNode(NodeType.AtruleType,x,token.ln,token.col);} /**
+	 * Check if token is part of a block (e.g. `{...}`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the block
+	 */function checkBlock(i){return i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket?tokens[i].right - i + 1:0;} /**
+	 * Get node with a block
+	 * @returns {Array} `['block', x]`
+	 */function getBlock(){var startPos=pos;var end=tokens[pos].right;var x=[];var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;while(pos < end) {if(checkBlockdecl(pos))x = x.concat(getBlockdecl());else throwError();}var end_=getLastPosition(x,line,column,1);pos = end + 1;return newNode(NodeType.BlockType,x,token.ln,token.col,end_);} /**
+	 * Check if token is part of a declaration (property-value pair)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the declaration
+	 */function checkBlockdecl(i){var l;if(i >= tokensLength)return 0;if(l = checkBlockdecl1(i))tokens[i].bd_type = 1;else if(l = checkBlockdecl2(i))tokens[i].bd_type = 2;else if(l = checkBlockdecl3(i))tokens[i].bd_type = 3;else if(l = checkBlockdecl4(i))tokens[i].bd_type = 4;else return 0;return l;} /**
+	 * @returns {Array}
+	 */function getBlockdecl(){switch(tokens[pos].bd_type){case 1:return getBlockdecl1();case 2:return getBlockdecl2();case 3:return getBlockdecl3();case 4:return getBlockdecl4();}} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkBlockdecl1(i){var start=i;var l=undefined;if(l = checkSC(i))i += l;if(l = checkConditionalStatement(i))tokens[i].bd_kind = 1;else if(l = checkInclude(i))tokens[i].bd_kind = 2;else if(l = checkExtend(i))tokens[i].bd_kind = 4;else if(l = checkLoop(i))tokens[i].bd_kind = 3;else if(l = checkAtrule(i))tokens[i].bd_kind = 6;else if(l = checkRuleset(i))tokens[i].bd_kind = 7;else if(l = checkDeclaration(i))tokens[i].bd_kind = 5;else return 0;i += l;if(i < tokensLength && (l = checkDeclDelim(i)))i += l;else return 0;if(l = checkSC(i))i += l;return i - start;} /**
+	 * @returns {Array}
+	 */function getBlockdecl1(){var sc=getSC();var x=undefined;switch(tokens[pos].bd_kind){case 1:x = getConditionalStatement();break;case 2:x = getInclude();break;case 3:x = getLoop();break;case 4:x = getExtend();break;case 5:x = getDeclaration();break;case 6:x = getAtrule();break;case 7:x = getRuleset();break;}return sc.concat([x]).concat([getDeclDelim()]).concat(getSC());} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkBlockdecl2(i){var start=i;var l=undefined;if(l = checkSC(i))i += l;if(l = checkConditionalStatement(i))tokens[i].bd_kind = 1;else if(l = checkInclude(i))tokens[i].bd_kind = 2;else if(l = checkExtend(i))tokens[i].bd_kind = 4;else if(l = checkMixin(i))tokens[i].bd_kind = 8;else if(l = checkLoop(i))tokens[i].bd_kind = 3;else if(l = checkAtrule(i))tokens[i].bd_kind = 6;else if(l = checkRuleset(i))tokens[i].bd_kind = 7;else if(l = checkDeclaration(i))tokens[i].bd_kind = 5;else return 0;i += l;if(l = checkSC(i))i += l;return i - start;} /**
+	 * @returns {Array}
+	 */function getBlockdecl2(){var sc=getSC();var x=undefined;switch(tokens[pos].bd_kind){case 1:x = getConditionalStatement();break;case 2:x = getInclude();break;case 3:x = getLoop();break;case 4:x = getExtend();break;case 5:x = getDeclaration();break;case 6:x = getAtrule();break;case 7:x = getRuleset();break;case 8:x = getMixin();break;}return sc.concat([x]).concat(getSC());} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkBlockdecl3(i){var start=i;var l=undefined;if(l = checkSC(i))i += l;if(l = checkDeclDelim(i))i += l;else return 0;if(l = checkSC(i))i += l;return i - start;} /**
+	 * @returns {Array} `[s0, ['declDelim'], s1]` where `s0` and `s1` are
+	 *      are optional whitespaces.
+	 */function getBlockdecl3(){return getSC().concat([getDeclDelim()]).concat(getSC());} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkBlockdecl4(i){return checkSC(i);} /**
+	 * @returns {Array}
+	 */function getBlockdecl4(){return getSC();} /**
+	 * Check if token is part of text inside square brackets, e.g. `[1]`
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkBrackets(i){if(i >= tokensLength || tokens[i].type !== TokenType.LeftSquareBracket)return 0;return tokens[i].right - i + 1;} /**
+	 * Get node with text inside parentheses or square brackets (e.g. `(1)`)
+	 * @return {Node}
+	 */function getBrackets(){var startPos=pos;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;var tsets=getTsets();var end=getLastPosition(tsets,line,column,1);pos++;return newNode(NodeType.BracketsType,tsets,token.ln,token.col,end);} /**
+	 * Check if token is part of a class selector (e.g. `.abc`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the class selector
+	 */function checkClass(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(tokens[i].class_l)return tokens[i].class_l;if(tokens[i++].type !== TokenType.FullStop)return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;return i - start;} /**
+	 * Get node with a class selector
+	 * @returns {Array} `['class', ['ident', x]]` where x is a class's
+	 *      identifier (without `.`, e.g. `abc`).
+	 */function getClass(){var startPos=pos;var x=[];pos++;x = x.concat(getIdentOrInterpolation());var token=tokens[startPos];return newNode(NodeType.ClassType,x,token.ln,token.col);}function checkCombinator(i){if(i >= tokensLength)return 0;var l=undefined;if(l = checkCombinator1(i))tokens[i].combinatorType = 1;else if(l = checkCombinator2(i))tokens[i].combinatorType = 2;else if(l = checkCombinator3(i))tokens[i].combinatorType = 3;return l;}function getCombinator(){var type=tokens[pos].combinatorType;if(type === 1)return getCombinator1();if(type === 2)return getCombinator2();if(type === 3)return getCombinator3();} /**
+	 * (1) `||`
+	 */function checkCombinator1(i){if(tokens[i].type === TokenType.VerticalLine && tokens[i + 1].type === TokenType.VerticalLine)return 2;else return 0;}function getCombinator1(){var type=NodeType.CombinatorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content='||';pos += 2;return newNode(type,content,line,column);} /**
+	 * (1) `>`
+	 * (2) `+`
+	 * (3) `~`
+	 */function checkCombinator2(i){var type=tokens[i].type;if(type === TokenType.PlusSign || type === TokenType.GreaterThanSign || type === TokenType.Tilde)return 1;else return 0;}function getCombinator2(){var type=NodeType.CombinatorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=tokens[pos++].value;return newNode(type,content,line,column);} /**
+	 * (1) `/panda/`
+	 */function checkCombinator3(i){var start=i;if(tokens[i].type === TokenType.Solidus)i++;else return 0;var l=undefined;if(l = checkIdent(i))i += l;else return 0;if(tokens[i].type === TokenType.Solidus)i++;else return 0;return i - start;}function getCombinator3(){var type=NodeType.CombinatorType;var token=tokens[pos];var line=token.ln;var column=token.col; // Skip `/`.
+	pos++;var ident=getIdent(); // Skip `/`.
+	pos++;var content='/' + ident.content + '/';return newNode(type,content,line,column);} /**
+	 * Check if token is a multiline comment.
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is a multiline comment, otherwise `0`
+	 */function checkCommentML(i){return i < tokensLength && tokens[i].type === TokenType.CommentML?1:0;} /**
+	 * Get node with a multiline comment
+	 * @returns {Array} `['commentML', x]` where `x`
+	 *      is the comment's text (without `/*` and `* /`).
+	 */function getCommentML(){var startPos=pos;var s=tokens[pos].value.substring(2);var l=s.length;var token=tokens[startPos];var line=token.ln;var column=token.col;if(s.charAt(l - 2) === '*' && s.charAt(l - 1) === '/')s = s.substring(0,l - 2);var end=getLastPosition(s,line,column,2);if(end[0] === line)end[1] += 2;pos++;return newNode(NodeType.CommentMLType,s,token.ln,token.col,end);} /**
+	 * Check if token is part of a single-line comment.
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is a single-line comment, otherwise `0`
+	 */function checkCommentSL(i){return i < tokensLength && tokens[i].type === TokenType.CommentSL?1:0;} /**
+	 * Get node with a single-line comment.
+	 * @returns {Array} `['commentSL', x]` where `x` is comment's message
+	 *      (without `//`)
+	 */function getCommentSL(){var startPos=pos;var x=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;x = tokens[pos++].value.substring(2);var end=getLastPosition(x,line,column + 2);return newNode(NodeType.CommentSLType,x,token.ln,token.col,end);} /**
+	 * Check if token is part of a condition
+	 * (e.g. `@if ...`, `@else if ...` or `@else ...`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the condition
+	 */function checkCondition(i){var start=i;var l=undefined;var _i=undefined;var s=undefined;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;if(['if','else'].indexOf(tokens[start + 1].value) < 0)return 0;while(i < tokensLength) {if(l = checkBlock(i))break;s = checkSC(i);_i = i + s;if(l = _checkCondition(_i))i += l + s;else break;}return i - start;}function _checkCondition(i){return checkVariable(i) || checkNumber(i) || checkInterpolation(i) || checkIdent(i) || checkOperator(i) || checkCombinator(i) || checkString(i);} /**
+	 * Get node with a condition.
+	 * @returns {Array} `['condition', x]`
+	 */function getCondition(){var startPos=pos;var x=[];var s;var _pos;x.push(getAtkeyword());while(pos < tokensLength) {if(checkBlock(pos))break;s = checkSC(pos);_pos = pos + s;if(!_checkCondition(_pos))break;if(s)x = x.concat(getSC());x.push(_getCondition());}var token=tokens[startPos];return newNode(NodeType.ConditionType,x,token.ln,token.col);}function _getCondition(){if(checkVariable(pos))return getVariable();if(checkNumber(pos))return getNumber();if(checkInterpolation(pos))return getInterpolation();if(checkIdent(pos))return getIdent();if(checkOperator(pos))return getOperator();if(checkCombinator(pos))return getCombinator();if(checkString(pos))return getString();} /**
+	 * Check if token is part of a conditional statement
+	 * (e.g. `@if ... {} @else if ... {} @else ... {}`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the condition
+	 */function checkConditionalStatement(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkCondition(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkBlock(i))i += l;else return 0;return i - start;} /**
+	 * Get node with a condition.
+	 * @returns {Array} `['condition', x]`
+	 */function getConditionalStatement(){var startPos=pos;var x=[];x.push(getCondition());x = x.concat(getSC());x.push(getBlock());var token=tokens[startPos];return newNode(NodeType.ConditionalStatementType,x,token.ln,token.col);} /**
+	 * Check if token is part of a declaration (property-value pair)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the declaration
+	 */function checkDeclaration(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkProperty(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkPropertyDelim(i))i++;else return 0;if(l = checkSC(i))i += l;if(l = checkValue(i))i += l;else return 0;return i - start;} /**
+	 * Get node with a declaration
+	 * @returns {Array} `['declaration', ['property', x], ['propertyDelim'],
+	 *       ['value', y]]`
+	 */function getDeclaration(){var startPos=pos;var x=[];x.push(getProperty());x = x.concat(getSC());x.push(getPropertyDelim());x = x.concat(getSC());x.push(getValue());var token=tokens[startPos];return newNode(NodeType.DeclarationType,x,token.ln,token.col);} /**
+	 * Check if token is a semicolon
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is a semicolon, otherwise `0`
+	 */function checkDeclDelim(i){return i < tokensLength && tokens[i].type === TokenType.Semicolon?1:0;} /**
+	 * Get node with a semicolon
+	 * @returns {Array} `['declDelim']`
+	 */function getDeclDelim(){var startPos=pos++;var token=tokens[startPos];return newNode(NodeType.DeclDelimType,';',token.ln,token.col);} /**
+	 * Check if token if part of `!default` word.
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the `!default` word
+	 */function checkDefault(i){var start=i;var l=undefined;if(i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark)return 0;if(l = checkSC(i))i += l;if(tokens[i].value === 'default'){tokens[start].defaultEnd = i;return i - start + 1;}else {return 0;}} /**
+	 * Get node with a `!default` word
+	 * @returns {Array} `['default', sc]` where `sc` is optional whitespace
+	 */function getDefault(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.defaultEnd);pos = token.defaultEnd + 1;return newNode(NodeType.DefaultType,content,line,column);} /**
+	 * Check if token is a comma
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is a comma, otherwise `0`
+	 */function checkDelim(i){return i < tokensLength && tokens[i].type === TokenType.Comma?1:0;} /**
+	 * Get node with a comma
+	 * @returns {Array} `['delim']`
+	 */function getDelim(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.DelimType,',',token.ln,token.col);} /**
+	 * Check if token is part of a number with dimension unit (e.g. `10px`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkDimension(i){var ln=checkNumber(i);var li=undefined;if(i >= tokensLength || !ln || i + ln >= tokensLength)return 0;return (li = checkNmName2(i + ln))?ln + li:0;} /**
+	 * Get node of a number with dimension unit
+	 * @returns {Array} `['dimension', ['number', x], ['ident', y]]` where
+	 *      `x` is a number converted to string (e.g. `'10'`) and `y` is
+	 *      a dimension unit (e.g. `'px'`).
+	 */function getDimension(){var startPos=pos;var x=[getNumber()];var token=tokens[pos];var ident=newNode(NodeType.IdentType,getNmName2(),token.ln,token.col);x.push(ident);token = tokens[startPos];return newNode(NodeType.DimensionType,x,token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkExpression(i){var start=i;if(i >= tokensLength || tokens[i++].value !== 'expression' || i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis)return 0;return tokens[i].right - start + 1;} /**
+	 * @returns {Array}
+	 */function getExpression(){var startPos=pos;var e;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;e = joinValues(pos + 1,tokens[pos].right - 1);var end=getLastPosition(e,line,column,1);if(end[0] === line)end[1] += 11;pos = tokens[pos].right + 1;return newNode(NodeType.ExpressionType,e,token.ln,token.col,end);}function checkExtend(i){var l=0;if(l = checkExtend1(i))tokens[i].extend_child = 1;else if(l = checkExtend2(i))tokens[i].extend_child = 2;return l;}function getExtend(){var type=tokens[pos].extend_child;if(type === 1)return getExtend1();else if(type === 2)return getExtend2();} /**
+	 * Checks if token is part of an extend with `!optional` flag.
+	 * @param {Number} i
+	 */function checkExtend1(i){var start=i;var l;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;if(tokens[start + 1].value !== 'extend')return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkSelectorsGroup(i))i += l;else return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkOptional(i))i += l;else return 0;return i - start;}function getExtend1(){var startPos=pos;var x=[].concat([getAtkeyword()],getSC(),getSelectorsGroup(),getSC(),[getOptional()]);var token=tokens[startPos];return newNode(NodeType.ExtendType,x,token.ln,token.col);} /**
+	 * Checks if token is part of an extend without `!optional` flag.
+	 * @param {Number} i
+	 */function checkExtend2(i){var start=i;var l;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;if(tokens[start + 1].value !== 'extend')return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkSelectorsGroup(i))i += l;else return 0;return i - start;}function getExtend2(){var startPos=pos;var x=[].concat([getAtkeyword()],getSC(),getSelectorsGroup());var token=tokens[startPos];return newNode(NodeType.ExtendType,x,token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkFunction(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;return i < tokensLength && tokens[i].type === TokenType.LeftParenthesis?tokens[i].right - start + 1:0;} /**
+	 * @returns {Array}
+	 */function getFunction(){var startPos=pos;var x=getIdentOrInterpolation();var body=undefined;body = getArguments();x.push(body);var token=tokens[startPos];return newNode(NodeType.FunctionType,x,token.ln,token.col);} /**
+	 * @returns {Array}
+	 */function getArguments(){var startPos=pos;var x=[];var body=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;while(pos < tokensLength && tokens[pos].type !== TokenType.RightParenthesis) {if(checkDeclaration(pos))x.push(getDeclaration());else if(checkArgument(pos)){body = getArgument();if(typeof body.content === 'string')x.push(body);else x = x.concat(body);}else if(checkClass(pos))x.push(getClass());else throwError();}var end=getLastPosition(x,line,column,1);pos++;return newNode(NodeType.ArgumentsType,x,token.ln,token.col,end);} /**
+	 * Check if token is part of an identifier
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the identifier
+	 */function checkIdent(i){var start=i;var interpolations=[];var wasIdent=undefined;var wasInt=false;var l=undefined;if(i >= tokensLength)return 0; // Check if token is part of an identifier starting with `_`:
+	if(tokens[i].type === TokenType.LowLine)return checkIdentLowLine(i);if(tokens[i].type === TokenType.HyphenMinus && tokens[i + 1].type === TokenType.DecimalNumber)return 0; // If token is a character, `-`, `$` or `*`, skip it & continue:
+	if(l = _checkIdent(i))i += l;else return 0; // Remember if previous token's type was identifier:
+	wasIdent = tokens[i - 1].type === TokenType.Identifier;while(i < tokensLength) {l = _checkIdent(i);if(!l)break;wasIdent = true;i += l;}if(!wasIdent && !wasInt && tokens[start].type !== TokenType.Asterisk)return 0;tokens[start].ident_last = i - 1;if(interpolations.length)tokens[start].interpolations = interpolations;return i - start;}function _checkIdent(i){if(tokens[i].type === TokenType.HyphenMinus || tokens[i].type === TokenType.Identifier || tokens[i].type === TokenType.DollarSign || tokens[i].type === TokenType.LowLine || tokens[i].type === TokenType.DecimalNumber || tokens[i].type === TokenType.Asterisk)return 1;return 0;} /**
+	 * Check if token is part of an identifier starting with `_`
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the identifier
+	 */function checkIdentLowLine(i){var start=i;if(i++ >= tokensLength)return 0;for(;i < tokensLength;i++) {if(tokens[i].type !== TokenType.HyphenMinus && tokens[i].type !== TokenType.DecimalNumber && tokens[i].type !== TokenType.LowLine && tokens[i].type !== TokenType.Identifier)break;} // Save index number of the last token of the identifier:
+	tokens[start].ident_last = i - 1;return i - start;} /**
+	 * Get node with an identifier
+	 * @returns {Array} `['ident', x]` where `x` is identifier's name
+	 */function getIdent(){var startPos=pos;var x=joinValues(pos,tokens[pos].ident_last);pos = tokens[pos].ident_last + 1;var token=tokens[startPos];return newNode(NodeType.IdentType,x,token.ln,token.col);}function checkIdentOrInterpolation(i){var start=i;var l=undefined;while(i < tokensLength) {if(l = checkInterpolation(i) || checkIdent(i))i += l;else break;}return i - start;}function getIdentOrInterpolation(){var x=[];while(pos < tokensLength) {if(checkInterpolation(pos))x.push(getInterpolation());else if(checkIdent(pos))x.push(getIdent());else break;}return x;} /**
+	 * Check if token is part of `!important` word
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkImportant(i){var start=i;var l=undefined;if(i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark)return 0;if(l = checkSC(i))i += l;if(tokens[i].value === 'important'){tokens[start].importantEnd = i;return i - start + 1;}else {return 0;}} /**
+	 * Get node with `!important` word
+	 * @returns {Array} `['important', sc]` where `sc` is optional whitespace
+	 */function getImportant(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.importantEnd);pos = token.importantEnd + 1;return newNode(NodeType.ImportantType,content,line,column);} /**
+	 * Check if token is part of an included mixin (`@include` or `@extend`
+	 *      directive).
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the included mixin
+	 */function checkInclude(i){var l;if(i >= tokensLength)return 0;if(l = checkInclude1(i))tokens[i].include_type = 1;else if(l = checkInclude2(i))tokens[i].include_type = 2;else if(l = checkInclude3(i))tokens[i].include_type = 3;else if(l = checkInclude4(i))tokens[i].include_type = 4;else if(l = checkInclude5(i))tokens[i].include_type = 5;return l;} /**
+	 * Check if token is part of `!global` word
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkGlobal(i){var start=i;var l=undefined;if(i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark)return 0;if(l = checkSC(i))i += l;if(tokens[i].value === 'global'){tokens[start].globalEnd = i;return i - start + 1;}else {return 0;}} /**
+	 * Get node with `!global` word
+	 */function getGlobal(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.globalEnd);pos = token.globalEnd + 1;return newNode(NodeType.GlobalType,content,line,column);} /**
+	 * Get node with included mixin
+	 * @returns {Array} `['include', x]`
+	 */function getInclude(){switch(tokens[pos].include_type){case 1:return getInclude1();case 2:return getInclude2();case 3:return getInclude3();case 4:return getInclude4();case 5:return getInclude5();}} /**
+	 * Get node with included mixin with keyfames selector like
+	 * `@include nani(foo) { 0% {}}`
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the include
+	 */function checkInclude1(i){var start=i;var l=undefined;if(l = checkAtkeyword(i))i += l;else return 0;if(tokens[start + 1].value !== 'include')return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkArguments(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkKeyframesBlocks(i))i += l;else return 0;return i - start;} /**
+	 * Get node with included mixin with keyfames selector like
+	 * `@include nani(foo) { 0% {}}`
+	 * @returns {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
+	 *      ['arguments', z], sc, ['block', q], sc` where `x` is `include` or
+	 *      `extend`, `y` is mixin's identifier (selector), `z` are arguments
+	 *      passed to the mixin, `q` is block passed to the mixin containing a
+	 *      ruleset > selector > keyframesSelector, and `sc` are optional
+	 *      whitespaces
+	 */function getInclude1(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getArguments(),getSC(),getKeyframesBlocks());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);} /**
+	 * Check if token is part of an included mixin like `@include nani(foo) {...}`
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the include
+	 */function checkInclude2(i){var start=i;var l=undefined;if(l = checkAtkeyword(i))i += l;else return 0;if(tokens[start + 1].value !== 'include')return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkArguments(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkBlock(i))i += l;else return 0;return i - start;} /**
+	 * Get node with included mixin like `@include nani(foo) {...}`
+	 * @returns {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
+	 *      ['arguments', z], sc, ['block', q], sc` where `x` is `include` or
+	 *      `extend`, `y` is mixin's identifier (selector), `z` are arguments
+	 *      passed to the mixin, `q` is block passed to the mixin and `sc`
+	 *      are optional whitespaces
+	 */function getInclude2(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getArguments(),getSC(),getBlock());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);} /**
+	 * Check if token is part of an included mixin like `@include nani(foo)`
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the include
+	 */function checkInclude3(i){var start=i;var l=undefined;if(l = checkAtkeyword(i))i += l;else return 0;if(tokens[start + 1].value !== 'include')return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkArguments(i))i += l;else return 0;return i - start;} /**
+	 * Get node with included mixin like `@include nani(foo)`
+	 * @returns {Array} `['include', ['atkeyword', x], sc, ['selector', y], sc,
+	 *      ['arguments', z], sc]` where `x` is `include` or `extend`, `y` is
+	 *      mixin's identifier (selector), `z` are arguments passed to the
+	 *      mixin and `sc` are optional whitespaces
+	 */function getInclude3(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getArguments());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);} /**
+	 * Check if token is part of an included mixin with a content block passed
+	 *      as an argument (e.g. `@include nani {...}`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the mixin
+	 */function checkInclude4(i){var start=i;var l=undefined;if(l = checkAtkeyword(i))i += l;else return 0;if(tokens[start + 1].value !== 'include')return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkBlock(i))i += l;else return 0;return i - start;} /**
+	 * Get node with an included mixin with a content block passed
+	 *      as an argument (e.g. `@include nani {...}`)
+	 * @returns {Array} `['include', x]`
+	 */function getInclude4(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation(),getSC(),getBlock());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkInclude5(i){var start=i;var l=undefined;if(l = checkAtkeyword(i))i += l;else return 0;if(tokens[start + 1].value !== 'include')return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;return i - start;} /**
+	 * @returns {Array} `['include', x]`
+	 */function getInclude5(){var startPos=pos;var x=[].concat(getAtkeyword(),getSC(),getIdentOrInterpolation());var token=tokens[startPos];return newNode(NodeType.IncludeType,x,token.ln,token.col);} /**
+	 * Check if token is part of an interpolated variable (e.g. `#{$nani}`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkInterpolation(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(tokens[i].type !== TokenType.NumberSign || !tokens[i + 1] || tokens[i + 1].type !== TokenType.LeftCurlyBracket)return 0;i += 2;while(tokens[i].type !== TokenType.RightCurlyBracket) {if(l = checkArgument(i))i += l;else return 0;}return tokens[i].type === TokenType.RightCurlyBracket?i - start + 1:0;} /**
+	 * Get node with an interpolated variable
+	 * @returns {Array} `['interpolation', x]`
+	 */function getInterpolation(){var startPos=pos;var x=[];var token=tokens[startPos];var line=token.ln;var column=token.col; // Skip `#{`:
+	pos += 2;while(pos < tokensLength && tokens[pos].type !== TokenType.RightCurlyBracket) {var body=getArgument();if(typeof body.content === 'string')x.push(body);else x = x.concat(body);}var end=getLastPosition(x,line,column,1); // Skip `}`:
+	pos++;return newNode(NodeType.InterpolationType,x,token.ln,token.col,end);}function checkKeyframesBlock(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkKeyframesSelector(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkBlock(i))i += l;else return 0;return i - start;}function getKeyframesBlock(){var type=NodeType.RulesetType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[].concat([getKeyframesSelector()],getSC(),[getBlock()]);return newNode(type,content,line,column);}function checkKeyframesBlocks(i){var start=i;var l=undefined;if(i < tokensLength && tokens[i].type === TokenType.LeftCurlyBracket)i++;else return 0;if(l = checkSC(i))i += l;if(l = checkKeyframesBlock(i))i += l;else return 0;while(tokens[i].type !== TokenType.RightCurlyBracket) {if(l = checkSC(i))i += l;else if(l = checkKeyframesBlock(i))i += l;else break;}if(i < tokensLength && tokens[i].type === TokenType.RightCurlyBracket)i++;else return 0;return i - start;}function getKeyframesBlocks(){var type=NodeType.BlockType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];var keyframesBlocksEnd=token.right; // Skip `{`.
+	pos++;while(pos < keyframesBlocksEnd) {if(checkSC(pos))content = content.concat(getSC());else if(checkKeyframesBlock(pos))content.push(getKeyframesBlock());}var end=getLastPosition(content,line,column,1); // Skip `}`.
+	pos++;return newNode(type,content,line,column,end);} /**
+	 * Check if token is part of a @keyframes rule.
+	 * @param {Number} i Token's index number
+	 * @return {Number} Length of the @keyframes rule
+	 */function checkKeyframesRule(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;var atruleName=joinValues2(i - l,l);if(atruleName.indexOf('keyframes') === -1)return 0;if(l = checkSC(i))i += l;else return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkKeyframesBlocks(i))i += l;else return 0;return i - start;} /**
+	 * @return {Node}
+	 */function getKeyframesRule(){var type=NodeType.AtruleType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[].concat([getAtkeyword()],getSC(),getIdentOrInterpolation(),getSC(),[getKeyframesBlocks()]);return newNode(type,content,line,column);}function checkKeyframesSelector(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkIdent(i)){ // Valid selectors are only `from` and `to`.
+	var selector=joinValues2(i,l);if(selector !== 'from' && selector !== 'to')return 0;i += l;tokens[start].keyframesSelectorType = 1;}else if(l = checkPercentage(i)){i += l;tokens[start].keyframesSelectorType = 2;}else if(l = checkInterpolation(i)){i += l;tokens[start].keyframesSelectorType = 3;}else {return 0;}return i - start;}function getKeyframesSelector(){var keyframesSelectorType=NodeType.KeyframesSelectorType;var selectorType=NodeType.SelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(token.keyframesSelectorType === 1){content.push(getIdent());}else if(token.keyframesSelectorType === 2){content.push(getPercentage());}else {content.push(getInterpolation());}var keyframesSelector=newNode(keyframesSelectorType,content,line,column);return newNode(selectorType,[keyframesSelector],line,column);} /**
+	 * Check if token is part of a loop.
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the loop
+	 */function checkLoop(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkAtkeyword(i))i += l;else return 0;if(['for','each','while'].indexOf(tokens[start + 1].value) < 0)return 0;while(i < tokensLength) {if(l = checkBlock(i)){i += l;break;}else if(l = checkVariable(i) || checkNumber(i) || checkInterpolation(i) || checkIdent(i) || checkSC(i) || checkOperator(i) || checkCombinator(i) || checkString(i))i += l;else return 0;}return i - start;} /**
+	 * Get node with a loop.
+	 * @returns {Array} `['loop', x]`
+	 */function getLoop(){var startPos=pos;var x=[];x.push(getAtkeyword());while(pos < tokensLength) {if(checkBlock(pos)){x.push(getBlock());break;}else if(checkVariable(pos))x.push(getVariable());else if(checkNumber(pos))x.push(getNumber());else if(checkInterpolation(pos))x.push(getInterpolation());else if(checkIdent(pos))x.push(getIdent());else if(checkOperator(pos))x.push(getOperator());else if(checkCombinator(pos))x.push(getCombinator());else if(checkSC(pos))x = x.concat(getSC());else if(checkString(pos))x.push(getString());}var token=tokens[startPos];return newNode(NodeType.LoopType,x,token.ln,token.col);} /**
+	 * Check if token is part of a mixin
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the mixin
+	 */function checkMixin(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if((l = checkAtkeyword(i)) && tokens[i + 1].value === 'mixin')i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkArguments(i))i += l;if(l = checkSC(i))i += l;if(l = checkBlock(i))i += l;else return 0;return i - start;} /**
+	 * Get node with a mixin
+	 * @returns {Array} `['mixin', x]`
+	 */function getMixin(){var startPos=pos;var x=[getAtkeyword()];x = x.concat(getSC());if(checkIdentOrInterpolation(pos))x = x.concat(getIdentOrInterpolation());x = x.concat(getSC());if(checkArguments(pos))x.push(getArguments());x = x.concat(getSC());if(checkBlock(pos))x.push(getBlock());var token=tokens[startPos];return newNode(NodeType.MixinType,x,token.ln,token.col);} /**
+	 * Check if token is a namespace sign (`|`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is `|`, `0` if not
+	 */function checkNamespace(i){return i < tokensLength && tokens[i].type === TokenType.VerticalLine?1:0;} /**
+	 * Get node with a namespace sign
+	 * @returns {Array} `['namespace']`
+	 */function getNamespace(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.NamespaceType,'|',token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkNmName2(i){if(tokens[i].type === TokenType.Identifier)return 1;else if(tokens[i].type !== TokenType.DecimalNumber)return 0;i++;return i < tokensLength && tokens[i].type === TokenType.Identifier?2:1;} /**
+	 * @returns {String}
+	 */function getNmName2(){var s=tokens[pos].value;if(tokens[pos++].type === TokenType.DecimalNumber && pos < tokensLength && tokens[pos].type === TokenType.Identifier)s += tokens[pos++].value;return s;} /**
+	 * Check if token is part of a number
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of number
+	 */function checkNumber(i){if(i >= tokensLength)return 0;if(tokens[i].number_l)return tokens[i].number_l; // `10`:
+	if(i < tokensLength && tokens[i].type === TokenType.DecimalNumber && (!tokens[i + 1] || tokens[i + 1] && tokens[i + 1].type !== TokenType.FullStop))return tokens[i].number_l = 1,tokens[i].number_l; // `10.`:
+	if(i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && (!tokens[i + 2] || tokens[i + 2].type !== TokenType.DecimalNumber))return tokens[i].number_l = 2,tokens[i].number_l; // `.10`:
+	if(i < tokensLength && tokens[i].type === TokenType.FullStop && tokens[i + 1].type === TokenType.DecimalNumber)return tokens[i].number_l = 2,tokens[i].number_l; // `10.10`:
+	if(i < tokensLength && tokens[i].type === TokenType.DecimalNumber && tokens[i + 1] && tokens[i + 1].type === TokenType.FullStop && tokens[i + 2] && tokens[i + 2].type === TokenType.DecimalNumber)return tokens[i].number_l = 3,tokens[i].number_l;return 0;} /**
+	 * Get node with number
+	 * @returns {Array} `['number', x]` where `x` is a number converted
+	 *      to string.
+	 */function getNumber(){var s='';var startPos=pos;var l=tokens[pos].number_l;for(var j=0;j < l;j++) {s += tokens[pos + j].value;}pos += l;var token=tokens[startPos];return newNode(NodeType.NumberType,s,token.ln,token.col);} /**
+	 * Check if token is an operator (`/`, `%`, `,`, `:` or `=`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is an operator, otherwise `0`
+	 */function checkOperator(i){if(i >= tokensLength)return 0;switch(tokens[i].type){case TokenType.Solidus:case TokenType.PercentSign:case TokenType.Comma:case TokenType.Colon:case TokenType.EqualsSign:case TokenType.EqualitySign:case TokenType.InequalitySign:case TokenType.LessThanSign:case TokenType.GreaterThanSign:case TokenType.Asterisk:return 1;}return 0;} /**
+	 * Get node with an operator
+	 * @returns {Array} `['operator', x]` where `x` is an operator converted
+	 *      to string.
+	 */function getOperator(){var startPos=pos;var x=tokens[pos++].value;var token=tokens[startPos];return newNode(NodeType.OperatorType,x,token.ln,token.col);} /**
+	 * Check if token is part of `!optional` word
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkOptional(i){var start=i;var l=undefined;if(i >= tokensLength || tokens[i++].type !== TokenType.ExclamationMark)return 0;if(l = checkSC(i))i += l;if(tokens[i].value === 'optional'){tokens[start].optionalEnd = i;return i - start + 1;}else {return 0;}} /**
+	 * Get node with `!optional` word
+	 */function getOptional(){var token=tokens[pos];var line=token.ln;var column=token.col;var content=joinValues(pos,token.optionalEnd);pos = token.optionalEnd + 1;return newNode(NodeType.OptionalType,content,line,column);} /**
+	 * Check if token is part of text inside parentheses, e.g. `(1)`
+	 * @param {Number} i Token's index number
+	 * @return {Number}
+	 */function checkParentheses(i){if(i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis)return 0;return tokens[i].right - i + 1;} /**
+	 * Get node with text inside parentheses, e.g. `(1)`
+	 * @return {Node}
+	 */function getParentheses(){var type=NodeType.ParenthesesType;var token=tokens[pos];var line=token.ln;var column=token.col;pos++;var tsets=getTsets();var end=getLastPosition(tsets,line,column,1);pos++;return newNode(type,tsets,line,column,end);} /**
+	 * Check if token is a parent selector (`&`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkParentSelector(i){return i < tokensLength && tokens[i].type === TokenType.Ampersand?1:0;} /**
+	 * Get node with a parent selector
+	 */function getParentSelector(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.ParentSelectorType,'&',token.ln,token.col);}function checkParentSelectorExtension(i){if(i >= tokensLength)return 0;var start=i;var l=undefined;while(i < tokensLength) {if(l = checkNumber(i) || checkIdentOrInterpolation(i))i += l;else break;}return i - start;}function getParentSelectorExtension(){var type=NodeType.ParentSelectorExtensionType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];while(pos < tokensLength) {if(checkNumber(pos))content.push(getNumber());else if(checkIdentOrInterpolation(pos))content = content.concat(getIdentOrInterpolation());else break;}return newNode(type,content,line,column);}function checkParentSelectorWithExtension(i){if(i >= tokensLength)return 0;var start=i;var l=undefined;if(l = checkParentSelector(i))i += l;else return 0;if(l = checkParentSelectorExtension(i))i += l;return i - start;}function getParentSelectorWithExtension(){var content=[getParentSelector()];if(checkParentSelectorExtension(pos))content.push(getParentSelectorExtension());return content;} /**
+	 * Check if token is part of a number with percent sign (e.g. `10%`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkPercentage(i){var x;if(i >= tokensLength)return 0;x = checkNumber(i);if(!x || i + x >= tokensLength)return 0;return tokens[i + x].type === TokenType.PercentSign?x + 1:0;} /**
+	 * Get node of number with percent sign
+	 * @returns {Array} `['percentage', ['number', x]]` where `x` is a number
+	 *      (without percent sign) converted to string.
+	 */function getPercentage(){var startPos=pos;var x=[getNumber()];var token=tokens[startPos];var line=token.ln;var column=token.col;var end=getLastPosition(x,line,column,1);pos++;return newNode(NodeType.PercentageType,x,token.ln,token.col,end);} /**
+	 * Check if token is part of a placeholder selector (e.g. `%abc`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the selector
+	 */function checkPlaceholder(i){var l;if(i >= tokensLength)return 0;if(tokens[i].placeholder_l)return tokens[i].placeholder_l;if(tokens[i].type === TokenType.PercentSign && (l = checkIdentOrInterpolation(i + 1))){tokens[i].placeholder_l = l + 1;return l + 1;}else return 0;} /**
+	 * Get node with a placeholder selector
+	 * @returns {Array} `['placeholder', ['ident', x]]` where x is a placeholder's
+	 *      identifier (without `%`, e.g. `abc`).
+	 */function getPlaceholder(){var startPos=pos;pos++;var x=getIdentOrInterpolation();var token=tokens[startPos];return newNode(NodeType.PlaceholderType,x,token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkProgid(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(joinValues2(i,6) === 'progid:DXImageTransform.Microsoft.')i += 6;else return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(tokens[i].type === TokenType.LeftParenthesis){tokens[start].progid_end = tokens[i].right;i = tokens[i].right + 1;}else return 0;return i - start;} /**
+	 * @returns {Array}
+	 */function getProgid(){var startPos=pos;var progid_end=tokens[pos].progid_end;var x=joinValues(pos,progid_end);pos = progid_end + 1;var token=tokens[startPos];return newNode(NodeType.ProgidType,x,token.ln,token.col);} /**
+	 * Check if token is part of a property
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the property
+	 */function checkProperty(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkVariable(i) || checkIdentOrInterpolation(i))i += l;else return 0;return i - start;} /**
+	 * Get node with a property
+	 * @returns {Array} `['property', x]`
+	 */function getProperty(){var startPos=pos;var x=[];if(checkVariable(pos)){x.push(getVariable());}else {x = x.concat(getIdentOrInterpolation());}var token=tokens[startPos];return newNode(NodeType.PropertyType,x,token.ln,token.col);} /**
+	 * Check if token is a colon
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is a colon, otherwise `0`
+	 */function checkPropertyDelim(i){return i < tokensLength && tokens[i].type === TokenType.Colon?1:0;} /**
+	 * Get node with a colon
+	 * @returns {Array} `['propertyDelim']`
+	 */function getPropertyDelim(){var startPos=pos;pos++;var token=tokens[startPos];return newNode(NodeType.PropertyDelimType,':',token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkPseudo(i){return checkPseudoe(i) || checkPseudoc(i);} /**
+	 * @returns {Array}
+	 */function getPseudo(){if(checkPseudoe(pos))return getPseudoe();if(checkPseudoc(pos))return getPseudoc();} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkPseudoe(i){var l;if(i >= tokensLength || tokens[i++].type !== TokenType.Colon || i >= tokensLength || tokens[i++].type !== TokenType.Colon)return 0;return (l = checkIdentOrInterpolation(i))?l + 2:0;} /**
+	 * @returns {Array}
+	 */function getPseudoe(){var startPos=pos;pos += 2;var x=getIdentOrInterpolation();var token=tokens[startPos];return newNode(NodeType.PseudoeType,x,token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkPseudoc(i){var l;if(i >= tokensLength || tokens[i].type !== TokenType.Colon)return 0;if(l = checkPseudoClass3(i))tokens[i].pseudoClassType = 3;else if(l = checkPseudoClass4(i))tokens[i].pseudoClassType = 4;else if(l = checkPseudoClass5(i))tokens[i].pseudoClassType = 5;else if(l = checkPseudoClass1(i))tokens[i].pseudoClassType = 1;else if(l = checkPseudoClass2(i))tokens[i].pseudoClassType = 2;else if(l = checkPseudoClass6(i))tokens[i].pseudoClassType = 6;else return 0;return l;} /**
+	 * @returns {Array}
+	 */function getPseudoc(){var childType=tokens[pos].pseudoClassType;if(childType === 1)return getPseudoClass1();if(childType === 2)return getPseudoClass2();if(childType === 3)return getPseudoClass3();if(childType === 4)return getPseudoClass4();if(childType === 5)return getPseudoClass5();if(childType === 6)return getPseudoClass6();} /**
+	 * (-) `:not(panda)`
+	 */function checkPseudoClass1(i){var start=i; // Skip `:`.
+	i++;if(i >= tokensLength)return 0;var l=undefined;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis)return 0;var right=tokens[i].right; // Skip `(`.
+	i++;if(l = checkSelectorsGroup(i))i += l;else return 0;if(i !== right)return 0;return right - start + 1;} /**
+	 * (-) `:not(panda)`
+	 */function getPseudoClass1(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[]; // Skip `:`.
+	pos++;content = content.concat(getIdentOrInterpolation());{var _type=NodeType.ArgumentsType;var _token=tokens[pos];var _line=_token.ln;var _column=_token.col; // Skip `(`.
+	pos++;var selectors=getSelectorsGroup();var end=getLastPosition(selectors,_line,_column,1);var args=newNode(_type,selectors,_line,_column,end);content.push(args); // Skip `)`.
+	pos++;}return newNode(type,content,line,column);} /**
+	 * (1) `:nth-child(odd)`
+	 * (2) `:nth-child(even)`
+	 * (3) `:lang(de-DE)`
+	 */function checkPseudoClass2(i){var start=i;var l=0; // Skip `:`.
+	i++;if(i >= tokensLength)return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis)return 0;var right=tokens[i].right; // Skip `(`.
+	i++;if(l = checkSC(i))i += l;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(l = checkSC(i))i += l;if(i !== right)return 0;return i - start + 1;}function getPseudoClass2(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[]; // Skip `:`.
+	pos++;content = content.concat(getIdentOrInterpolation());var l=tokens[pos].ln;var c=tokens[pos].col;var value=[]; // Skip `(`.
+	pos++;value = value.concat(getSC()).concat(getIdentOrInterpolation()).concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args); // Skip `)`.
+	pos++;return newNode(type,content,line,column);} /**
+	 * (-) `:nth-child(-3n + 2)`
+	 */function checkPseudoClass3(i){var start=i;var l=0; // Skip `:`.
+	i++;if(i >= tokensLength)return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis)return 0;var right=tokens[i].right; // Skip `(`.
+	i++;if(l = checkSC(i))i += l;if(l = checkUnary(i))i += l;if(i >= tokensLength)return 0;if(tokens[i].type === TokenType.DecimalNumber)i++;if(i >= tokensLength)return 0;if(tokens[i].value === 'n')i++;else return 0;if(l = checkSC(i))i += l;if(i >= tokensLength)return 0;if(tokens[i].value === '+' || tokens[i].value === '-')i++;else return 0;if(l = checkSC(i))i += l;if(tokens[i].type === TokenType.DecimalNumber)i++;else return 0;if(l = checkSC(i))i += l;if(i !== right)return 0;return i - start + 1;}function getPseudoClass3(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col; // Skip `:`.
+	pos++;var content=getIdentOrInterpolation();var l=tokens[pos].ln;var c=tokens[pos].col;var value=[]; // Skip `(`.
+	pos++;if(checkUnary(pos))value.push(getUnary());if(checkNumber(pos))value.push(getNumber());{var _l=tokens[pos].ln;var _c=tokens[pos].col;var _content=tokens[pos].value;var ident=newNode(NodeType.IdentType,_content,_l,_c);value.push(ident);pos++;}value = value.concat(getSC());if(checkUnary(pos))value.push(getUnary());value = value.concat(getSC());if(checkNumber(pos))value.push(getNumber());value = value.concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args); // Skip `)`.
+	pos++;return newNode(type,content,line,column);} /**
+	 * (-) `:nth-child(-3n)`
+	 */function checkPseudoClass4(i){var start=i;var l=0; // Skip `:`.
+	i++;if(i >= tokensLength)return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(i >= tokensLength)return 0;if(tokens[i].type !== TokenType.LeftParenthesis)return 0;var right=tokens[i].right; // Skip `(`.
+	i++;if(l = checkSC(i))i += l;if(l = checkUnary(i))i += l;if(tokens[i].type === TokenType.DecimalNumber)i++;if(tokens[i].value === 'n')i++;else return 0;if(l = checkSC(i))i += l;if(i !== right)return 0;return i - start + 1;}function getPseudoClass4(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col; // Skip `:`.
+	pos++;var content=getIdentOrInterpolation();var l=tokens[pos].ln;var c=tokens[pos].col;var value=[]; // Skip `(`.
+	pos++;value = value.concat(getSC());if(checkUnary(pos))value.push(getUnary());if(checkNumber(pos))value.push(getNumber());if(checkIdent(pos))value.push(getIdent());value = value.concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args); // Skip `)`.
+	pos++;return newNode(type,content,line,column);} /**
+	 * (-) `:nth-child(+8)`
+	 */function checkPseudoClass5(i){var start=i;var l=0; // Skip `:`.
+	i++;if(i >= tokensLength)return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;if(i >= tokensLength)return 0;if(tokens[i].type !== TokenType.LeftParenthesis)return 0;var right=tokens[i].right; // Skip `(`.
+	i++;if(l = checkSC(i))i += l;if(l = checkUnary(i))i += l;if(tokens[i].type === TokenType.DecimalNumber)i++;else return 0;if(l = checkSC(i))i += l;if(i !== right)return 0;return i - start + 1;}function getPseudoClass5(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col; // Skip `:`.
+	pos++;var content=getIdentOrInterpolation();var l=tokens[pos].ln;var c=tokens[pos].col;var value=[]; // Skip `(`.
+	pos++;if(checkUnary(pos))value.push(getUnary());if(checkNumber(pos))value.push(getNumber());value = value.concat(getSC());var end=getLastPosition(value,l,c,1);var args=newNode(NodeType.ArgumentsType,value,l,c,end);content.push(args); // Skip `)`.
+	pos++;return newNode(type,content,line,column);} /**
+	 * (-) `:checked`
+	 */function checkPseudoClass6(i){var start=i;var l=0; // Skip `:`.
+	i++;if(i >= tokensLength)return 0;if(l = checkIdentOrInterpolation(i))i += l;else return 0;return i - start;}function getPseudoClass6(){var type=NodeType.PseudocType;var token=tokens[pos];var line=token.ln;var column=token.col; // Skip `:`.
+	pos++;var content=getIdentOrInterpolation();return newNode(type,content,line,column);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkRuleset(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkSelectorsGroup(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkBlock(i))i += l;else return 0;return i - start;}function getRuleset(){var type=NodeType.RulesetType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];content = content.concat(getSelectorsGroup());content = content.concat(getSC());content.push(getBlock());return newNode(type,content,line,column);} /**
+	 * Check if token is marked as a space (if it's a space or a tab
+	 *      or a line break).
+	 * @param {Number} i
+	 * @returns {Number} Number of spaces in a row starting with the given token.
+	 */function checkS(i){return i < tokensLength && tokens[i].ws?tokens[i].ws_last - i + 1:0;} /**
+	 * Get node with spaces
+	 * @returns {Array} `['s', x]` where `x` is a string containing spaces
+	 */function getS(){var startPos=pos;var x=joinValues(pos,tokens[pos].ws_last);pos = tokens[pos].ws_last + 1;var token=tokens[startPos];return newNode(NodeType.SType,x,token.ln,token.col);} /**
+	 * Check if token is a space or a comment.
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Number of similar (space or comment) tokens
+	 *      in a row starting with the given token.
+	 */function checkSC(i){if(i >= tokensLength)return 0;var l=undefined;var lsc=0;while(i < tokensLength) {if(!(l = checkS(i)) && !(l = checkCommentML(i)) && !(l = checkCommentSL(i)))break;i += l;lsc += l;}return lsc || 0;} /**
+	 * Get node with spaces and comments
+	 * @returns {Array} Array containing nodes with spaces (if there are any)
+	 *      and nodes with comments (if there are any):
+	 *      `[['s', x]*, ['comment', y]*]` where `x` is a string of spaces
+	 *      and `y` is a comment's text (without `/*` and `* /`).
+	 */function getSC(){var sc=[];if(pos >= tokensLength)return sc;while(pos < tokensLength) {if(checkS(pos))sc.push(getS());else if(checkCommentML(pos))sc.push(getCommentML());else if(checkCommentSL(pos))sc.push(getCommentSL());else break;}return sc;} /**
+	 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
+	 *      a simple selector
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkShash(i){var l;if(i >= tokensLength || tokens[i].type !== TokenType.NumberSign)return 0;return (l = checkIdentOrInterpolation(i + 1))?l + 1:0;} /**
+	 * Get node with a hexadecimal number (e.g. `#fff`) inside a simple
+	 *      selector
+	 * @returns {Array} `['shash', x]` where `x` is a hexadecimal number
+	 *      converted to string (without `#`, e.g. `fff`)
+	 */function getShash(){var startPos=pos;var token=tokens[startPos];pos++;var x=getIdentOrInterpolation();return newNode(NodeType.ShashType,x,token.ln,token.col);} /**
+	 * Check if token is part of a string (text wrapped in quotes)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is part of a string, `0` if not
+	 */function checkString(i){return i < tokensLength && (tokens[i].type === TokenType.StringSQ || tokens[i].type === TokenType.StringDQ)?1:0;} /**
+	 * Get string's node
+	 * @returns {Array} `['string', x]` where `x` is a string (including
+	 *      quotes).
+	 */function getString(){var startPos=pos;var x=tokens[pos++].value;var token=tokens[startPos];return newNode(NodeType.StringType,x,token.ln,token.col);} /**
+	 * Validate stylesheet: it should consist of any number (0 or more) of
+	 * rulesets (sets of rules with selectors), @-rules, whitespaces or
+	 * comments.
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkStylesheet(i){var start=i;var l=undefined;while(i < tokensLength) {if(l = checkSC(i) || checkDeclaration(i) || checkDeclDelim(i) || checkInclude(i) || checkExtend(i) || checkMixin(i) || checkLoop(i) || checkConditionalStatement(i) || checkAtrule(i) || checkRuleset(i))i += l;else throwError(i);}return i - start;} /**
+	 * @returns {Array} `['stylesheet', x]` where `x` is all stylesheet's
+	 *      nodes.
+	 */function getStylesheet(){var startPos=pos;var x=[];while(pos < tokensLength) {if(checkSC(pos))x = x.concat(getSC());else if(checkRuleset(pos))x.push(getRuleset());else if(checkInclude(pos))x.push(getInclude());else if(checkExtend(pos))x.push(getExtend());else if(checkMixin(pos))x.push(getMixin());else if(checkLoop(pos))x.push(getLoop());else if(checkConditionalStatement(pos))x.push(getConditionalStatement());else if(checkAtrule(pos))x.push(getAtrule());else if(checkDeclaration(pos))x.push(getDeclaration());else if(checkDeclDelim(pos))x.push(getDeclDelim());else throwError();}var token=tokens[startPos];return newNode(NodeType.StylesheetType,x,token.ln,token.col);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkTset(i){return checkVhash(i) || checkOperator(i) || checkAny(i) || checkSC(i) || checkInterpolation(i);} /**
+	 * @returns {Array}
+	 */function getTset(){if(checkVhash(pos))return getVhash();else if(checkOperator(pos))return getOperator();else if(checkAny(pos))return getAny();else if(checkSC(pos))return getSC();else if(checkInterpolation(pos))return getInterpolation();} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkTsets(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;while(l = checkTset(i)) {i += l;}return i - start;} /**
+	 * @returns {Array}
+	 */function getTsets(){var x=[];var t=undefined;while(t = getTset()) {if(typeof t.content === 'string')x.push(t);else x = x.concat(t);}return x;} /**
+	 * Check if token is an unary (arithmetical) sign (`+` or `-`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} `1` if token is an unary sign, `0` if not
+	 */function checkUnary(i){return i < tokensLength && (tokens[i].type === TokenType.HyphenMinus || tokens[i].type === TokenType.PlusSign)?1:0;} /**
+	 * Get node with an unary (arithmetical) sign (`+` or `-`)
+	 * @returns {Array} `['unary', x]` where `x` is an unary sign
+	 *      converted to string.
+	 */function getUnary(){var startPos=pos;var x=tokens[pos++].value;var token=tokens[startPos];return newNode(NodeType.OperatorType,x,token.ln,token.col);} /**
+	 * Check if token is part of URI (e.g. `url('/css/styles.css')`)
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of URI
+	 */function checkUri(i){var start=i;if(i >= tokensLength || tokens[i++].value !== 'url' || i >= tokensLength || tokens[i].type !== TokenType.LeftParenthesis)return 0;return tokens[i].right - start + 1;} /**
+	 * Get node with URI
+	 * @returns {Array} `['uri', x]` where `x` is URI's nodes (without `url`
+	 *      and braces, e.g. `['string', ''/css/styles.css'']`).
+	 */function getUri(){var startPos=pos;var uriExcluding={};var uri=undefined;var token=undefined;var l=undefined;var raw=undefined;pos += 2;uriExcluding[TokenType.Space] = 1;uriExcluding[TokenType.Tab] = 1;uriExcluding[TokenType.Newline] = 1;uriExcluding[TokenType.LeftParenthesis] = 1;uriExcluding[TokenType.RightParenthesis] = 1;if(checkUriContent(pos)){uri = [].concat(getSC()).concat(getUriContent()).concat(getSC());}else {uri = [].concat(getSC());l = checkExcluding(uriExcluding,pos);token = tokens[pos];raw = newNode(NodeType.RawType,joinValues(pos,pos + l),token.ln,token.col);uri.push(raw);pos += l + 1;uri = uri.concat(getSC());}token = tokens[startPos];var line=token.ln;var column=token.col;var end=getLastPosition(uri,line,column,1);pos++;return newNode(NodeType.UriType,uri,token.ln,token.col,end);} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkUriContent(i){return checkUri1(i) || checkFunction(i);} /**
+	 * @returns {Array}
+	 */function getUriContent(){if(checkUri1(pos))return getString();else if(checkFunction(pos))return getFunction();} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkUri1(i){var start=i;var l=undefined;if(i >= tokensLength)return 0;if(l = checkSC(i))i += l;if(tokens[i].type !== TokenType.StringDQ && tokens[i].type !== TokenType.StringSQ)return 0;i++;if(l = checkSC(i))i += l;return i - start;} /**
+	 * Check if token is part of a value
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the value
+	 */function checkValue(i){var start=i;var l=undefined;var s=undefined;var _i=undefined;while(i < tokensLength) {if(checkDeclDelim(i))break;s = checkSC(i);_i = i + s;if(l = _checkValue(_i))i += l + s;if(!l || checkBlock(i - l))break;}return i - start;} /**
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function _checkValue(i){return checkInterpolation(i) || checkVariable(i) || checkVhash(i) || checkBlock(i) || checkAtkeyword(i) || checkOperator(i) || checkImportant(i) || checkGlobal(i) || checkDefault(i) || checkProgid(i) || checkAny(i);} /**
+	 * @returns {Array}
+	 */function getValue(){var startPos=pos;var x=[];var _pos=undefined;var s=undefined;while(pos < tokensLength) {s = checkSC(pos);_pos = pos + s;if(checkDeclDelim(_pos))break;if(!_checkValue(_pos))break;if(s)x = x.concat(getSC());x.push(_getValue());if(checkBlock(_pos))break;}var token=tokens[startPos];return newNode(NodeType.ValueType,x,token.ln,token.col);} /**
+	 * @returns {Array}
+	 */function _getValue(){if(checkInterpolation(pos))return getInterpolation();else if(checkVariable(pos))return getVariable();else if(checkVhash(pos))return getVhash();else if(checkBlock(pos))return getBlock();else if(checkAtkeyword(pos))return getAtkeyword();else if(checkOperator(pos))return getOperator();else if(checkImportant(pos))return getImportant();else if(checkGlobal(pos))return getGlobal();else if(checkDefault(pos))return getDefault();else if(checkProgid(pos))return getProgid();else if(checkAny(pos))return getAny();} /**
+	 * Check if token is part of a variable
+	 * @param {Number} i Token's index number
+	 * @returns {Number} Length of the variable
+	 */function checkVariable(i){var l;if(i >= tokensLength || tokens[i].type !== TokenType.DollarSign)return 0;return (l = checkIdent(i + 1))?l + 1:0;} /**
+	 * Get node with a variable
+	 * @returns {Array} `['variable', ['ident', x]]` where `x` is
+	 *      a variable name.
+	 */function getVariable(){var startPos=pos;var x=[];pos++;x.push(getIdent());var token=tokens[startPos];return newNode(NodeType.VariableType,x,token.ln,token.col);} /**
+	 * Check if token is part of a variables list (e.g. `$values...`).
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkVariablesList(i){var d=0; // Number of dots
+	var l=undefined;if(i >= tokensLength)return 0;if(l = checkVariable(i))i += l;else return 0;while(i < tokensLength && tokens[i].type === TokenType.FullStop) {d++;i++;}return d === 3?l + d:0;} /**
+	 * Get node with a variables list
+	 * @returns {Array} `['variableslist', ['variable', ['ident', x]]]` where
+	 *      `x` is a variable name.
+	 */function getVariablesList(){var startPos=pos;var x=getVariable();var token=tokens[startPos];var line=token.ln;var column=token.col;var end=getLastPosition([x],line,column,3);pos += 3;return newNode(NodeType.VariablesListType,[x],token.ln,token.col,end);} /**
+	 * Check if token is part of a hexadecimal number (e.g. `#fff`) inside
+	 *      some value
+	 * @param {Number} i Token's index number
+	 * @returns {Number}
+	 */function checkVhash(i){var l;if(i >= tokensLength || tokens[i].type !== TokenType.NumberSign)return 0;return (l = checkNmName2(i + 1))?l + 1:0;} /**
+	 * Get node with a hexadecimal number (e.g. `#fff`) inside some value
+	 * @returns {Array} `['vhash', x]` where `x` is a hexadecimal number
+	 *      converted to string (without `#`, e.g. `'fff'`).
+	 */function getVhash(){var startPos=pos;var x=undefined;var token=tokens[startPos];var line=token.ln;var column=token.col;pos++;x = getNmName2();var end=getLastPosition(x,line,column + 1);return newNode(NodeType.VhashType,x,token.ln,token.col,end);}module.exports = function(_tokens,context){tokens = _tokens;tokensLength = tokens.length;pos = 0;return contexts[context]();};function checkSelectorsGroup(i){if(i >= tokensLength)return 0;var start=i;var l=undefined;if(l = checkSelector(i))i += l;else return 0;while(i < tokensLength) {var sb=checkSC(i);var c=checkDelim(i + sb);if(!c)break;var sa=checkSC(i + sb + c);if(l = checkSelector(i + sb + c + sa))i += sb + c + sa + l;else break;}tokens[start].selectorsGroupEnd = i;return i - start;}function getSelectorsGroup(){var selectorsGroup=[];var selectorsGroupEnd=tokens[pos].selectorsGroupEnd;selectorsGroup.push(getSelector());while(pos < selectorsGroupEnd) {selectorsGroup = selectorsGroup.concat(getSC());selectorsGroup.push(getDelim());selectorsGroup = selectorsGroup.concat(getSC());selectorsGroup.push(getSelector());}return selectorsGroup;}function checkSelector(i){var l;if(l = checkSelector1(i))tokens[i].selectorType = 1;else if(l = checkSelector2(i))tokens[i].selectorType = 2;return l;}function getSelector(){var selectorType=tokens[pos].selectorType;if(selectorType === 1)return getSelector1();else return getSelector2();} /**
+	 * Checks for selector which starts with a compound selector.
+	 */function checkSelector1(i){if(i >= tokensLength)return 0;var start=i;var l=undefined;if(l = checkCompoundSelector(i))i += l;else return 0;while(i < tokensLength) {var s=checkSC(i);var c=checkCombinator(i + s);if(!s && !c)break;if(c){i += s + c;s = checkSC(i);}if(l = checkCompoundSelector(i + s))i += s + l;else break;}tokens[start].selectorEnd = i;return i - start;}function getSelector1(){var type=NodeType.SelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var selectorEnd=token.selectorEnd;var content=getCompoundSelector();while(pos < selectorEnd) {if(checkSC(pos))content = content.concat(getSC());else if(checkCombinator(pos))content.push(getCombinator());else if(checkCompoundSelector(pos))content = content.concat(getCompoundSelector());}return newNode(type,content,line,column);} /**
+	 * Checks for a selector that starts with a combinator.
+	 */function checkSelector2(i){if(i >= tokensLength)return 0;var start=i;var l=undefined;if(l = checkCombinator(i))i += l;else return 0;while(i < tokensLength) {var sb=checkSC(i);if(l = checkCompoundSelector(i + sb))i += sb + l;else break;var sa=checkSC(i);var c=checkCombinator(i + sa);if(!sa && !c)break;if(c){i += sa + c;}}tokens[start].selectorEnd = i;return i - start;}function getSelector2(){var type=NodeType.SelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var selectorEnd=token.selectorEnd;var content=[getCombinator()];while(pos < selectorEnd) {if(checkSC(pos))content = content.concat(getSC());else if(checkCombinator(pos))content.push(getCombinator());else if(checkCompoundSelector(pos))content = content.concat(getCompoundSelector());}return newNode(type,content,line,column);}function checkCompoundSelector(i){var l=undefined;if(l = checkCompoundSelector1(i)){tokens[i].compoundSelectorType = 1;}else if(l = checkCompoundSelector2(i)){tokens[i].compoundSelectorType = 2;}return l;}function getCompoundSelector(){var type=tokens[pos].compoundSelectorType;if(type === 1)return getCompoundSelector1();if(type === 2)return getCompoundSelector2();}function checkCompoundSelector1(i){if(i >= tokensLength)return 0;var start=i;var l=undefined;if(l = checkTypeSelector(i) || checkPlaceholder(i) || checkParentSelectorWithExtension(i))i += l;else return 0;while(i < tokensLength) {var _l2=checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i) || checkPlaceholder(i);if(_l2)i += _l2;else break;}tokens[start].compoundSelectorEnd = i;return i - start;}function getCompoundSelector1(){var sequence=[];var compoundSelectorEnd=tokens[pos].compoundSelectorEnd;if(checkTypeSelector(pos))sequence.push(getTypeSelector());else if(checkPlaceholder(pos))sequence.push(getPlaceholder());else if(checkParentSelectorWithExtension(pos))sequence = sequence.concat(getParentSelectorWithExtension());while(pos < compoundSelectorEnd) {if(checkShash(pos))sequence.push(getShash());else if(checkClass(pos))sequence.push(getClass());else if(checkAttributeSelector(pos))sequence.push(getAttributeSelector());else if(checkPseudo(pos))sequence.push(getPseudo());else if(checkPlaceholder(pos))sequence.push(getPlaceholder());}return sequence;}function checkCompoundSelector2(i){if(i >= tokensLength)return 0;var start=i;while(i < tokensLength) {var l=checkShash(i) || checkClass(i) || checkAttributeSelector(i) || checkPseudo(i) || checkPlaceholder(i);if(l)i += l;else break;}tokens[start].compoundSelectorEnd = i;return i - start;}function getCompoundSelector2(){var sequence=[];var compoundSelectorEnd=tokens[pos].compoundSelectorEnd;while(pos < compoundSelectorEnd) {if(checkShash(pos))sequence.push(getShash());else if(checkClass(pos))sequence.push(getClass());else if(checkAttributeSelector(pos))sequence.push(getAttributeSelector());else if(checkPseudo(pos))sequence.push(getPseudo());else if(checkPlaceholder(pos))sequence.push(getPlaceholder());}return sequence;}function checkTypeSelector(i){if(i >= tokensLength)return 0;var start=i;var l=undefined;if(l = checkNamePrefix(i))i += l;if(tokens[i].type === TokenType.Asterisk)i++;else if(l = checkIdentOrInterpolation(i))i += l;else return 0;return i - start;}function getTypeSelector(){var type=NodeType.TypeSelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkNamePrefix(pos))content.push(getNamePrefix());if(checkIdentOrInterpolation(pos))content = content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);}function checkAttributeSelector(i){var l=undefined;if(l = checkAttributeSelector1(i))tokens[i].attributeSelectorType = 1;else if(l = checkAttributeSelector2(i))tokens[i].attributeSelectorType = 2;return l;}function getAttributeSelector(){var type=tokens[pos].attributeSelectorType;if(type === 1)return getAttributeSelector1();else return getAttributeSelector2();} /**
+	 * (1) `[panda=nani]`
+	 * (2) `[panda='nani']`
+	 * (3) `[panda='nani' i]`
+	 *
+	 */function checkAttributeSelector1(i){var start=i;if(tokens[i].type === TokenType.LeftSquareBracket)i++;else return 0;var l=undefined;if(l = checkSC(i))i += l;if(l = checkAttributeName(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkAttributeMatch(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkAttributeValue(i))i += l;else return 0;if(l = checkSC(i))i += l;if(l = checkAttributeFlags(i)){i += l;if(l = checkSC(i))i += l;}if(tokens[i].type === TokenType.RightSquareBracket)i++;else return 0;return i - start;}function getAttributeSelector1(){var type=NodeType.AttributeSelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[]; // Skip `[`.
+	pos++;content = content.concat(getSC());content.push(getAttributeName());content = content.concat(getSC());content.push(getAttributeMatch());content = content.concat(getSC());content.push(getAttributeValue());content = content.concat(getSC());if(checkAttributeFlags(pos)){content.push(getAttributeFlags());content = content.concat(getSC());} // Skip `]`.
+	pos++;var end=getLastPosition(content,line,column,1);return newNode(type,content,line,column,end);} /**
+	 * (1) `[panda]`
+	 */function checkAttributeSelector2(i){var start=i;if(tokens[i].type === TokenType.LeftSquareBracket)i++;else return 0;var l=undefined;if(l = checkSC(i))i += l;if(l = checkAttributeName(i))i += l;else return 0;if(l = checkSC(i))i += l;if(tokens[i].type === TokenType.RightSquareBracket)i++;else return 0;return i - start;}function getAttributeSelector2(){var type=NodeType.AttributeSelectorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[]; // Skip `[`.
+	pos++;content = content.concat(getSC());content.push(getAttributeName());content = content.concat(getSC()); // Skip `]`.
+	pos++;var end=getLastPosition(content,line,column,1);return newNode(type,content,line,column,end);}function checkAttributeName(i){var start=i;var l=undefined;if(l = checkNamePrefix(i))i += l;if(l = checkIdentOrInterpolation(i))i += l;else return 0;return i - start;}function getAttributeName(){var type=NodeType.AttributeNameType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkNamePrefix(pos))content.push(getNamePrefix());content = content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);}function checkAttributeMatch(i){var l=undefined;if(l = checkAttributeMatch1(i))tokens[i].attributeMatchType = 1;else if(l = checkAttributeMatch2(i))tokens[i].attributeMatchType = 2;return l;}function getAttributeMatch(){var type=tokens[pos].attributeMatchType;if(type === 1)return getAttributeMatch1();else return getAttributeMatch2();}function checkAttributeMatch1(i){var start=i;var type=tokens[i].type;if(type === TokenType.Tilde || type === TokenType.VerticalLine || type === TokenType.CircumflexAccent || type === TokenType.DollarSign || type === TokenType.Asterisk)i++;else return 0;if(tokens[i].type === TokenType.EqualsSign)i++;else return 0;return i - start;}function getAttributeMatch1(){var type=NodeType.AttributeMatchType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=tokens[pos].value + tokens[pos + 1].value;pos += 2;return newNode(type,content,line,column);}function checkAttributeMatch2(i){if(tokens[i].type === TokenType.EqualsSign)return 1;else return 0;}function getAttributeMatch2(){var type=NodeType.AttributeMatchType;var token=tokens[pos];var line=token.ln;var column=token.col;var content='=';pos++;return newNode(type,content,line,column);}function checkAttributeValue(i){return checkString(i) || checkIdentOrInterpolation(i);}function getAttributeValue(){var type=NodeType.AttributeValueType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkString(pos))content.push(getString());else content = content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);}function checkAttributeFlags(i){return checkIdentOrInterpolation(i);}function getAttributeFlags(){var type=NodeType.AttributeFlagsType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=getIdentOrInterpolation();return newNode(type,content,line,column);}function checkNamePrefix(i){if(i >= tokensLength)return 0;var l=undefined;if(l = checkNamePrefix1(i))tokens[i].namePrefixType = 1;else if(l = checkNamePrefix2(i))tokens[i].namePrefixType = 2;return l;}function getNamePrefix(){var type=tokens[pos].namePrefixType;if(type === 1)return getNamePrefix1();else return getNamePrefix2();} /**
+	 * (1) `panda|`
+	 * (2) `panda<comment>|`
+	 */function checkNamePrefix1(i){var start=i;var l=undefined;if(l = checkNamespacePrefix(i))i += l;else return 0;if(l = checkCommentML(i))i += l;if(l = checkNamespaceSeparator(i))i += l;else return 0;return i - start;}function getNamePrefix1(){var type=NodeType.NamePrefixType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];content.push(getNamespacePrefix());if(checkCommentML(pos))content.push(getCommentML());content.push(getNamespaceSeparator());return newNode(type,content,line,column);} /**
+	 * (1) `|`
+	 */function checkNamePrefix2(i){return checkNamespaceSeparator(i);}function getNamePrefix2(){var type=NodeType.NamePrefixType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[getNamespaceSeparator()];return newNode(type,content,line,column);} /**
+	 * (1) `*`
+	 * (2) `panda`
+	 */function checkNamespacePrefix(i){if(i >= tokensLength)return 0;var l=undefined;if(tokens[i].type === TokenType.Asterisk)return 1;else if(l = checkIdentOrInterpolation(i))return l;else return 0;}function getNamespacePrefix(){var type=NodeType.NamespacePrefixType;var token=tokens[pos];var line=token.ln;var column=token.col;var content=[];if(checkIdentOrInterpolation(pos))content = content.concat(getIdentOrInterpolation());return newNode(type,content,line,column);} /**
+	 * (1) `|`
+	 */function checkNamespaceSeparator(i){if(i >= tokensLength)return 0;if(tokens[i].type === TokenType.VerticalLine)return 1;else return 0;}function getNamespaceSeparator(){var type=NodeType.NamespaceSeparatorType;var token=tokens[pos];var line=token.ln;var column=token.col;var content='|';pos++;return newNode(type,content,line,column);}
+
+/***/ },
+/* 14 */
+/***/ function(module, exports) {
+
+	'use strict';
+
+	module.exports = {
+	  ArgumentsType: 'arguments',
+	  AtkeywordType: 'atkeyword',
+	  AtruleType: 'atrule',
+	  AttributeSelectorType: 'attributeSelector',
+	  AttributeNameType: 'attributeName',
+	  AttributeFlagsType: 'attributeFlags',
+	  AttributeMatchType: 'attributeMatch',
+	  AttributeValueType: 'attributeValue',
+	  BlockType: 'block',
+	  BracketsType: 'brackets',
+	  ClassType: 'class',
+	  CombinatorType: 'combinator',
+	  CommentMLType: 'multilineComment',
+	  CommentSLType: 'singlelineComment',
+	  ConditionType: 'condition',
+	  ConditionalStatementType: 'conditionalStatement',
+	  DeclarationType: 'declaration',
+	  DeclDelimType: 'declarationDelimiter',
+	  DefaultType: 'default',
+	  DelimType: 'delimiter',
+	  DimensionType: 'dimension',
+	  EscapedStringType: 'escapedString',
+	  ExtendType: 'extend',
+	  ExpressionType: 'expression',
+	  FunctionType: 'function',
+	  GlobalType: 'global',
+	  IdentType: 'ident',
+	  ImportantType: 'important',
+	  IncludeType: 'include',
+	  InterpolationType: 'interpolation',
+	  InterpolatedVariableType: 'interpolatedVariable',
+	  KeyframesSelectorType: 'keyframesSelector',
+	  LoopType: 'loop',
+	  MixinType: 'mixin',
+	  NamePrefixType: 'namePrefix',
+	  NamespacePrefixType: 'namespacePrefix',
+	  NamespaceSeparatorType: 'namespaceSeparator',
+	  NumberType: 'number',
+	  OperatorType: 'operator',
+	  OptionalType: 'optional',
+	  ParenthesesType: 'parentheses',
+	  ParentSelectorType: 'parentSelector',
+	  ParentSelectorExtensionType: 'parentSelectorExtension',
+	  PercentageType: 'percentage',
+	  PlaceholderType: 'placeholder',
+	  ProgidType: 'progid',
+	  PropertyType: 'property',
+	  PropertyDelimType: 'propertyDelimiter',
+	  PseudocType: 'pseudoClass',
+	  PseudoeType: 'pseudoElement',
+	  RawType: 'raw',
+	  RulesetType: 'ruleset',
+	  SType: 'space',
+	  SelectorType: 'selector',
+	  ShashType: 'id',
+	  StringType: 'string',
+	  StylesheetType: 'stylesheet',
+	  TypeSelectorType: 'typeSelector',
+	  UriType: 'uri',
+	  ValueType: 'value',
+	  VariableType: 'variable',
+	  VariablesListType: 'variablesList',
+	  VhashType: 'color'
+	};
+
+/***/ },
+/* 15 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	module.exports = function (css, tabSize) {
+	  var TokenType = __webpack_require__(12);
+
+	  var tokens = [];
+	  var urlMode = false;
+	  var blockMode = 0;
+	  var c = undefined; // Current character
+	  var cn = undefined; // Next character
+	  var pos = 0;
+	  var tn = 0;
+	  var ln = 1;
+	  var col = 1;
+
+	  var Punctuation = {
+	    ' ': TokenType.Space,
+	    '\n': TokenType.Newline,
+	    '\r': TokenType.Newline,
+	    '\t': TokenType.Tab,
+	    '!': TokenType.ExclamationMark,
+	    '"': TokenType.QuotationMark,
+	    '#': TokenType.NumberSign,
+	    '$': TokenType.DollarSign,
+	    '%': TokenType.PercentSign,
+	    '&': TokenType.Ampersand,
+	    '\'': TokenType.Apostrophe,
+	    '(': TokenType.LeftParenthesis,
+	    ')': TokenType.RightParenthesis,
+	    '*': TokenType.Asterisk,
+	    '+': TokenType.PlusSign,
+	    ',': TokenType.Comma,
+	    '-': TokenType.HyphenMinus,
+	    '.': TokenType.FullStop,
+	    '/': TokenType.Solidus,
+	    ':': TokenType.Colon,
+	    ';': TokenType.Semicolon,
+	    '<': TokenType.LessThanSign,
+	    '=': TokenType.EqualsSign,
+	    '==': TokenType.EqualitySign,
+	    '!=': TokenType.InequalitySign,
+	    '>': TokenType.GreaterThanSign,
+	    '?': TokenType.QuestionMark,
+	    '@': TokenType.CommercialAt,
+	    '[': TokenType.LeftSquareBracket,
+	    ']': TokenType.RightSquareBracket,
+	    '^': TokenType.CircumflexAccent,
+	    '_': TokenType.LowLine,
+	    '{': TokenType.LeftCurlyBracket,
+	    '|': TokenType.VerticalLine,
+	    '}': TokenType.RightCurlyBracket,
+	    '~': TokenType.Tilde
+	  };
+
+	  /**
+	   * Add a token to the token list
+	   * @param {string} type
+	   * @param {string} value
+	   */
+	  function pushToken(type, value, column) {
+	    tokens.push({
+	      tn: tn++,
+	      ln: ln,
+	      col: column,
+	      type: type,
+	      value: value
+	    });
+	  }
+
+	  /**
+	   * Check if a character is a decimal digit
+	   * @param {string} c Character
+	   * @returns {boolean}
+	   */
+	  function isDecimalDigit(c) {
+	    return '0123456789'.indexOf(c) >= 0;
+	  }
+
+	  /**
+	   * Parse spaces
+	   * @param {string} css Unparsed part of CSS string
+	   */
+	  function parseSpaces(css) {
+	    var start = pos;
+
+	    // Read the string until we meet a non-space character:
+	    for (; pos < css.length; pos++) {
+	      if (css.charAt(pos) !== ' ') break;
+	    }
+
+	    // Add a substring containing only spaces to tokens:
+	    pushToken(TokenType.Space, css.substring(start, pos--), col);
+	    col += pos - start;
+	  }
+
+	  /**
+	   * Parse a string within quotes
+	   * @param {string} css Unparsed part of CSS string
+	   * @param {string} q Quote (either `'` or `"`)
+	   */
+	  function parseString(css, q) {
+	    var start = pos;
+
+	    // Read the string until we meet a matching quote:
+	    for (pos++; pos < css.length; pos++) {
+	      // Skip escaped quotes:
+	      if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) === q) break;
+	    }
+
+	    // Add the string (including quotes) to tokens:
+	    var type = q === '"' ? TokenType.StringDQ : TokenType.StringSQ;
+	    pushToken(type, css.substring(start, pos + 1), col);
+	    col += pos - start;
+	  }
+
+	  /**
+	   * Parse numbers
+	   * @param {string} css Unparsed part of CSS string
+	   */
+	  function parseDecimalNumber(css) {
+	    var start = pos;
+
+	    // Read the string until we meet a character that's not a digit:
+	    for (; pos < css.length; pos++) {
+	      if (!isDecimalDigit(css.charAt(pos))) break;
+	    }
+
+	    // Add the number to tokens:
+	    pushToken(TokenType.DecimalNumber, css.substring(start, pos--), col);
+	    col += pos - start;
+	  }
+
+	  /**
+	   * Parse identifier
+	   * @param {string} css Unparsed part of CSS string
+	   */
+	  function parseIdentifier(css) {
+	    var start = pos;
+
+	    // Skip all opening slashes:
+	    while (css.charAt(pos) === '/') pos++;
+
+	    // Read the string until we meet a punctuation mark:
+	    for (; pos < css.length; pos++) {
+	      // Skip all '\':
+	      if (css.charAt(pos) === '\\') pos++;else if (css.charAt(pos) in Punctuation) break;
+	    }
+
+	    var ident = css.substring(start, pos--);
+
+	    // Enter url mode if parsed substring is `url`:
+	    if (!urlMode && ident === 'url' && css.charAt(pos + 1) === '(') {
+	      urlMode = true;
+	    }
+
+	    // Add identifier to tokens:
+	    pushToken(TokenType.Identifier, ident, col);
+	    col += pos - start;
+	  }
+
+	  /**
+	   * Parse equality sign
+	   */
+	  function parseEquality() {
+	    pushToken(TokenType.EqualitySign, '==', col);
+	    pos++;
+	    col++;
+	  }
+
+	  /**
+	   * Parse inequality sign
+	   */
+	  function parseInequality() {
+	    pushToken(TokenType.InequalitySign, '!=', col);
+	    pos++;
+	    col++;
+	  }
+
+	  /**
+	  * Parse a multiline comment
+	  * @param {string} css Unparsed part of CSS string
+	  */
+	  function parseMLComment(css) {
+	    var start = pos;
+
+	    // Read the string until we meet `*/`.
+	    // Since we already know first 2 characters (`/*`), start reading
+	    // from `pos + 2`:
+	    for (pos += 2; pos < css.length; pos++) {
+	      if (css.charAt(pos) === '*' && css.charAt(pos + 1) === '/') {
+	        pos++;
+	        break;
+	      }
+	    }
+
+	    // Add full comment (including `/*` and `*/`) to the list of tokens:
+	    var comment = css.substring(start, pos + 1);
+	    pushToken(TokenType.CommentML, comment, col);
+
+	    var newlines = comment.split('\n');
+	    if (newlines.length > 1) {
+	      ln += newlines.length - 1;
+	      col = newlines[newlines.length - 1].length;
+	    } else {
+	      col += pos - start;
+	    }
+	  }
+
+	  /**
+	  * Parse a single line comment
+	  * @param {string} css Unparsed part of CSS string
+	  */
+	  function parseSLComment(css) {
+	    var start = pos;
+
+	    // Read the string until we meet line break.
+	    // Since we already know first 2 characters (`//`), start reading
+	    // from `pos + 2`:
+	    for (pos += 2; pos < css.length; pos++) {
+	      if (css.charAt(pos) === '\n' || css.charAt(pos) === '\r') {
+	        break;
+	      }
+	    }
+
+	    // Add comment (including `//` and line break) to the list of tokens:
+	    pushToken(TokenType.CommentSL, css.substring(start, pos--), col);
+	    col += pos - start;
+	  }
+
+	  /**
+	   * Convert a CSS string to a list of tokens
+	   * @param {string} css CSS string
+	   * @returns {Array} List of tokens
+	   * @private
+	   */
+	  function getTokens(css) {
+	    // Parse string, character by character:
+	    for (pos = 0; pos < css.length; col++, pos++) {
+	      c = css.charAt(pos);
+	      cn = css.charAt(pos + 1);
+
+	      // If we meet `/*`, it's a start of a multiline comment.
+	      // Parse following characters as a multiline comment:
+	      if (c === '/' && cn === '*') {
+	        parseMLComment(css);
+	      }
+
+	      // If we meet `//` and it is not a part of url:
+	      else if (!urlMode && c === '/' && cn === '/') {
+	          // If we're currently inside a block, treat `//` as a start
+	          // of identifier. Else treat `//` as a start of a single-line
+	          // comment:
+	          parseSLComment(css);
+	        }
+
+	        // If current character is a double or single quote, it's a start
+	        // of a string:
+	        else if (c === '"' || c === "'") {
+	            parseString(css, c);
+	          }
+
+	          // If current character is a space:
+	          else if (c === ' ') {
+	              parseSpaces(css);
+	            }
+
+	            // If current character is `=`, it must be combined with next `=`
+	            else if (c === '=' && cn === '=') {
+	                parseEquality(css);
+	              }
+
+	              // If we meet `!=`, this must be inequality
+	              else if (c === '!' && cn === '=') {
+	                  parseInequality(css);
+	                }
+
+	                // If current character is a punctuation mark:
+	                else if (c in Punctuation) {
+	                    // Check for CRLF here or just LF
+	                    if (c === '\r' && cn === '\n' || c === '\n') {
+	                      // If \r we know the next character is \n due to statement above
+	                      // so we push a CRLF token type to the token list and importantly
+	                      // skip the next character so as not to double count newlines or
+	                      // columns etc
+	                      if (c === '\r') {
+	                        pushToken(TokenType.Newline, '\r\n', col);
+	                        pos++; // If CRLF skip the next character and push crlf token
+	                      } else if (c === '\n') {
+	                          // If just a LF newline and not part of CRLF newline we can just
+	                          // push punctuation as usual
+	                          pushToken(Punctuation[c], c, col);
+	                        }
+
+	                      ln++; // Go to next line
+	                      col = 0; // Reset the column count
+	                    } else if (c !== '\r' && c !== '\n') {
+	                        // Handle all other punctuation and add to list of tokens
+	                        pushToken(Punctuation[c], c, col);
+	                      } // Go to next line
+	                    if (c === ')') urlMode = false; // Exit url mode
+	                    if (c === '{') blockMode++; // Enter a block
+	                    if (c === '}') blockMode--; // Exit a block
+	                    else if (c === '\t' && tabSize > 1) col += tabSize - 1;
+	                  }
+
+	                  // If current character is a decimal digit:
+	                  else if (isDecimalDigit(c)) {
+	                      parseDecimalNumber(css);
+	                    }
+
+	                    // If current character is anything else:
+	                    else {
+	                        parseIdentifier(css);
+	                      }
+	    }
+
+	    return tokens;
+	  }
+
+	  return getTokens(css);
+	};
+
+/***/ },
+/* 16 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
+	var Node = __webpack_require__(1);
+	var NodeTypes = __webpack_require__(14);
+
+	module.exports = function () {
+	  return new Node({
+	    type: NodeTypes.StylesheetType,
+	    content: [],
+	    start: [0, 0],
+	    end: [0, 0]
+	  });
+	};
+
+/***/ }
+/******/ ])
+});
+;
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/gonzales/module.json b/third_party/WebKit/Source/devtools/front_end/gonzales/module.json
new file mode 100644
index 0000000..1e0d51a
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/gonzales/module.json
@@ -0,0 +1,19 @@
+{
+    "dependencies": [
+        "formatter_worker"
+    ],
+    "scripts": [
+        "gonzales-scss.js",
+        "SCSSParser.js"
+    ],
+    "extensions": [
+        {
+            "type": "@WebInspector.FormatterWorkerContentParser",
+            "className": "WebInspector.SCSSParser",
+            "mimeType": "text/x-scss"
+        }
+    ],
+    "skip_compilation": [
+        "gonzales-scss.js"
+    ]
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index 9e92fdf..711852f5 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -108,7 +108,6 @@
         Runtime.experiments.register("cpuThrottling", "CPU throttling", true);
         Runtime.experiments.register("deviceFrames", "Device frames", true);
         Runtime.experiments.register("emptySourceMapAutoStepping", "Empty sourcemap auto-stepping");
-        Runtime.experiments.register("samplingHeapProfiler", "Sampling Heap Profiler", true);
         Runtime.experiments.register("inputEventsOnTimelineOverview", "Input events on Timeline overview", true);
         Runtime.experiments.register("layersPanel", "Layers panel");
         Runtime.experiments.register("layoutEditor", "Layout editor", true);
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
index bef3722..4d1281b 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
@@ -679,8 +679,7 @@
      */
     _registerProfileType: function(profileType)
     {
-        if (Runtime.experiments.isEnabled("samplingHeapProfiler") || profileType !== WebInspector.SamplingHeapProfileType.instance)
-            this._launcherView.addProfileType(profileType);
+        this._launcherView.addProfileType(profileType);
         var profileTypeSection = new WebInspector.ProfileTypeSidebarSection(this, profileType);
         this._typeIdToSidebarSection[profileType.id] = profileTypeSection;
         this._sidebarTree.appendChild(profileTypeSection);
diff --git a/third_party/WebKit/Source/devtools/front_end/sass/ASTService.js b/third_party/WebKit/Source/devtools/front_end/sass/ASTService.js
index cf2ca5c7..c7803380 100644
--- a/third_party/WebKit/Source/devtools/front_end/sass/ASTService.js
+++ b/third_party/WebKit/Source/devtools/front_end/sass/ASTService.js
@@ -7,8 +7,6 @@
  */
 WebInspector.ASTService = function()
 {
-    this._sassInitPromise = self.runtime.instancePromise(WebInspector.TokenizerFactory);
-    this._terminated = false;
 }
 
 WebInspector.ASTService.prototype = {
@@ -19,7 +17,6 @@
      */
     parseCSS: function(url, text)
     {
-        console.assert(!this._terminated, "Illegal call parseCSS on terminated ASTService.");
         return WebInspector.SASSSupport.parseCSS(url, text);
     },
 
@@ -30,7 +27,6 @@
      */
     parseSCSS: function(url, text)
     {
-        console.assert(!this._terminated, "Illegal call parseSCSS on terminated ASTService.");
-        return this._sassInitPromise.then(tokenizer => WebInspector.SASSSupport.parseSCSS(tokenizer, url, text));
+        return WebInspector.SASSSupport.parseSCSS(url, text);
     },
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js b/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js
index c827004..07a53fe 100644
--- a/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js
+++ b/third_party/WebKit/Source/devtools/front_end/sass/SASSSupport.js
@@ -42,210 +42,56 @@
 }
 
 /**
- * @param {!WebInspector.TokenizerFactory} tokenizerFactory
  * @param {string} url
- * @param {string} text
- * @return {!WebInspector.SASSSupport.AST}
+ * @param {string} content
+ * @return {!Promise<!WebInspector.SASSSupport.AST>}
  */
-WebInspector.SASSSupport.parseSCSS = function(tokenizerFactory, url, text)
+WebInspector.SASSSupport.parseSCSS = function(url, content)
 {
-    var document = new WebInspector.SASSSupport.ASTDocument(url, new WebInspector.Text(text));
-    var result = WebInspector.SASSSupport._innerParseSCSS(document, tokenizerFactory);
+    var text = new WebInspector.Text(content);
+    var document = new WebInspector.SASSSupport.ASTDocument(url, text);
 
-    var rules = [
-        new WebInspector.SASSSupport.Rule(document, "variables", WebInspector.TextRange.createFromLocation(0, 0), result.variables),
-        new WebInspector.SASSSupport.Rule(document, "properties", WebInspector.TextRange.createFromLocation(0, 0), result.properties),
-        new WebInspector.SASSSupport.Rule(document, "mixins", WebInspector.TextRange.createFromLocation(0, 0), result.mixins)
-    ];
-
-    return new WebInspector.SASSSupport.AST(document, rules);
-}
-
-/** @enum {string} */
-WebInspector.SASSSupport.SCSSParserStates = {
-    Initial: "Initial",
-    PropertyName: "PropertyName",
-    PropertyValue: "PropertyValue",
-    VariableName: "VariableName",
-    VariableValue: "VariableValue",
-    MixinName: "MixinName",
-    MixinValue: "MixinValue",
-    Media: "Media"
-}
-
-/**
- * @param {!WebInspector.SASSSupport.ASTDocument} document
- * @param {!WebInspector.TokenizerFactory} tokenizerFactory
- * @return {!{variables: !Array<!WebInspector.SASSSupport.Property>, properties: !Array<!WebInspector.SASSSupport.Property>, mixins: !Array<!WebInspector.SASSSupport.Property>}}
- */
-WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory)
-{
-    var properties = [];
-    var variables = [];
-    var mixins = [];
-
-    var States = WebInspector.SASSSupport.SCSSParserStates;
-    var state = States.Initial;
-    var propertyName, propertyValue;
-    var variableName, variableValue;
-    var mixinName, mixinValue;
-    var UndefTokenType = {};
-
-    var cursor = new WebInspector.TextCursor(document.text.lineEndings());
+    return WebInspector.formatterWorkerPool.runTask("parseSCSS", {content: content}).then(onParsed);
 
     /**
-     * @param {string} tokenValue
-     * @param {?string} tokenTypes
-     * @param {number} startPosition
-     * @param {number} endPosition
+     * @param {?MessageEvent} event
+     * @return {!WebInspector.SASSSupport.AST}
      */
-    function processToken(tokenValue, tokenTypes, startPosition, endPosition)
+    function onParsed(event)
     {
-        cursor.advance(startPosition);
-        var startLine = cursor.lineNumber();
-        var startColumn = cursor.columnNumber();
-        cursor.advance(endPosition);
-        var endLine = cursor.lineNumber();
-        var endColumn = cursor.columnNumber();
+        if (!event)
+            return new WebInspector.SASSSupport.AST(document, []);
+        var data = /** @type {!{properties: !Array<!Object>, variables: !Array<!Object>, mixins: !Array<!Object>}} */(event.data);
+        var properties = data.properties.map(createProperty);
+        var variables = data.variables.map(createProperty);
+        var mixins = data.mixins.map(createProperty);
+        var rules = [
+            new WebInspector.SASSSupport.Rule(document, "variables", WebInspector.TextRange.createFromLocation(0, 0), variables),
+            new WebInspector.SASSSupport.Rule(document, "properties", WebInspector.TextRange.createFromLocation(0, 0), properties),
+            new WebInspector.SASSSupport.Rule(document, "mixins", WebInspector.TextRange.createFromLocation(0, 0), mixins)
+        ];
 
-        var tokenType = tokenTypes ? tokenTypes.split(" ").keySet() : UndefTokenType;
-        switch (state) {
-        case States.Initial:
-            if (tokenType["css-variable-2"]) {
-                variableName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
-                state = States.VariableName;
-            } else if (tokenType["css-property"] || tokenType["css-meta"]) {
-                propertyName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
-                state = States.PropertyName;
-            } else if (tokenType["css-def"] && tokenValue === "@include") {
-                mixinName = new WebInspector.SASSSupport.TextNode(document, tokenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn));
-                state = States.MixinName;
-            } else if (tokenType["css-comment"]) {
-                // Support only a one-line comments.
-                if (startLine !== endLine || tokenValue.substring(0, 2) !== "/*" || tokenValue.substring(tokenValue.length - 2) !== "*/")
-                    break;
-                var uncommentedText = tokenValue.substring(2, tokenValue.length - 2);
-                var fakeRuleText = "a{" + uncommentedText + "}";
-                var fakeDocument = new WebInspector.SASSSupport.ASTDocument("", new WebInspector.Text(fakeRuleText));
-                var result = WebInspector.SASSSupport._innerParseSCSS(fakeDocument, tokenizerFactory);
-                if (result.properties.length === 1 && result.variables.length === 0 && result.mixins.length === 0) {
-                    var disabledProperty = result.properties[0];
-                    var nameRange = rebaseInsideOneLineComment(disabledProperty.name.range, startLine, startColumn);
-                    var valueRange = rebaseInsideOneLineComment(disabledProperty.value.range, startLine, startColumn);
-                    var name = new WebInspector.SASSSupport.TextNode(document, disabledProperty.name.text, nameRange);
-                    var value = new WebInspector.SASSSupport.TextNode(document, disabledProperty.value.text, valueRange);
-                    var range = new WebInspector.TextRange(startLine, startColumn, startLine, endColumn);
-                    var property = new WebInspector.SASSSupport.Property(document, name, value, range, true);
-                    properties.push(property);
-                }
-            } else if (tokenType["css-def"] && tokenValue === "@media") {
-                state = States.Media;
-            }
-            break;
-        case States.VariableName:
-            if (tokenValue === "}" && tokenType === UndefTokenType) {
-                state = States.Initial;
-            } else if (tokenValue === ")" && tokenType === UndefTokenType) {
-                state = States.Initial;
-            } else if (tokenValue === ":" && tokenType === UndefTokenType) {
-                state = States.VariableValue;
-                variableValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
-            } else if (tokenType !== UndefTokenType) {
-                state = States.Initial;
-            }
-            break;
-        case States.VariableValue:
-            if (tokenValue === ";" && tokenType === UndefTokenType) {
-                variableValue.range.endLine = startLine;
-                variableValue.range.endColumn = startColumn;
-                var variable = new WebInspector.SASSSupport.Property(document, variableName, variableValue, variableName.range.clone(), false);
-                variable.range.endLine = startLine;
-                variable.range.endColumn = endColumn;
-                variables.push(variable);
-                state = States.Initial;
-            } else {
-                variableValue.text += tokenValue;
-            }
-            break;
-        case States.PropertyName:
-            if (tokenValue === "{" && tokenType === UndefTokenType) {
-                state = States.Initial;
-            } else if (tokenValue === ":" && tokenType === UndefTokenType) {
-                state = States.PropertyValue;
-                propertyName.range.endLine = startLine;
-                propertyName.range.endColumn = startColumn;
-                propertyValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
-            } else if (tokenType["css-property"]) {
-                propertyName.text += tokenValue;
-            }
-            break;
-        case States.PropertyValue:
-            if (tokenValue === "{" && tokenType === UndefTokenType) {
-                state = States.Initial;
-            } else if ((tokenValue === "}" || tokenValue === ";") && tokenType === UndefTokenType) {
-                propertyValue.range.endLine = startLine;
-                propertyValue.range.endColumn = startColumn;
-                var property = new WebInspector.SASSSupport.Property(document, propertyName, propertyValue, propertyName.range.clone(), false);
-                property.range.endLine = startLine;
-                property.range.endColumn = endColumn;
-                properties.push(property);
-                state = States.Initial;
-            } else {
-                propertyValue.text += tokenValue;
-            }
-            break;
-        case States.MixinName:
-            if (tokenValue === "(" && tokenType === UndefTokenType) {
-                state = States.MixinValue;
-                mixinName.range.endLine = startLine;
-                mixinName.range.endColumn = startColumn;
-                mixinValue = new WebInspector.SASSSupport.TextNode(document, "", WebInspector.TextRange.createFromLocation(startLine, endColumn));
-            } else if (tokenValue === ";" && tokenType === UndefTokenType) {
-                state = States.Initial;
-                mixinValue = null;
-            } else {
-                mixinName.text += tokenValue;
-            }
-            break;
-        case States.MixinValue:
-            if (tokenValue === ")" && tokenType === UndefTokenType) {
-                mixinValue.range.endLine = startLine;
-                mixinValue.range.endColumn = startColumn;
-                var mixin = new WebInspector.SASSSupport.Property(document, mixinName, /** @type {!WebInspector.SASSSupport.TextNode} */(mixinValue), mixinName.range.clone(), false);
-                mixin.range.endLine = startLine;
-                mixin.range.endColumn = endColumn;
-                mixins.push(mixin);
-                state = States.Initial;
-            } else {
-                mixinValue.text += tokenValue;
-            }
-            break;
-        case States.Media:
-            if (tokenValue === "{" && tokenType === UndefTokenType)
-                state = States.Initial;
-            break;
-        default:
-            console.assert(false, "Unknown SASS parser state.");
-        }
+        return new WebInspector.SASSSupport.AST(document, rules);
     }
-    var tokenizer = tokenizerFactory.createTokenizer("text/x-scss");
-    tokenizer(document.text.value(), processToken);
-
-    return {
-        variables: variables,
-        properties: properties,
-        mixins: mixins
-    };
 
     /**
-     * @param {!WebInspector.TextRange} range
-     * @param {number} startLine
-     * @param {number} startColumn
-     * @return {!WebInspector.TextRange}
+     * @param {!Object} payload
      */
-    function rebaseInsideOneLineComment(range, startLine, startColumn)
+    function createTextNode(payload)
     {
-        return new WebInspector.TextRange(range.startLine + startLine, range.startColumn + startColumn, range.endLine + startLine, range.endColumn + startColumn);
+        var range = WebInspector.TextRange.fromObject(payload);
+        var value = text.extract(range);
+        return new WebInspector.SASSSupport.TextNode(document, text.extract(range), range);
+    }
+
+    /**
+     * @param {!Object} payload
+     */
+    function createProperty(payload)
+    {
+        var name = createTextNode(payload.name);
+        var value = createTextNode(payload.value);
+        return new WebInspector.SASSSupport.Property(document, name, value, WebInspector.TextRange.fromObject(payload.range), payload.disabled);
     }
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSModel.js
index 1cd8131..7536064 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSModel.js
@@ -157,7 +157,6 @@
             var factoryExtension = this._factoryForSourceMap(sourceMap);
             if (!factoryExtension)
                 return Promise.resolve(/** @type {?WebInspector.SourceMap} */(sourceMap));
-
             return factoryExtension.instancePromise()
                 .then(factory => factory.editableSourceMap(this.target(), sourceMap))
                 .then(map => map || sourceMap)
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js b/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js
index 2ac8903e..6cc960f 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/AdvancedSearchView.js
@@ -25,7 +25,7 @@
 
     this._search = WebInspector.HistoryInput.create();
     this._searchPanelElement.appendChild(this._search);
-    this._search.placeholder = WebInspector.UIString("Search all sources (use \"file:\" to filter by path)");
+    this._search.placeholder = WebInspector.UIString("Search all sources (use \"file:\" to filter by path)\u200e");
     this._search.setAttribute("type", "text");
     this._search.classList.add("search-config-search");
     this._search.setAttribute("results", "0");
diff --git a/third_party/WebKit/Source/devtools/scripts/compile_frontend.py b/third_party/WebKit/Source/devtools/scripts/compile_frontend.py
index b95dee3..828699a 100755
--- a/third_party/WebKit/Source/devtools/scripts/compile_frontend.py
+++ b/third_party/WebKit/Source/devtools/scripts/compile_frontend.py
@@ -126,7 +126,7 @@
     sys.__excepthook__(exctype, value, traceback)
 sys.excepthook = error_excepthook
 
-application_descriptors = ['inspector.json', 'toolbox.json']
+application_descriptors = ['inspector.json', 'toolbox.json', 'formatter_worker.json', 'heap_snapshot_worker.json', 'temp_storage_shared_worker.json']
 loader = modular_build.DescriptorLoader(devtools_frontend_path)
 descriptors = loader.load_applications(application_descriptors)
 modules_by_name = descriptors.modules
diff --git a/third_party/WebKit/Source/devtools/scripts/lint_javascript.py b/third_party/WebKit/Source/devtools/scripts/lint_javascript.py
new file mode 100755
index 0000000..3293c74
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/scripts/lint_javascript.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env 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.
+
+import os
+import os.path as path
+import re
+import subprocess
+import sys
+
+files_to_lint = None
+
+if len(sys.argv) == 2:
+    if sys.argv[1] == "--help":
+        print("Usage: %s [file|dir|glob]*" % path.basename(sys.argv[0]))
+        print
+        print(" [file|dir|glob]*  Path or glob to run eslint on.")
+        print("                   If absent, the entire frontend will be checked.")
+        sys.exit(0)
+
+    else:
+        print "Linting only this path:\n %s" % sys.argv[1:]
+        files_to_lint = sys.argv[1:]
+
+
+is_cygwin = sys.platform == "cygwin"
+
+
+def popen(arguments):
+    return subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+
+def to_platform_path(filepath):
+    if not is_cygwin:
+        return filepath
+    return re.sub(r"^/cygdrive/(\w)", "\\1:", filepath)
+
+
+def to_platform_path_exact(filepath):
+    if not is_cygwin:
+        return filepath
+    output, _ = popen(["cygpath", "-w", filepath]).communicate()
+    # pylint: disable=E1103
+    return output.strip().replace("\\", "\\\\")
+
+scripts_path = path.dirname(path.abspath(__file__))
+devtools_path = path.dirname(scripts_path)
+devtools_frontend_path = path.join(devtools_path, "front_end")
+
+
+# Based on http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python.
+def which(program):
+    def is_exe(fpath):
+        return path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+    fpath, fname = path.split(program)
+    if fpath:
+        if is_exe(program):
+            return program
+    else:
+        for part in os.environ["PATH"].split(os.pathsep):
+            part = part.strip("\"")
+            exe_file = path.join(part, program)
+            if is_exe(exe_file):
+                return exe_file
+    return None
+
+
+print "Linting JavaScript with eslint...\n"
+
+
+def js_lint(files_list=None):
+    eslint_errors_found = False
+
+    eslint_path = which("eslint")
+    if not eslint_path:
+        print "!! Skipping JavaScript linting because eslint is not installed."
+        print "!!   npm install -g eslint"
+        eslint_errors_found = False  # Linting is opt-in for now, so this is a soft failure
+        return eslint_errors_found
+
+    if files_list is None:
+        files_list = [devtools_frontend_path]
+
+    eslintconfig_path = path.join(devtools_path, "front_end/.eslintrc.js")
+    eslintignore_path = path.join(devtools_path, "front_end/.eslintignore")
+    exec_command = [
+        eslint_path,
+        "--config", to_platform_path_exact(eslintconfig_path),
+        "--ignore-path", to_platform_path_exact(eslintignore_path),
+        " ".join(files_list)
+        ]
+
+    eslint_proc = popen(exec_command)
+    (eslint_proc_out, _) = eslint_proc.communicate()
+    if eslint_proc.returncode != 0:
+        eslint_errors_found = True
+    else:
+        print "eslint exited successfully"
+
+    print eslint_proc_out
+
+
+errors_found = js_lint(files_to_lint)
+
+if errors_found:
+    print "ERRORS DETECTED"
+    sys.exit(1)
+else:
+    print "OK"
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
index e9102811..5e17912 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -1018,18 +1018,19 @@
 
 AXObject* AXLayoutObject::nextOnLine() const
 {
-    if (!m_layoutObject)
-        return 0;
+    if (!getLayoutObject())
+        return nullptr;
 
-    InlineBox* inlineBox;
-    if (m_layoutObject->isLayoutInline())
-        inlineBox = toLayoutInline(m_layoutObject)->lastLineBox();
-    else if (m_layoutObject->isText())
-        inlineBox = toLayoutText(m_layoutObject)->lastTextBox();
-    else
-        return 0;
+    InlineBox* inlineBox = nullptr;
+    if (getLayoutObject()->isLayoutInline())
+        inlineBox = toLayoutInline(getLayoutObject())->lastLineBox();
+    else if (getLayoutObject()->isText())
+        inlineBox = toLayoutText(getLayoutObject())->lastTextBox();
 
-    AXObject* result = 0;
+    if (!inlineBox)
+        return nullptr;
+
+    AXObject* result = nullptr;
     for (InlineBox* next = inlineBox->nextOnLine(); next; next = next->nextOnLine()) {
         LayoutObject* layoutObject = LineLayoutAPIShim::layoutObjectFrom(next->getLineLayoutItem());
         result = axObjectCache().getOrCreate(layoutObject);
@@ -1047,18 +1048,19 @@
 
 AXObject* AXLayoutObject::previousOnLine() const
 {
-    if (!m_layoutObject)
-        return 0;
+    if (!getLayoutObject())
+        return nullptr;
 
-    InlineBox* inlineBox;
-    if (m_layoutObject->isLayoutInline())
-        inlineBox = toLayoutInline(m_layoutObject)->firstLineBox();
-    else if (m_layoutObject->isText())
-        inlineBox = toLayoutText(m_layoutObject)->firstTextBox();
-    else
-        return 0;
+    InlineBox* inlineBox = nullptr;
+    if (getLayoutObject()->isLayoutInline())
+        inlineBox = toLayoutInline(getLayoutObject())->firstLineBox();
+    else if (getLayoutObject()->isText())
+        inlineBox = toLayoutText(getLayoutObject())->firstTextBox();
 
-    AXObject* result = 0;
+    if (!inlineBox)
+        return nullptr;
+
+    AXObject* result = nullptr;
     for (InlineBox* prev = inlineBox->prevOnLine(); prev; prev = prev->prevOnLine()) {
         LayoutObject* layoutObject = LineLayoutAPIShim::layoutObjectFrom(prev->getLineLayoutItem());
         result = axObjectCache().getOrCreate(layoutObject);
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp
index ffd38e6..b777d97 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasStyle.cpp
@@ -34,6 +34,7 @@
 #include "core/html/HTMLCanvasElement.h"
 #include "modules/canvas2d/CanvasGradient.h"
 #include "modules/canvas2d/CanvasPattern.h"
+#include "third_party/skia/include/core/SkShader.h"
 #include "wtf/PassRefPtr.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h b/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h
index 307618d..6e12cbac 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/csspaint/PaintRenderingContext2D.h
@@ -9,7 +9,8 @@
 #include "modules/ModulesExport.h"
 #include "modules/canvas2d/BaseRenderingContext2D.h"
 #include "platform/graphics/ImageBuffer.h"
-#include "third_party/skia/include/core/SkCanvas.h"
+
+class SkCanvas;
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/modules/mediasession/OWNERS b/third_party/WebKit/Source/modules/mediasession/OWNERS
index c66ab543..8e1a79d3 100644
--- a/third_party/WebKit/Source/modules/mediasession/OWNERS
+++ b/third_party/WebKit/Source/modules/mediasession/OWNERS
@@ -1,4 +1,3 @@
 avayvod@chromium.org
 davve@opera.com
 mlamouri@chromium.org
-philipj@opera.com
diff --git a/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp b/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp
index 8089d19..1b346c56 100644
--- a/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp
+++ b/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp
@@ -177,11 +177,8 @@
         return;
     }
 
-    // 2. If the sourceBuffer.updating attribute equals true, then run the following steps: ...
-    buffer->abortIfUpdating();
-
-    // Steps 3-8 are related to updating audioTracks, videoTracks, and textTracks which aren't implmented yet.
-    // FIXME(91649): support track selection
+    // Steps 2-8 are implemented by SourceBuffer::removedFromMediaSource.
+    buffer->removedFromMediaSource();
 
     // 9. If sourceBuffer is in activeSourceBuffers, then remove sourceBuffer from activeSourceBuffers ...
     m_activeSourceBuffers->remove(buffer);
@@ -191,7 +188,7 @@
     m_sourceBuffers->remove(buffer);
 
     // 11. Destroy all resources for sourceBuffer.
-    buffer->removedFromMediaSource();
+    // This should have been done already by SourceBuffer::removedFromMediaSource (steps 2-8) above.
 }
 
 void MediaSource::onReadyStateChange(const AtomicString& oldState, const AtomicString& newState)
@@ -215,6 +212,8 @@
         m_sourceBuffers->item(i)->removedFromMediaSource();
     m_sourceBuffers->clear();
 
+    m_attachedElement.clear();
+
     scheduleEvent(EventTypeNames::sourceclose);
 }
 
@@ -450,7 +449,6 @@
 
     if (state == closedKeyword()) {
         m_webMediaSource.clear();
-        m_attachedElement.clear();
     }
 
     if (oldState == state)
diff --git a/third_party/WebKit/Source/modules/mediasource/OWNERS b/third_party/WebKit/Source/modules/mediasource/OWNERS
index 88a1f84..90a1e19 100644
--- a/third_party/WebKit/Source/modules/mediasource/OWNERS
+++ b/third_party/WebKit/Source/modules/mediasource/OWNERS
@@ -1,2 +1,2 @@
-philipj@opera.com
+chcunningham@chromium.org
 wolenetz@chromium.org
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
index 3e8dffe..263f854 100644
--- a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
+++ b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
@@ -484,12 +484,85 @@
     WTF_LOG(Media, "SourceBuffer(%p)::removedFromMediaSource", this);
     abortIfUpdating();
 
+    if (RuntimeEnabledFeatures::audioVideoTracksEnabled()) {
+        ASSERT(m_source);
+        if (m_source->mediaElement()->audioTracks().length() > 0
+            || m_source->mediaElement()->videoTracks().length() > 0) {
+            removeMediaTracks();
+        }
+    }
+
     m_webSourceBuffer->removedFromMediaSource();
     m_webSourceBuffer.clear();
     m_source = nullptr;
     m_asyncEventQueue = nullptr;
 }
 
+void SourceBuffer::removeMediaTracks()
+{
+    ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+    // Spec: http://w3c.github.io/media-source/#widl-MediaSource-removeSourceBuffer-void-SourceBuffer-sourceBuffer
+    ASSERT(m_source);
+
+    HTMLMediaElement* mediaElement = m_source->mediaElement();
+    ASSERT(mediaElement);
+    // 3. Let SourceBuffer audioTracks list equal the AudioTrackList object returned by sourceBuffer.audioTracks.
+    // 4. If the SourceBuffer audioTracks list is not empty, then run the following steps:
+    // 4.1 Let HTMLMediaElement audioTracks list equal the AudioTrackList object returned by the audioTracks attribute on the HTMLMediaElement.
+    // 4.2 Let the removed enabled audio track flag equal false.
+    bool removedEnabledAudioTrack = false;
+    // 4.3 For each AudioTrack object in the SourceBuffer audioTracks list, run the following steps:
+    while (audioTracks().length() > 0) {
+        AudioTrack* audioTrack = audioTracks().anonymousIndexedGetter(0);
+        // 4.3.1 Set the sourceBuffer attribute on the AudioTrack object to null.
+        SourceBufferTrackBaseSupplement::setSourceBuffer(*audioTrack, nullptr);
+        // 4.3.2 If the enabled attribute on the AudioTrack object is true, then set the removed enabled audio track flag to true.
+        if (audioTrack->enabled())
+            removedEnabledAudioTrack = true;
+        // 4.3.3 Remove the AudioTrack object from the HTMLMediaElement audioTracks list.
+        // 4.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement audioTracks list.
+        mediaElement->audioTracks().remove(audioTrack->trackId());
+        // 4.3.5 Remove the AudioTrack object from the SourceBuffer audioTracks list.
+        // 4.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not cancelable, and that uses the TrackEvent interface, at the SourceBuffer audioTracks list.
+        audioTracks().remove(audioTrack->trackId());
+    }
+    // 4.4 If the removed enabled audio track flag equals true, then queue a task to fire a simple event named change at the HTMLMediaElement audioTracks list.
+    if (removedEnabledAudioTrack) {
+        Event* event = Event::create(EventTypeNames::change);
+        event->setTarget(&mediaElement->audioTracks());
+        mediaElement->scheduleEvent(event);
+    }
+
+    // 5. Let SourceBuffer videoTracks list equal the VideoTrackList object returned by sourceBuffer.videoTracks.
+    // 6. If the SourceBuffer videoTracks list is not empty, then run the following steps:
+    // 6.1 Let HTMLMediaElement videoTracks list equal the VideoTrackList object returned by the videoTracks attribute on the HTMLMediaElement.
+    // 6.2 Let the removed selected video track flag equal false.
+    bool removedSelectedVideoTrack = false;
+    // 6.3 For each VideoTrack object in the SourceBuffer videoTracks list, run the following steps:
+    while (videoTracks().length() > 0) {
+        VideoTrack* videoTrack = videoTracks().anonymousIndexedGetter(0);
+        // 6.3.1 Set the sourceBuffer attribute on the VideoTrack object to null.
+        SourceBufferTrackBaseSupplement::setSourceBuffer(*videoTrack, nullptr);
+        // 6.3.2 If the selected attribute on the VideoTrack object is true, then set the removed selected video track flag to true.
+        if (videoTrack->selected())
+            removedSelectedVideoTrack = true;
+        // 6.3.3 Remove the VideoTrack object from the HTMLMediaElement videoTracks list.
+        // 6.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement videoTracks list.
+        mediaElement->videoTracks().remove(videoTrack->trackId());
+        // 6.3.5 Remove the VideoTrack object from the SourceBuffer videoTracks list.
+        // 6.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not cancelable, and that uses the TrackEvent interface, at the SourceBuffer videoTracks list.
+        videoTracks().remove(videoTrack->trackId());
+    }
+    // 6.4 If the removed selected video track flag equals true, then queue a task to fire a simple event named change at the HTMLMediaElement videoTracks list.
+    if (removedSelectedVideoTrack) {
+        Event* event = Event::create(EventTypeNames::change);
+        event->setTarget(&mediaElement->videoTracks());
+        mediaElement->scheduleEvent(event);
+    }
+
+    // 7-8. TODO(servolk): Remove text tracks once SourceBuffer has text tracks.
+}
+
 template<class T>
 T* findExistingTrackById(const TrackListBase<T>& trackList, const String& id)
 {
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h
index 07404b03..5add19d 100644
--- a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h
+++ b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.h
@@ -134,6 +134,8 @@
     void appendStreamDone(bool success);
     void clearAppendStreamState();
 
+    void removeMediaTracks();
+
     // FileReaderLoaderClient interface
     void didStartLoading() override;
     void didReceiveDataForClient(const char* data, unsigned dataLength) override;
diff --git a/third_party/WebKit/Source/platform/DragImageTest.cpp b/third_party/WebKit/Source/platform/DragImageTest.cpp
index b4db5aa1..d71bf51 100644
--- a/third_party/WebKit/Source/platform/DragImageTest.cpp
+++ b/third_party/WebKit/Source/platform/DragImageTest.cpp
@@ -37,6 +37,7 @@
 #include "platform/graphics/Image.h"
 #include "platform/weborigin/KURL.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkPixelRef.h"
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index 96c9695..403d782 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -21,6 +21,9 @@
 // feature can be enabled at runtime on a per-page basis through a signed token for the corresponding feature name.
 // Declaring the origin_trial_feature_name will cause a static method to be generated in OriginTrials.h/cpp. This static
 // method allows the feature implementation to check if it is enabled for the current context.
+//
+// settable_from_internals specifies whether a feature can be set from internals.runtimeFlags, with the default
+// being false.
 
 AppBanner status=stable
 AlwaysUseComplexText status=stable
@@ -52,6 +55,7 @@
 CSSIndependentTransformProperties status=experimental
 CSSMaskSourceType status=experimental
 CSSOMSmoothScroll status=experimental
+CSSPreloadImport status=experimental
 CSSPaintAPI status=test, depends_on=Worklet
 CSSPropertyD status=stable
 CSSSnapSize status=experimental
@@ -174,7 +178,7 @@
 ScreenOrientation status=stable
 ScriptedSpeech status=stable
 // Scrolls to compensate for layout movements (bit.ly/scroll-anchoring).
-ScrollAnchoring
+ScrollAnchoring settable_from_internals=True
 // Implements documentElement.scrollTop/Left and bodyElement.scrollTop/Left
 // as per the spec, matching other Web engines.
 ScrollTopLeftInterop status=experimental
diff --git a/third_party/WebKit/Source/platform/exported/WebFont.cpp b/third_party/WebKit/Source/platform/exported/WebFont.cpp
index 2c8c9b18..f2306489 100644
--- a/third_party/WebKit/Source/platform/exported/WebFont.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebFont.cpp
@@ -8,7 +8,6 @@
 #include "platform/fonts/FontCache.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/paint/DisplayItemClient.h"
 #include "platform/graphics/paint/DrawingRecorder.h"
 #include "platform/graphics/paint/SkPictureBuilder.h"
 #include "platform/text/TextRun.h"
@@ -25,7 +24,7 @@
     return new WebFont(description);
 }
 
-class WebFont::Impl final : public DisplayItemClient {
+class WebFont::Impl final {
 public:
     explicit Impl(const WebFontDescription& description)
         : m_font(description)
@@ -34,12 +33,6 @@
     }
 
     const Font& getFont() const { return m_font; }
-    String debugName() const final { return "WebFont::Impl"; }
-    LayoutRect visualRect() const final
-    {
-        // TODO(chrishtr): fix this.
-        return LayoutRect();
-    }
 
 private:
     Font m_font;
@@ -98,9 +91,8 @@
     SkPictureBuilder pictureBuilder(intRect);
     GraphicsContext& context = pictureBuilder.context();
 
-    ASSERT(!DrawingRecorder::useCachedDrawingIfPossible(context, *m_private, DisplayItem::WebFont));
     {
-        DrawingRecorder drawingRecorder(context, *m_private, DisplayItem::WebFont, intRect);
+        DrawingRecorder drawingRecorder(context, pictureBuilder, DisplayItem::WebFont, intRect);
         context.save();
         context.setFillColor(color);
         context.clip(textClipRect);
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
index 476057b..40352ea8 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
@@ -310,9 +310,6 @@
         // whether the buffer direction is horizontal or vertical.
         float advance = harfBuzzPositionToFloat(pos.x_advance - pos.y_advance);
 
-        // The characterIndex of one ShapeResult run is normalized to the run's
-        // startIndex and length.  TODO crbug.com/542703: Consider changing that
-        // and instead pass the whole run to hb_buffer_t each time.
         run->m_glyphData[i].characterIndex =
             glyphInfos[startGlyph + i].cluster - startCluster;
 
diff --git a/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp b/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp
index 5d474693..780d567 100644
--- a/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp
+++ b/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp
@@ -192,14 +192,11 @@
         return adoptRef(m_fontManager->matchFamilyStyle(name.data(), fontDescription.skiaFontStyle()));
 #endif
 
-    // FIXME: Use m_fontManager, SkFontStyle and matchFamilyStyle instead of
-    // CreateFromName on all platforms.
-    int style = SkTypeface::kNormal;
-    if (fontDescription.weight() >= FontWeight600)
-        style |= SkTypeface::kBold;
-    if (fontDescription.style())
-        style |= SkTypeface::kItalic;
-    return adoptRef(SkTypeface::CreateFromName(name.data(), static_cast<SkTypeface::Style>(style)));
+    // FIXME: Use m_fontManager, matchFamilyStyle instead of
+    // legacyCreateTypeface on all platforms.
+    RefPtr<SkFontMgr> fm = adoptRef(SkFontMgr::RefDefault());
+    return adoptRef(fm->legacyCreateTypeface(name.data(),
+        fontDescription.skiaFontStyle()));
 }
 
 #if !OS(WIN)
@@ -214,7 +211,7 @@
     return adoptPtr(new FontPlatformData(tf,
         name.data(),
         fontSize,
-        (fontDescription.weight() >= FontWeight600 && !tf->isBold()) || fontDescription.isSyntheticBold(),
+        (fontDescription.weight() > 200 + tf->fontStyle().weight()) || fontDescription.isSyntheticBold(),
         ((fontDescription.style() == FontStyleItalic || fontDescription.style() == FontStyleOblique) && !tf->isItalic()) || fontDescription.isSyntheticItalic(),
         fontDescription.orientation()));
 }
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
index ec8e2d948..5f86d32 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp
@@ -37,6 +37,7 @@
 #include "platform/testing/HistogramTester.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkImage.h"
 #include "wtf/StdLibExtras.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
index 0dd0ade..0654fde 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.h
@@ -34,7 +34,7 @@
 #include "public/platform/WebExternalTextureMailbox.h"
 #include "public/platform/WebThread.h"
 #include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkSurface.h"
 #include "wtf/Allocator.h"
 #include "wtf/Deque.h"
 #include "wtf/PassOwnPtr.h"
@@ -43,6 +43,8 @@
 #include "wtf/Vector.h"
 #include "wtf/WeakPtr.h"
 
+class SkImage;
+struct SkImageInfo;
 class SkPictureRecorder;
 
 namespace gpu {
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
index d6084c91..f27bb669 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
@@ -29,8 +29,6 @@
 #include "platform/PlatformExport.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/image-decoders/ImageDecoder.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
 #include "third_party/skia/include/core/SkRWBuffer.h"
 #include "wtf/Allocator.h"
 #include "wtf/Forward.h"
diff --git a/third_party/WebKit/Source/platform/graphics/FrameData.cpp b/third_party/WebKit/Source/platform/graphics/FrameData.cpp
index b510aa9..8f3f36b 100644
--- a/third_party/WebKit/Source/platform/graphics/FrameData.cpp
+++ b/third_party/WebKit/Source/platform/graphics/FrameData.cpp
@@ -25,6 +25,7 @@
  */
 
 #include "platform/graphics/FrameData.h"
+#include "third_party/skia/include/core/SkImage.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/graphics/FrameData.h b/third_party/WebKit/Source/platform/graphics/FrameData.h
index e64c931..8b785b8d 100644
--- a/third_party/WebKit/Source/platform/graphics/FrameData.h
+++ b/third_party/WebKit/Source/platform/graphics/FrameData.h
@@ -29,12 +29,13 @@
 #define FrameData_h
 
 #include "platform/graphics/ImageOrientation.h"
-#include "third_party/skia/include/core/SkImage.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/RefPtr.h"
 #include "wtf/VectorTraits.h"
 
+class SkImage;
+
 namespace blink {
 
 struct FrameData {
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index 1e71246..27e66fc 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -49,7 +49,7 @@
 #include "public/platform/WebContentLayer.h"
 #include "public/platform/WebImageLayer.h"
 #include "public/platform/WebLayerScrollClient.h"
-#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkFilterQuality.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/Vector.h"
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h b/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h
index 610906b..22c27ac 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsTypes.h
@@ -28,6 +28,7 @@
 
 #include "platform/PlatformExport.h"
 #include "public/platform/WebBlendMode.h"
+#include "third_party/skia/include/core/SkFilterQuality.h"
 #include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkPath.h"
 #include "wtf/Forward.h"
diff --git a/third_party/WebKit/Source/platform/graphics/Image.h b/third_party/WebKit/Source/platform/graphics/Image.h
index 412b355d..9bbd0109 100644
--- a/third_party/WebKit/Source/platform/graphics/Image.h
+++ b/third_party/WebKit/Source/platform/graphics/Image.h
@@ -34,7 +34,6 @@
 #include "platform/graphics/ImageAnimationPolicy.h"
 #include "platform/graphics/ImageObserver.h"
 #include "platform/graphics/ImageOrientation.h"
-#include "third_party/skia/include/core/SkCanvas.h"
 #include "wtf/Assertions.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/PassRefPtr.h"
@@ -43,6 +42,7 @@
 #include "wtf/text/WTFString.h"
 
 class SkBitmap;
+class SkCanvas;
 class SkImage;
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
index cd29a64..3efd86e2 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
@@ -29,6 +29,7 @@
 #include "platform/TraceEvent.h"
 #include "platform/graphics/ImageDecodingStore.h"
 #include "platform/image-decoders/ImageDecoder.h"
+#include "third_party/skia/include/core/SkYUVSizeInfo.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
index 4b31634..b8053b9 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
@@ -31,7 +31,6 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkSize.h"
 #include "third_party/skia/include/core/SkTypes.h"
-#include "third_party/skia/include/core/SkYUVSizeInfo.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/PassOwnPtr.h"
@@ -43,6 +42,7 @@
 #include "wtf/Vector.h"
 
 class SkData;
+struct SkYUVSizeInfo;
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/platform/graphics/PaintGeneratedImage.h b/third_party/WebKit/Source/platform/graphics/PaintGeneratedImage.h
index 1b7b780..d78262ba 100644
--- a/third_party/WebKit/Source/platform/graphics/PaintGeneratedImage.h
+++ b/third_party/WebKit/Source/platform/graphics/PaintGeneratedImage.h
@@ -9,6 +9,8 @@
 #include "platform/graphics/GeneratedImage.h"
 #include "wtf/OwnPtr.h"
 
+class SkPicture;
+
 namespace blink {
 
 class PLATFORM_EXPORT PaintGeneratedImage : public GeneratedImage {
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h
index 7f87b6b..011073e 100644
--- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.h
@@ -8,12 +8,12 @@
 #include "platform/graphics/GraphicsContext.h"
 #include "platform/graphics/ImageBufferSurface.h"
 #include "public/platform/WebThread.h"
-#include "third_party/skia/include/core/SkCanvas.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/RefPtr.h"
 
+class SkCanvas;
 class SkPicture;
 class SkPictureRecorder;
 
diff --git a/third_party/WebKit/Source/platform/graphics/ReplayingCanvas.h b/third_party/WebKit/Source/platform/graphics/ReplayingCanvas.h
index 45aa5bd1..09e1c6e 100644
--- a/third_party/WebKit/Source/platform/graphics/ReplayingCanvas.h
+++ b/third_party/WebKit/Source/platform/graphics/ReplayingCanvas.h
@@ -32,6 +32,7 @@
 #define ReplayingCanvas_h
 
 #include "platform/graphics/InterceptingCanvas.h"
+#include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkPicture.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/graphics/StrokeData.cpp b/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
index e566daf0..d7b3b56 100644
--- a/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
+++ b/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
@@ -27,6 +27,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "platform/graphics/StrokeData.h"
+#include "third_party/skia/include/effects/SkDashPathEffect.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 
diff --git a/third_party/WebKit/Source/platform/graphics/StrokeData.h b/third_party/WebKit/Source/platform/graphics/StrokeData.h
index bb5335f..cded26af 100644
--- a/third_party/WebKit/Source/platform/graphics/StrokeData.h
+++ b/third_party/WebKit/Source/platform/graphics/StrokeData.h
@@ -34,8 +34,8 @@
 #include "platform/graphics/Gradient.h"
 #include "platform/graphics/GraphicsTypes.h"
 #include "platform/graphics/Pattern.h"
-#include "third_party/skia/include/core/SkColorPriv.h"
-#include "third_party/skia/include/effects/SkDashPathEffect.h"
+#include "third_party/skia/include/core/SkPaint.h"
+#include "third_party/skia/include/core/SkPathEffect.h"
 #include "wtf/Allocator.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h b/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h
index 378be340..8815e8ed 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h
@@ -128,6 +128,8 @@
 
     class PLATFORM_EXPORT ImageExtractor final {
         STACK_ALLOCATED();
+        WTF_MAKE_NONCOPYABLE(ImageExtractor);
+
     public:
         ImageExtractor(Image*, ImageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile);
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h b/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h
index 63e7b5f..f2652e7a 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h
@@ -7,6 +7,7 @@
 
 #include "platform/PlatformExport.h"
 #include "platform/geometry/FloatRect.h"
+#include "platform/graphics/paint/DisplayItemClient.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassRefPtr.h"
@@ -21,7 +22,7 @@
 
 // When slimming paint ships we can remove this SkPicture abstraction and
 // rely on PaintController here.
-class PLATFORM_EXPORT SkPictureBuilder final {
+class PLATFORM_EXPORT SkPictureBuilder final : public DisplayItemClient {
     WTF_MAKE_NONCOPYABLE(SkPictureBuilder);
 public:
     // Constructs a new builder with the given bounds for the resulting recorded picture. If
@@ -37,6 +38,10 @@
     // construction.
     PassRefPtr<SkPicture> endRecording();
 
+    // DisplayItemClient methods
+    String debugName() const final { return "SkPictureBuilder"; }
+    LayoutRect visualRect() const final { return LayoutRect(); }
+
 private:
     OwnPtr<PaintController> m_paintController;
     OwnPtr<GraphicsContext> m_context;
diff --git a/third_party/WebKit/Source/platform/graphics/skia/ImagePixelLocker.h b/third_party/WebKit/Source/platform/graphics/skia/ImagePixelLocker.h
index 2aadcef..e3b8bc319 100644
--- a/third_party/WebKit/Source/platform/graphics/skia/ImagePixelLocker.h
+++ b/third_party/WebKit/Source/platform/graphics/skia/ImagePixelLocker.h
@@ -7,7 +7,6 @@
 
 #include "platform/heap/Heap.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
-#include "third_party/skia/include/core/SkPixmap.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/PassRefPtr.h"
diff --git a/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h b/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h
index e1c5886..e4282bb 100644
--- a/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h
+++ b/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h
@@ -38,7 +38,10 @@
 #include "platform/graphics/Image.h"
 #include "platform/transforms/AffineTransform.h"
 #include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
+#include "third_party/skia/include/core/SkScalar.h"
+#include "third_party/skia/include/core/SkXfermode.h"
 #include "wtf/MathExtras.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h
index 6fa99ff..88683855b 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoderTestHelpers.h
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "third_party/skia/include/core/SkBitmap.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/Vector.h"
 
+class SkBitmap;
+
 namespace blink {
 class ImageDecoder;
 class SharedBuffer;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp
index 51a682dd..be0f20b7 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp
@@ -623,7 +623,7 @@
     ASSERT(num < V8InspectorSessionImpl::kInspectedObjectBufferSize);
     ConsoleHelper helper(info);
     if (V8InspectorSessionImpl* session = helper.currentSession()) {
-        V8RuntimeAgent::Inspectable* object = session->inspectedObject(num);
+        V8InspectorSession::Inspectable* object = session->inspectedObject(num);
         v8::Isolate* isolate = info.GetIsolate();
         if (object)
             info.GetReturnValue().Set(object->get(isolate->GetCurrentContext()));
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
index 0cc989f..44a74433 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
@@ -104,7 +104,7 @@
     return value.As<v8::Object>();
 }
 
-class InspectableHeapObject final : public V8RuntimeAgent::Inspectable {
+class InspectableHeapObject final : public V8InspectorSession::Inspectable {
 public:
     explicit InspectableHeapObject(int heapObjectId) : m_heapObjectId(heapObjectId) { }
     v8::Local<v8::Value> get(v8::Local<v8::Context> context) override
@@ -266,7 +266,7 @@
         return;
     }
 
-    *result = m_session->runtimeAgent()->wrapObject(heapObject->CreationContext(), heapObject, objectGroup.fromMaybe(""));
+    *result = m_session->wrapObject(heapObject->CreationContext(), heapObject, objectGroup.fromMaybe(""));
     if (!result)
         *error = "Object is not available";
 }
@@ -292,13 +292,13 @@
         return;
     }
 
-    m_session->runtimeAgent()->addInspectedObject(adoptPtr(new InspectableHeapObject(id)));
+    m_session->addInspectedObject(adoptPtr(new InspectableHeapObject(id)));
 }
 
 void V8HeapProfilerAgentImpl::getHeapObjectId(ErrorString* errorString, const String16& objectId, String16* heapSnapshotObjectId)
 {
     v8::HandleScope handles(m_isolate);
-    v8::Local<v8::Value> value = m_session->runtimeAgent()->findObject(errorString, objectId);
+    v8::Local<v8::Value> value = m_session->findObject(errorString, objectId);
     if (value.IsEmpty() || value->IsUndefined())
         return;
 
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp
index c07fa1f..80e40356 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp
@@ -142,6 +142,43 @@
     }
 }
 
+v8::Local<v8::Value> V8InspectorSessionImpl::findObject(ErrorString* errorString, const String16& objectId, v8::Local<v8::Context>* context, String16* groupName)
+{
+    OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(errorString, objectId);
+    if (!remoteId)
+        return v8::Local<v8::Value>();
+    InjectedScript* injectedScript = findInjectedScript(errorString, remoteId.get());
+    if (!injectedScript)
+        return v8::Local<v8::Value>();
+    v8::Local<v8::Value> objectValue;
+    injectedScript->findObject(errorString, *remoteId, &objectValue);
+    if (objectValue.IsEmpty())
+        return v8::Local<v8::Value>();
+    if (context)
+        *context = injectedScript->context()->context();
+    if (groupName)
+        *groupName = injectedScript->objectGroupName(*remoteId);
+    return objectValue;
+}
+
+PassOwnPtr<protocol::Runtime::RemoteObject> V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context, v8::Local<v8::Value> value, const String16& groupName, bool generatePreview)
+{
+    ErrorString errorString;
+    InjectedScript* injectedScript = findInjectedScript(&errorString, V8Debugger::contextId(context));
+    if (!injectedScript)
+        return nullptr;
+    return injectedScript->wrapObject(&errorString, value, groupName, false, generatePreview);
+}
+
+PassOwnPtr<protocol::Runtime::RemoteObject> V8InspectorSessionImpl::wrapTable(v8::Local<v8::Context> context, v8::Local<v8::Value> table, v8::Local<v8::Value> columns)
+{
+    ErrorString errorString;
+    InjectedScript* injectedScript = findInjectedScript(&errorString, V8Debugger::contextId(context));
+    if (!injectedScript)
+        return nullptr;
+    return injectedScript->wrapTable(table, columns);
+}
+
 void V8InspectorSessionImpl::setCustomObjectFormatterEnabled(bool enabled)
 {
     m_customObjectFormatterEnabled = enabled;
@@ -174,14 +211,14 @@
         m_client->stopInstrumenting();
 }
 
-void V8InspectorSessionImpl::addInspectedObject(PassOwnPtr<V8RuntimeAgent::Inspectable> inspectable)
+void V8InspectorSessionImpl::addInspectedObject(PassOwnPtr<V8InspectorSession::Inspectable> inspectable)
 {
     m_inspectedObjects.prepend(std::move(inspectable));
     while (m_inspectedObjects.size() > kInspectedObjectBufferSize)
         m_inspectedObjects.removeLast();
 }
 
-V8RuntimeAgent::Inspectable* V8InspectorSessionImpl::inspectedObject(unsigned num)
+V8InspectorSession::Inspectable* V8InspectorSessionImpl::inspectedObject(unsigned num)
 {
     if (num >= m_inspectedObjects.size())
         return nullptr;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h
index cbe74c6a..c8cc8237 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h
@@ -44,12 +44,12 @@
     void reset();
     void discardInjectedScripts();
     void reportAllContexts(V8RuntimeAgentImpl*);
-    void releaseObjectGroup(const String16& objectGroup);
     void setCustomObjectFormatterEnabled(bool);
     void changeInstrumentationCounter(int delta);
 
     // V8InspectorSession implementation.
     void setClient(V8InspectorSessionClient*) override;
+    void addInspectedObject(PassOwnPtr<V8InspectorSession::Inspectable>) override;
     V8DebuggerAgent* debuggerAgent() override;
     V8HeapProfilerAgent* heapProfilerAgent() override;
     V8ProfilerAgent* profilerAgent() override;
@@ -64,9 +64,12 @@
     void asyncTaskStarted(void* task) override;
     void asyncTaskFinished(void* task) override;
     void allAsyncTasksCanceled() override;
+    void releaseObjectGroup(const String16& objectGroup) override;
+    v8::Local<v8::Value> findObject(ErrorString*, const String16& objectId, v8::Local<v8::Context>* = nullptr, String16* groupName = nullptr) override;
+    PassOwnPtr<protocol::Runtime::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName, bool generatePreview = false) override;
+    PassOwnPtr<protocol::Runtime::RemoteObject> wrapTable(v8::Local<v8::Context>, v8::Local<v8::Value> table, v8::Local<v8::Value> columns) override;
 
-    void addInspectedObject(PassOwnPtr<V8RuntimeAgent::Inspectable>);
-    V8RuntimeAgent::Inspectable* inspectedObject(unsigned num);
+    V8InspectorSession::Inspectable* inspectedObject(unsigned num);
     static const unsigned kInspectedObjectBufferSize = 5;
 
 private:
@@ -82,7 +85,7 @@
     OwnPtr<V8DebuggerAgentImpl> m_debuggerAgent;
     OwnPtr<V8HeapProfilerAgentImpl> m_heapProfilerAgent;
     OwnPtr<V8ProfilerAgentImpl> m_profilerAgent;
-    protocol::Vector<OwnPtr<V8RuntimeAgent::Inspectable>> m_inspectedObjects;
+    protocol::Vector<OwnPtr<V8InspectorSession::Inspectable>> m_inspectedObjects;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
index 34b6ea6..6822775 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
@@ -383,53 +383,6 @@
     m_session->changeInstrumentationCounter(-1);
 }
 
-PassOwnPtr<RemoteObject> V8RuntimeAgentImpl::wrapObject(v8::Local<v8::Context> context, v8::Local<v8::Value> value, const String16& groupName, bool generatePreview)
-{
-    ErrorString errorString;
-    InjectedScript* injectedScript = m_session->findInjectedScript(&errorString, V8Debugger::contextId(context));
-    if (!injectedScript)
-        return nullptr;
-    return injectedScript->wrapObject(&errorString, value, groupName, false, generatePreview);
-}
-
-PassOwnPtr<RemoteObject> V8RuntimeAgentImpl::wrapTable(v8::Local<v8::Context> context, v8::Local<v8::Value> table, v8::Local<v8::Value> columns)
-{
-    ErrorString errorString;
-    InjectedScript* injectedScript = m_session->findInjectedScript(&errorString, V8Debugger::contextId(context));
-    if (!injectedScript)
-        return nullptr;
-    return injectedScript->wrapTable(table, columns);
-}
-
-void V8RuntimeAgentImpl::disposeObjectGroup(const String16& groupName)
-{
-    m_session->releaseObjectGroup(groupName);
-}
-
-v8::Local<v8::Value> V8RuntimeAgentImpl::findObject(ErrorString* errorString, const String16& objectId, v8::Local<v8::Context>* context, String16* groupName)
-{
-    OwnPtr<RemoteObjectId> remoteId = RemoteObjectId::parse(errorString, objectId);
-    if (!remoteId)
-        return v8::Local<v8::Value>();
-    InjectedScript* injectedScript = m_session->findInjectedScript(errorString, remoteId.get());
-    if (!injectedScript)
-        return v8::Local<v8::Value>();
-    v8::Local<v8::Value> objectValue;
-    injectedScript->findObject(errorString, *remoteId, &objectValue);
-    if (objectValue.IsEmpty())
-        return v8::Local<v8::Value>();
-    if (context)
-        *context = injectedScript->context()->context();
-    if (groupName)
-        *groupName = injectedScript->objectGroupName(*remoteId);
-    return objectValue;
-}
-
-void V8RuntimeAgentImpl::addInspectedObject(PassOwnPtr<Inspectable> inspectable)
-{
-    m_session->addInspectedObject(std::move(inspectable));
-}
-
 void V8RuntimeAgentImpl::reset()
 {
     m_compiledScripts.clear();
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h
index 4035fd0..caad78d 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h
@@ -119,12 +119,6 @@
     void reportExecutionContextDestroyed(InspectedContext*);
     void inspect(PassOwnPtr<protocol::Runtime::RemoteObject> objectToInspect, PassOwnPtr<protocol::DictionaryValue> hints);
 
-    PassOwnPtr<protocol::Runtime::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName, bool generatePreview = false) override;
-    PassOwnPtr<protocol::Runtime::RemoteObject> wrapTable(v8::Local<v8::Context>, v8::Local<v8::Value> table, v8::Local<v8::Value> columns) override;
-    void disposeObjectGroup(const String16&) override;
-    v8::Local<v8::Value> findObject(ErrorString*, const String16& objectId, v8::Local<v8::Context>* = nullptr, String16* groupName = nullptr) override;
-    void addInspectedObject(PassOwnPtr<Inspectable>) override;
-
 private:
     V8InspectorSessionImpl* m_session;
     protocol::DictionaryValue* m_state;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h
index c3fb2df5..fc8c73ca 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h
@@ -6,8 +6,11 @@
 #define V8InspectorSession_h
 
 #include "platform/PlatformExport.h"
+#include "platform/inspector_protocol/TypeBuilder.h"
 #include "wtf/PassOwnPtr.h"
 
+#include <v8.h>
+
 namespace blink {
 
 class V8DebuggerAgent;
@@ -19,9 +22,18 @@
 class PLATFORM_EXPORT V8InspectorSession {
 public:
     static const char backtraceObjectGroup[];
+
+    // Cross-context inspectable values (DOM nodes in different worlds, etc.).
+    class Inspectable {
+    public:
+        virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0;
+        virtual ~Inspectable() { }
+    };
+
     virtual ~V8InspectorSession() { }
 
     virtual void setClient(V8InspectorSessionClient*) = 0;
+    virtual void addInspectedObject(PassOwnPtr<Inspectable>) = 0;
 
     // API for the embedder to report native activities.
     virtual void schedulePauseOnNextStatement(const String16& breakReason, PassOwnPtr<protocol::DictionaryValue> data) = 0;
@@ -30,13 +42,20 @@
     virtual void breakProgramOnException(const String16& breakReason, PassOwnPtr<protocol::DictionaryValue> data) = 0;
     virtual void setSkipAllPauses(bool) = 0;
 
-    // Async call stacks implementation.
+    // API to report async call stacks.
     virtual void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) = 0;
     virtual void asyncTaskCanceled(void* task) = 0;
     virtual void asyncTaskStarted(void* task) = 0;
     virtual void asyncTaskFinished(void* task) = 0;
     virtual void allAsyncTasksCanceled() = 0;
 
+    // API to work with remote objects.
+    virtual PassOwnPtr<protocol::Runtime::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName, bool generatePreview = false) = 0;
+    // FIXME: remove when InspectorConsoleAgent moves into V8 inspector.
+    virtual PassOwnPtr<protocol::Runtime::RemoteObject> wrapTable(v8::Local<v8::Context>, v8::Local<v8::Value> table, v8::Local<v8::Value> columns) = 0;
+    virtual v8::Local<v8::Value> findObject(ErrorString*, const String16& objectId, v8::Local<v8::Context>* = nullptr, String16* objectGroup = nullptr) = 0;
+    virtual void releaseObjectGroup(const String16&) = 0;
+
     virtual V8DebuggerAgent* debuggerAgent() = 0;
     virtual V8HeapProfilerAgent* heapProfilerAgent() = 0;
     virtual V8ProfilerAgent* profilerAgent() = 0;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8RuntimeAgent.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8RuntimeAgent.h
index 042a4e7..917114f4 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/public/V8RuntimeAgent.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8RuntimeAgent.h
@@ -7,33 +7,15 @@
 
 #include "platform/PlatformExport.h"
 #include "platform/inspector_protocol/Dispatcher.h"
-#include "platform/v8_inspector/public/V8ContextInfo.h"
 #include "platform/v8_inspector/public/V8Debugger.h"
 
-#include <v8.h>
-
 namespace blink {
 
 class InjectedScriptManager;
 
 class PLATFORM_EXPORT V8RuntimeAgent : public protocol::Backend::Runtime, public V8Debugger::Agent<protocol::Frontend::Runtime> {
 public:
-    // Cross-context inspectable values (DOM nodes in different worlds, etc.).
-    class Inspectable {
-    public:
-        virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0;
-        virtual ~Inspectable() { }
-    };
-
     virtual ~V8RuntimeAgent() { }
-
-    // Embedder API.
-    virtual PassOwnPtr<protocol::Runtime::RemoteObject> wrapObject(v8::Local<v8::Context>, v8::Local<v8::Value>, const String16& groupName, bool generatePreview = false) = 0;
-    // FIXME: remove when InspectorConsoleAgent moves into V8 inspector.
-    virtual PassOwnPtr<protocol::Runtime::RemoteObject> wrapTable(v8::Local<v8::Context>, v8::Local<v8::Value> table, v8::Local<v8::Value> columns) = 0;
-    virtual v8::Local<v8::Value> findObject(ErrorString*, const String16& objectId, v8::Local<v8::Context>* = nullptr, String16* objectGroup = nullptr) = 0;
-    virtual void disposeObjectGroup(const String16&) = 0;
-    virtual void addInspectedObject(PassOwnPtr<Inspectable>) = 0;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
index 8760f9cd..60767e26 100644
--- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -565,13 +565,8 @@
     DCHECK(widget->isFrameView());
     const FrameView* view = toFrameView(widget);
     LocalFrame* frame = view->frame().localFrameRoot();
-    WebWidgetClient* client = nullptr;
 
-    // TODO(kenrb): Consolidate this to a single case when WebViewFrameWidget refactor is complete.
-    if (WebLocalFrameImpl::fromFrame(frame) && WebLocalFrameImpl::fromFrame(frame)->frameWidget() && WebLocalFrameImpl::fromFrame(frame)->frameWidget()->forSubframe())
-        client = toWebFrameWidgetImpl(WebLocalFrameImpl::fromFrame(frame)->frameWidget())->client();
-    else
-        client = m_webView->client();
+    WebWidgetClient* client = WebLocalFrameImpl::fromFrame(frame)->frameWidget()->client();
 
     if (client) {
         client->convertViewportToWindow(&screenRect);
@@ -579,6 +574,7 @@
         screenRect.x += windowRect.x;
         screenRect.y += windowRect.y;
     }
+
     return screenRect;
 }
 
diff --git a/third_party/WebKit/Source/web/PageOverlayTest.cpp b/third_party/WebKit/Source/web/PageOverlayTest.cpp
index bf2036c4..b592a509 100644
--- a/third_party/WebKit/Source/web/PageOverlayTest.cpp
+++ b/third_party/WebKit/Source/web/PageOverlayTest.cpp
@@ -71,7 +71,7 @@
     void initialize(CompositingMode compositingMode)
     {
         m_helper.initialize(
-            false /* enableJavascript */, nullptr /* webFrameClient */, nullptr /* webViewClient */,
+            false /* enableJavascript */, nullptr /* webFrameClient */, nullptr /* webViewClient */, nullptr /* webWidgetClient */,
             compositingMode == AcceleratedCompositing ? enableAcceleratedCompositing : disableAcceleratedCompositing);
         webViewImpl()->resize(WebSize(viewportWidth, viewportHeight));
         webViewImpl()->updateAllLifecyclePhases();
diff --git a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
index 6c7ff73b..2a3a406 100644
--- a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
+++ b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
@@ -80,16 +80,15 @@
 
         AffineTransform scale;
         scale.scale(scaleFactor);
-        TransformRecorder scaleRecorder(paintContext, root, scale);
+        TransformRecorder scaleRecorder(paintContext, pictureBuilder, scale);
 
         IntRect dirtyRect(rect);
         FrameView* view = root.view();
         if (view) {
-            ClipRecorder clipRecorder(paintContext, root, DisplayItem::PageWidgetDelegateClip, LayoutRect(dirtyRect));
-
+            ClipRecorder clipRecorder(paintContext, pictureBuilder, DisplayItem::PageWidgetDelegateClip, LayoutRect(dirtyRect));
             view->paint(paintContext, globalPaintFlags, CullRect(dirtyRect));
-        } else if (!DrawingRecorder::useCachedDrawingIfPossible(paintContext, root, DisplayItem::PageWidgetDelegateBackgroundFallback)) {
-            DrawingRecorder drawingRecorder(paintContext, root, DisplayItem::PageWidgetDelegateBackgroundFallback, dirtyRect);
+        } else {
+            DrawingRecorder drawingRecorder(paintContext, pictureBuilder, DisplayItem::PageWidgetDelegateBackgroundFallback, dirtyRect);
             paintContext.fillRect(dirtyRect, Color::white);
         }
     }
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
index a3d98ef..8c3aca5 100644
--- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
+++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -303,7 +303,7 @@
 #if DCHECK_IS_ON()
     , m_hasBeenDisposed(false)
 #endif
-    , m_instrumentingSessions(m_webLocalFrameImpl->frame()->instrumentingSessions())
+    , m_instrumentingAgents(m_webLocalFrameImpl->frame()->instrumentingAgents())
     , m_resourceContentLoader(InspectorResourceContentLoader::create(m_webLocalFrameImpl->frame()))
     , m_overlay(overlay)
     , m_inspectedFrames(InspectedFrames::create(m_webLocalFrameImpl->frame()))
@@ -354,7 +354,7 @@
 DEFINE_TRACE(WebDevToolsAgentImpl)
 {
     visitor->trace(m_webLocalFrameImpl);
-    visitor->trace(m_instrumentingSessions);
+    visitor->trace(m_instrumentingAgents);
     visitor->trace(m_resourceContentLoader);
     visitor->trace(m_overlay);
     visitor->trace(m_inspectedFrames);
@@ -377,18 +377,16 @@
 
 void WebDevToolsAgentImpl::initializeSession(int sessionId, const String& hostId)
 {
-    m_session = new InspectorSession(this, m_inspectedFrames.get(), sessionId, false /* autoFlush */);
+    m_session = new InspectorSession(this, m_inspectedFrames.get(), m_instrumentingAgents.get(), sessionId, false /* autoFlush */);
 
     ClientMessageLoopAdapter::ensureMainThreadDebuggerCreated(m_client);
     MainThreadDebugger* mainThreadDebugger = MainThreadDebugger::instance();
     v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
-
     m_v8Session = mainThreadDebugger->debugger()->connect(mainThreadDebugger->contextGroupId(m_inspectedFrames->root()));
-    V8RuntimeAgent* runtimeAgent = m_v8Session->runtimeAgent();
 
-    m_session->append(PageRuntimeAgent::create(this, runtimeAgent, m_inspectedFrames.get()));
+    m_session->append(PageRuntimeAgent::create(this, m_v8Session->runtimeAgent(), m_inspectedFrames.get()));
 
-    InspectorDOMAgent* domAgent = InspectorDOMAgent::create(isolate, m_inspectedFrames.get(), runtimeAgent, m_overlay.get());
+    InspectorDOMAgent* domAgent = new InspectorDOMAgent(isolate, m_inspectedFrames.get(), m_v8Session.get(), m_overlay.get());
     m_domAgent = domAgent;
     m_session->append(domAgent);
 
@@ -403,7 +401,7 @@
     InspectorCSSAgent* cssAgent = InspectorCSSAgent::create(m_domAgent, m_inspectedFrames.get(), m_resourceAgent, m_resourceContentLoader.get(), m_resourceContainer.get());
     m_session->append(cssAgent);
 
-    m_session->append(InspectorAnimationAgent::create(m_inspectedFrames.get(), m_domAgent, cssAgent, runtimeAgent));
+    m_session->append(new InspectorAnimationAgent(m_inspectedFrames.get(), m_domAgent, cssAgent, m_v8Session.get()));
 
     m_session->append(InspectorMemoryAgent::create());
 
@@ -414,7 +412,7 @@
     InspectorDebuggerAgent* debuggerAgent = PageDebuggerAgent::create(m_v8Session->debuggerAgent(), m_inspectedFrames.get());
     m_session->append(debuggerAgent);
 
-    PageConsoleAgent* pageConsoleAgent = PageConsoleAgent::create(runtimeAgent, m_domAgent, m_inspectedFrames.get());
+    PageConsoleAgent* pageConsoleAgent = new PageConsoleAgent(m_v8Session.get(), m_domAgent, m_inspectedFrames.get());
     m_session->append(pageConsoleAgent);
 
     InspectorWorkerAgent* workerAgent = InspectorWorkerAgent::create(m_inspectedFrames.get(), pageConsoleAgent);
@@ -424,7 +422,7 @@
     m_tracingAgent = tracingAgent;
     m_session->append(tracingAgent);
 
-    m_session->append(new InspectorDOMDebuggerAgent(isolate, m_domAgent, runtimeAgent, m_v8Session.get()));
+    m_session->append(new InspectorDOMDebuggerAgent(isolate, m_domAgent, m_v8Session.get()));
 
     m_session->append(InspectorInputAgent::create(m_inspectedFrames.get()));
 
@@ -458,8 +456,7 @@
         m_overlay->init(cssAgent, debuggerAgent, m_domAgent);
 
     Platform::current()->currentThread()->addTaskObserver(this);
-    InspectorInstrumentation::registerInstrumentingSessions(m_instrumentingSessions.get());
-    m_instrumentingSessions->add(m_session);
+    InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
 }
 
 void WebDevToolsAgentImpl::destroySession()
@@ -474,12 +471,11 @@
     m_domAgent.clear();
 
     m_session->detach();
-    m_instrumentingSessions->remove(m_session);
     m_v8Session.clear();
     m_session.clear();
 
     Platform::current()->currentThread()->removeTaskObserver(this);
-    InspectorInstrumentation::unregisterInstrumentingSessions(m_instrumentingSessions.get());
+    InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
 }
 
 void WebDevToolsAgentImpl::attach(const WebString& hostId, int sessionId)
@@ -558,11 +554,11 @@
     m_client->setCPUThrottlingRate(rate);
 }
 
-void WebDevToolsAgentImpl::dispatchOnInspectorBackend(int sessionId, const WebString& message)
+void WebDevToolsAgentImpl::dispatchOnInspectorBackend(int sessionId, int callId, const WebString& method, const WebString& message)
 {
     if (!attached())
         return;
-    if (WebDevToolsAgent::shouldInterruptForMessage(message))
+    if (WebDevToolsAgent::shouldInterruptForMethod(method))
         MainThreadDebugger::instance()->taskRunner()->runAllTasksDontWait();
     else
         dispatchMessageFromFrontend(sessionId, message);
@@ -681,16 +677,13 @@
     MainThreadDebugger::interruptMainThreadAndRun(threadSafeBind(WebDevToolsAgentImpl::runDebuggerTask, sessionId, passed(adoptPtr(rawDescriptor))));
 }
 
-bool WebDevToolsAgent::shouldInterruptForMessage(const WebString& message)
+bool WebDevToolsAgent::shouldInterruptForMethod(const WebString& method)
 {
-    String16 commandName;
-    if (!protocol::Dispatcher::getCommandName(message, &commandName))
-        return false;
-    return commandName == "Debugger.pause"
-        || commandName == "Debugger.setBreakpoint"
-        || commandName == "Debugger.setBreakpointByUrl"
-        || commandName == "Debugger.removeBreakpoint"
-        || commandName == "Debugger.setBreakpointsActive";
+    return method == "Debugger.pause"
+        || method == "Debugger.setBreakpoint"
+        || method == "Debugger.setBreakpointByUrl"
+        || method == "Debugger.removeBreakpoint"
+        || method == "Debugger.setBreakpointsActive";
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
index f5fe808..b4c6f35 100644
--- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
+++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.h
@@ -35,7 +35,6 @@
 #include "core/inspector/InspectorRuntimeAgent.h"
 #include "core/inspector/InspectorSession.h"
 #include "core/inspector/InspectorTracingAgent.h"
-#include "core/inspector/InstrumentingSessions.h"
 #include "platform/heap/Handle.h"
 #include "public/platform/WebSize.h"
 #include "public/platform/WebThread.h"
@@ -106,7 +105,7 @@
     void reattach(const WebString& hostId, int sessionId, const WebString& savedState) override;
     void detach() override;
     void continueProgram() override;
-    void dispatchOnInspectorBackend(int sessionId, const WebString& message) override;
+    void dispatchOnInspectorBackend(int sessionId, int callId, const WebString& method, const WebString& message) override;
     void inspectElementAt(const WebPoint&) override;
     void failedToRequestDevTools() override;
     WebString evaluateInWebInspectorOverlay(const WebString& script) override;
@@ -150,7 +149,7 @@
     bool m_hasBeenDisposed;
 #endif
 
-    Member<InstrumentingSessions> m_instrumentingSessions;
+    Member<InstrumentingAgents> m_instrumentingAgents;
     Member<InspectorResourceContentLoader> m_resourceContentLoader;
     Member<InspectorOverlay> m_overlay;
     Member<InspectedFrames> m_inspectedFrames;
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
index b8e98c9..d77299aa 100644
--- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.cpp
@@ -196,13 +196,13 @@
         devtoolsAgent->detach();
 }
 
-void WebEmbeddedWorkerImpl::dispatchDevToolsMessage(int sessionId, const WebString& message)
+void WebEmbeddedWorkerImpl::dispatchDevToolsMessage(int sessionId, int callId, const WebString& method, const WebString& message)
 {
     if (m_askedToTerminate)
         return;
     WebDevToolsAgent* devtoolsAgent = m_mainFrame->devToolsAgent();
     if (devtoolsAgent)
-        devtoolsAgent->dispatchOnInspectorBackend(sessionId, message);
+        devtoolsAgent->dispatchOnInspectorBackend(sessionId, callId, method, message);
 }
 
 void WebEmbeddedWorkerImpl::addMessageToConsole(const WebConsoleMessage& message)
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
index 34e88d3..c2681ab 100644
--- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImpl.h
@@ -66,7 +66,7 @@
     void attachDevTools(const WebString& hostId, int sessionId) override;
     void reattachDevTools(const WebString& hostId, int sessionId, const WebString& savedState) override;
     void detachDevTools() override;
-    void dispatchDevToolsMessage(int sessionId, const WebString&) override;
+    void dispatchDevToolsMessage(int sessionId, int callId, const WebString& method, const WebString& message) override;
     void addMessageToConsole(const WebConsoleMessage&) override;
 
     void postMessageToPageInspector(const WTF::String&);
diff --git a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
index 2d8266572..21a8519 100644
--- a/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
+++ b/third_party/WebKit/Source/web/WebFrameWidgetImpl.h
@@ -122,7 +122,7 @@
     void setBaseBackgroundColor(WebColor) override;
     void scheduleAnimation() override;
 
-    WebWidgetClient* client() const { return m_client; }
+    WebWidgetClient* client() const override { return m_client; }
 
     Frame* focusedCoreFrame() const;
 
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index 2baa092..e702d81 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -271,7 +271,7 @@
 
 // Simple class to override some of PrintContext behavior. Some of the methods
 // made virtual so that they can be overridden by ChromePluginPrintContext.
-class ChromePrintContext : public PrintContext, public DisplayItemClient {
+class ChromePrintContext : public PrintContext {
     WTF_MAKE_NONCOPYABLE(ChromePrintContext);
 public:
     ChromePrintContext(LocalFrame* frame)
@@ -309,7 +309,7 @@
         SkPictureBuilder pictureBuilder(pageRect, &skia::GetMetaData(*canvas));
         pictureBuilder.context().setPrinting(true);
 
-        float scale = spoolPage(pictureBuilder.context(), pageNumber);
+        float scale = spoolPage(pictureBuilder, pageNumber);
         pictureBuilder.endRecording()->playback(canvas);
         return scale;
     }
@@ -339,7 +339,7 @@
 
         // Fill the whole background by white.
         {
-            DrawingRecorder backgroundRecorder(context, *this, DisplayItem::PrintedContentBackground, allPagesRect);
+            DrawingRecorder backgroundRecorder(context, pictureBuilder, DisplayItem::PrintedContentBackground, allPagesRect);
             context.fillRect(FloatRect(0, 0, pageWidth, totalHeight), Color::white);
         }
 
@@ -348,7 +348,7 @@
             ScopeRecorder scopeRecorder(context);
             // Draw a line for a page boundary if this isn't the first page.
             if (pageIndex > 0) {
-                DrawingRecorder lineBoundaryRecorder(context, *this, DisplayItem::PrintedContentLineBoundary, allPagesRect);
+                DrawingRecorder lineBoundaryRecorder(context, pictureBuilder, DisplayItem::PrintedContentLineBoundary, allPagesRect);
                 context.save();
                 context.setStrokeColor(Color(0, 0, 255));
                 context.setFillColor(Color(0, 0, 255));
@@ -364,42 +364,39 @@
             float scale = getPageShrink(pageIndex);
             transform.scale(scale, scale);
 #endif
-            TransformRecorder transformRecorder(context, *this, transform);
-            spoolPage(context, pageIndex);
+            TransformRecorder transformRecorder(context, pictureBuilder, transform);
+            spoolPage(pictureBuilder, pageIndex);
 
             currentHeight += pageSizeInPixels.height() + 1;
         }
         pictureBuilder.endRecording()->playback(canvas);
     }
 
-    // DisplayItemClient methods
-    String debugName() const final { return "ChromePrintContext"; }
-    LayoutRect visualRect() const override { return LayoutRect(); }
-
 protected:
     // Spools the printed page, a subrect of frame(). Skip the scale step.
     // NativeTheme doesn't play well with scaling. Scaling is done browser side
     // instead. Returns the scale to be applied.
     // On Linux, we don't have the problem with NativeTheme, hence we let WebKit
     // do the scaling and ignore the return value.
-    virtual float spoolPage(GraphicsContext& context, int pageNumber)
+    virtual float spoolPage(SkPictureBuilder& pictureBuilder, int pageNumber)
     {
         IntRect pageRect = m_pageRects[pageNumber];
         float scale = m_printedPageWidth / pageRect.width();
+        GraphicsContext& context = pictureBuilder.context();
 
         AffineTransform transform;
 #if OS(POSIX) && !OS(MACOSX)
         transform.scale(scale);
 #endif
         transform.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y()));
-        TransformRecorder transformRecorder(context, *this, transform);
+        TransformRecorder transformRecorder(context, pictureBuilder, transform);
 
-        ClipRecorder clipRecorder(context, *this, DisplayItem::ClipPrintedPage, LayoutRect(pageRect));
+        ClipRecorder clipRecorder(context, pictureBuilder, DisplayItem::ClipPrintedPage, LayoutRect(pageRect));
 
         frame()->view()->paintContents(context, GlobalPaintNormalPhase, pageRect);
 
         {
-            DrawingRecorder lineBoundaryRecorder(context, *this, DisplayItem::PrintedContentDestinationLocations, pageRect);
+            DrawingRecorder lineBoundaryRecorder(context, pictureBuilder, DisplayItem::PrintedContentDestinationLocations, pageRect);
             outputLinkedDestinations(context, pageRect);
         }
 
@@ -471,10 +468,10 @@
     // Spools the printed page, a subrect of frame(). Skip the scale step.
     // NativeTheme doesn't play well with scaling. Scaling is done browser side
     // instead. Returns the scale to be applied.
-    float spoolPage(GraphicsContext& context, int pageNumber) override
+    float spoolPage(SkPictureBuilder& pictureBuilder, int pageNumber) override
     {
         IntRect pageRect = m_pageRects[pageNumber];
-        m_plugin->printPage(pageNumber, context, pageRect);
+        m_plugin->printPage(pageNumber, pictureBuilder.context(), pageRect);
 
         return 1.0;
     }
@@ -1571,6 +1568,10 @@
 
     WebViewImpl* webView = viewImpl();
 
+    // Check if we're shutting down.
+    if (!webView->page())
+        return;
+
     bool isMainFrame = !parent();
     IntSize initialSize = (isMainFrame || !frameWidget()) ? webView->mainFrameSize() : (IntSize)frameWidget()->size();
     bool isTransparent = !isMainFrame && parent()->isWebRemoteFrame() ? true : webView->isTransparent();
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
index 10c60f5c..3e9d44c 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.cpp
@@ -384,13 +384,13 @@
         devtoolsAgent->detach();
 }
 
-void WebSharedWorkerImpl::dispatchDevToolsMessage(int sessionId, const WebString& message)
+void WebSharedWorkerImpl::dispatchDevToolsMessage(int sessionId, int callId, const WebString& method, const WebString& message)
 {
     if (m_askedToTerminate)
         return;
     WebDevToolsAgent* devtoolsAgent = m_mainFrame->devToolsAgent();
     if (devtoolsAgent)
-        devtoolsAgent->dispatchOnInspectorBackend(sessionId, message);
+        devtoolsAgent->dispatchOnInspectorBackend(sessionId, callId, method, message);
 }
 
 WebSharedWorker* WebSharedWorker::create(WebSharedWorkerClient* client)
diff --git a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
index 468e7a92..de5099dd 100644
--- a/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
+++ b/third_party/WebKit/Source/web/WebSharedWorkerImpl.h
@@ -106,7 +106,7 @@
     void attachDevTools(const WebString& hostId, int sessionId) override;
     void reattachDevTools(const WebString& hostId, int sesionId, const WebString& savedState) override;
     void detachDevTools() override;
-    void dispatchDevToolsMessage(int sessionId, const WebString&) override;
+    void dispatchDevToolsMessage(int sessionId, int callId, const WebString& method, const WebString& message) override;
 
 private:
     ~WebSharedWorkerImpl() override;
diff --git a/third_party/WebKit/Source/web/WebViewFrameWidget.h b/third_party/WebKit/Source/web/WebViewFrameWidget.h
index e7761d7..dd1c593 100644
--- a/third_party/WebKit/Source/web/WebViewFrameWidget.h
+++ b/third_party/WebKit/Source/web/WebViewFrameWidget.h
@@ -94,6 +94,7 @@
     void setBaseBackgroundColor(WebColor) override;
     bool forSubframe() const { return false; }
     void scheduleAnimation() override;
+    WebWidgetClient* client() const override { return m_client; }
 
 private:
     WebWidgetClient* m_client;
diff --git a/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp b/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp
index 19327c5..c405ad1 100644
--- a/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp
@@ -31,7 +31,7 @@
         : m_baseURL("http://www.test.com/")
     {
         RuntimeEnabledFeatures::setCompositorWorkerEnabled(true);
-        m_helper.initialize(true, 0, &m_mockWebViewClient, &configureSettings);
+        m_helper.initialize(true, nullptr, &m_mockWebViewClient, nullptr, &configureSettings);
         webViewImpl()->resize(IntSize(320, 240));
     }
 
diff --git a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
index d3aa43a..8e7e2079 100644
--- a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
@@ -69,7 +69,7 @@
     void SetUp() override
     {
         // We want the images to load and JavaScript to be on.
-        m_helper.initialize(true, 0, 0, &configureSettings);
+        m_helper.initialize(true, nullptr, nullptr, nullptr, &configureSettings);
     }
 
     void TearDown() override
diff --git a/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp b/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp
index 95996064..438ebbf 100644
--- a/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp
+++ b/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp
@@ -189,7 +189,7 @@
     reset();
 }
 
-WebViewImpl* WebViewHelper::initializeWithOpener(WebFrame* opener, bool enableJavascript, TestWebFrameClient* webFrameClient, TestWebViewClient* webViewClient, void (*updateSettingsFunc)(WebSettings*))
+WebViewImpl* WebViewHelper::initializeWithOpener(WebFrame* opener, bool enableJavascript, TestWebFrameClient* webFrameClient, TestWebViewClient* webViewClient, TestWebWidgetClient* webWidgetClient, void (*updateSettingsFunc)(WebSettings*))
 {
     reset();
 
@@ -197,6 +197,8 @@
         webFrameClient = defaultWebFrameClient();
     if (!webViewClient)
         webViewClient = defaultWebViewClient();
+    if (!webWidgetClient)
+        webWidgetClient = webViewClient->widgetClient();
     m_webView = WebViewImpl::create(webViewClient);
     m_webView->settings()->setJavaScriptEnabled(enableJavascript);
     m_webView->settings()->setPluginsEnabled(true);
@@ -218,21 +220,21 @@
     m_webView->setMainFrame(frame);
     // TODO(dcheng): The main frame widget currently has a special case.
     // Eliminate this once WebView is no longer a WebWidget.
-    m_webViewWidget = blink::WebFrameWidget::create(webViewClient, m_webView, frame);
+    m_webViewWidget = blink::WebFrameWidget::create(webWidgetClient, m_webView, frame);
 
     m_testWebViewClient = webViewClient;
 
     return m_webView;
 }
 
-WebViewImpl* WebViewHelper::initialize(bool enableJavascript, TestWebFrameClient* webFrameClient, TestWebViewClient* webViewClient, void (*updateSettingsFunc)(WebSettings*))
+WebViewImpl* WebViewHelper::initialize(bool enableJavascript, TestWebFrameClient* webFrameClient, TestWebViewClient* webViewClient, TestWebWidgetClient* webWidgetClient, void (*updateSettingsFunc)(WebSettings*))
 {
-    return initializeWithOpener(nullptr, enableJavascript, webFrameClient, webViewClient, updateSettingsFunc);
+    return initializeWithOpener(nullptr, enableJavascript, webFrameClient, webViewClient, webWidgetClient, updateSettingsFunc);
 }
 
-WebViewImpl* WebViewHelper::initializeAndLoad(const std::string& url, bool enableJavascript, TestWebFrameClient* webFrameClient, TestWebViewClient* webViewClient, void (*updateSettingsFunc)(WebSettings*))
+WebViewImpl* WebViewHelper::initializeAndLoad(const std::string& url, bool enableJavascript, TestWebFrameClient* webFrameClient, TestWebViewClient* webViewClient, TestWebWidgetClient* webWidgetClient, void (*updateSettingsFunc)(WebSettings*))
 {
-    initialize(enableJavascript, webFrameClient, webViewClient, updateSettingsFunc);
+    initialize(enableJavascript, webFrameClient, webViewClient, webWidgetClient, updateSettingsFunc);
 
     loadFrame(webView()->mainFrame(), url);
 
diff --git a/third_party/WebKit/Source/web/tests/FrameTestHelpers.h b/third_party/WebKit/Source/web/tests/FrameTestHelpers.h
index adba60b..be5c57b 100644
--- a/third_party/WebKit/Source/web/tests/FrameTestHelpers.h
+++ b/third_party/WebKit/Source/web/tests/FrameTestHelpers.h
@@ -59,6 +59,7 @@
 namespace FrameTestHelpers {
 
 class TestWebFrameClient;
+using TestWebWidgetClient = WebWidgetClient;
 
 // Loads a url into the specified WebFrame for testing purposes. Pumps any
 // pending resource requests, as well as waiting for the threaded parser to
@@ -127,6 +128,11 @@
     bool animationScheduled() { return m_animationScheduled; }
     void clearAnimationScheduled() { m_animationScheduled = false; }
 
+    // TODO(lfg): This is a temporary method to retrieve the WebWidgetClient,
+    // while we refactor WebView to not inherit from Webwidget.
+    // Returns the WebWidgetClient.
+    WebWidgetClient* widgetClient() { return this; }
+
 private:
     OwnPtr<WebLayerTreeView> m_layerTreeView;
     bool m_animationScheduled;
@@ -142,14 +148,14 @@
     // Creates and initializes the WebView. Implicitly calls reset() first. If
     // a WebFrameClient or a WebViewClient are passed in, they must outlive the
     // WebViewHelper.
-    WebViewImpl* initializeWithOpener(WebFrame* opener, bool enableJavascript = false, TestWebFrameClient* = nullptr, TestWebViewClient* = nullptr, void (*updateSettingsFunc)(WebSettings*) = nullptr);
+    WebViewImpl* initializeWithOpener(WebFrame* opener, bool enableJavascript = false, TestWebFrameClient* = nullptr, TestWebViewClient* = nullptr, TestWebWidgetClient* = nullptr, void (*updateSettingsFunc)(WebSettings*) = nullptr);
 
     // Same as initializeWithOpener(), but always sets the opener to null.
-    WebViewImpl* initialize(bool enableJavascript = false, TestWebFrameClient* = 0, TestWebViewClient* = 0, void (*updateSettingsFunc)(WebSettings*) = 0);
+    WebViewImpl* initialize(bool enableJavascript = false, TestWebFrameClient* = nullptr, TestWebViewClient* = nullptr, TestWebWidgetClient* = nullptr, void (*updateSettingsFunc)(WebSettings*) = 0);
 
     // Same as initialize() but also performs the initial load of the url. Only
     // returns once the load is complete.
-    WebViewImpl* initializeAndLoad(const std::string& url, bool enableJavascript = false, TestWebFrameClient* = 0, TestWebViewClient* = 0, void (*updateSettingsFunc)(WebSettings*) = 0);
+    WebViewImpl* initializeAndLoad(const std::string& url, bool enableJavascript = false, TestWebFrameClient* = nullptr, TestWebViewClient* = nullptr, TestWebWidgetClient* = nullptr, void (*updateSettingsFunc)(WebSettings*) = 0);
 
     void resize(WebSize);
 
diff --git a/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp b/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp
index a82e133a..b87c75c 100644
--- a/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp
+++ b/third_party/WebKit/Source/web/tests/LinkSelectionTest.cpp
@@ -108,7 +108,7 @@
 
         // We need to set deviceSupportsMouse setting to true and page's focus controller to active
         // so that FrameView can set the mouse cursor.
-        m_webView = m_helper.initialize(false, &m_testFrameClient, nullptr,
+        m_webView = m_helper.initialize(false, &m_testFrameClient, nullptr, nullptr,
             [](WebSettings* settings) { settings->setDeviceSupportsMouse(true); });
         m_mainFrame = m_webView->mainFrameImpl();
         FrameTestHelpers::loadHTMLString(m_mainFrame, kHTMLString, URLTestHelpers::toKURL("http://foobar.com"));
diff --git a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
index 70f4f792..4c6abf7 100644
--- a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
@@ -59,7 +59,8 @@
         // Load a page with large body and set viewport size to 400x400 to
         // ensure main frame is scrollable.
         m_helper.initializeAndLoad(
-            m_baseURL + pageName, true, 0, &m_client, &configureSettings);
+            m_baseURL + pageName, true, nullptr, &m_client, nullptr,
+            &configureSettings);
 
         // Initialize top controls to be shown.
         webViewImpl()->resizeWithTopControls(IntSize(400, 400), 50, true);
diff --git a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
index 00047a3b..6faad43 100644
--- a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
@@ -52,7 +52,7 @@
     ScrollingCoordinatorTest()
         : m_baseURL("http://www.test.com/")
     {
-        m_helper.initialize(true, 0, &m_mockWebViewClient, &configureSettings);
+        m_helper.initialize(true, nullptr, &m_mockWebViewClient, nullptr, &configureSettings);
         webViewImpl()->resize(IntSize(320, 240));
 
         // OSX attaches main frame scrollbars to the VisualViewport so the VisualViewport layers need
diff --git a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
index faf99c2..6fd0027 100644
--- a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
@@ -78,7 +78,7 @@
 
         // Load a page with large body and set viewport size to 400x400 to ensure
         // main frame is scrollable.
-        m_helper.initializeAndLoad(m_baseURL + pageName, true, 0, 0, &configureSettings);
+        m_helper.initializeAndLoad(m_baseURL + pageName, true, nullptr, nullptr, nullptr, &configureSettings);
 
         webViewImpl()->resize(IntSize(400, 400));
         return webViewImpl();
diff --git a/third_party/WebKit/Source/web/tests/ViewportTest.cpp b/third_party/WebKit/Source/web/tests/ViewportTest.cpp
index d365edd..695cd6a9 100644
--- a/third_party/WebKit/Source/web/tests/ViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ViewportTest.cpp
@@ -113,7 +113,7 @@
     registerMockedHttpURLLoad("viewport/viewport-1.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-1.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-1.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -131,7 +131,7 @@
     registerMockedHttpURLLoad("viewport/viewport-2.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-2.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-2.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -149,7 +149,7 @@
     registerMockedHttpURLLoad("viewport/viewport-3.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-3.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-3.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -167,7 +167,7 @@
     registerMockedHttpURLLoad("viewport/viewport-4.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-4.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-4.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -185,7 +185,7 @@
     registerMockedHttpURLLoad("viewport/viewport-5.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-5.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-5.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -203,7 +203,7 @@
     registerMockedHttpURLLoad("viewport/viewport-6.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-6.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-6.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -222,7 +222,7 @@
     registerMockedHttpURLLoad("viewport/viewport-7.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-7.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-7.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -240,7 +240,7 @@
     registerMockedHttpURLLoad("viewport/viewport-8.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-8.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-8.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -258,7 +258,7 @@
     registerMockedHttpURLLoad("viewport/viewport-9.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-9.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-9.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -276,7 +276,7 @@
     registerMockedHttpURLLoad("viewport/viewport-10.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-10.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-10.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -294,7 +294,7 @@
     registerMockedHttpURLLoad("viewport/viewport-11.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-11.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-11.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -312,7 +312,7 @@
     registerMockedHttpURLLoad("viewport/viewport-12.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-12.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-12.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -330,7 +330,7 @@
     registerMockedHttpURLLoad("viewport/viewport-13.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-13.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-13.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -348,7 +348,7 @@
     registerMockedHttpURLLoad("viewport/viewport-14.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-14.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-14.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -366,7 +366,7 @@
     registerMockedHttpURLLoad("viewport/viewport-15.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-15.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-15.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -384,7 +384,7 @@
     registerMockedHttpURLLoad("viewport/viewport-16.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-16.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-16.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -402,7 +402,7 @@
     registerMockedHttpURLLoad("viewport/viewport-17.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-17.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-17.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -420,7 +420,7 @@
     registerMockedHttpURLLoad("viewport/viewport-18.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-18.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-18.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -438,7 +438,7 @@
     registerMockedHttpURLLoad("viewport/viewport-19.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-19.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-19.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -456,7 +456,7 @@
     registerMockedHttpURLLoad("viewport/viewport-20.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-20.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-20.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -474,7 +474,7 @@
     registerMockedHttpURLLoad("viewport/viewport-21.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-21.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-21.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -492,7 +492,7 @@
     registerMockedHttpURLLoad("viewport/viewport-22.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-22.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-22.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -510,7 +510,7 @@
     registerMockedHttpURLLoad("viewport/viewport-23.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-23.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-23.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -528,7 +528,7 @@
     registerMockedHttpURLLoad("viewport/viewport-24.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-24.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-24.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -546,7 +546,7 @@
     registerMockedHttpURLLoad("viewport/viewport-25.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-25.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-25.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -564,7 +564,7 @@
     registerMockedHttpURLLoad("viewport/viewport-26.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-26.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-26.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -582,7 +582,7 @@
     registerMockedHttpURLLoad("viewport/viewport-27.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-27.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-27.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -600,7 +600,7 @@
     registerMockedHttpURLLoad("viewport/viewport-28.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-28.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-28.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -618,7 +618,7 @@
     registerMockedHttpURLLoad("viewport/viewport-29.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-29.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-29.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -636,7 +636,7 @@
     registerMockedHttpURLLoad("viewport/viewport-30.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-30.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-30.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -654,7 +654,7 @@
     registerMockedHttpURLLoad("viewport/viewport-31.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-31.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-31.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -672,7 +672,7 @@
     registerMockedHttpURLLoad("viewport/viewport-32.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-32.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-32.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -690,7 +690,7 @@
     registerMockedHttpURLLoad("viewport/viewport-33.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-33.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-33.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -708,7 +708,7 @@
     registerMockedHttpURLLoad("viewport/viewport-34.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-34.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-34.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -726,7 +726,7 @@
     registerMockedHttpURLLoad("viewport/viewport-35.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-35.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-35.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -744,7 +744,7 @@
     registerMockedHttpURLLoad("viewport/viewport-36.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-36.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-36.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -762,7 +762,7 @@
     registerMockedHttpURLLoad("viewport/viewport-37.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-37.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-37.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -780,7 +780,7 @@
     registerMockedHttpURLLoad("viewport/viewport-38.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-38.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-38.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -798,7 +798,7 @@
     registerMockedHttpURLLoad("viewport/viewport-39.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-39.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-39.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -816,7 +816,7 @@
     registerMockedHttpURLLoad("viewport/viewport-40.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-40.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-40.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -834,7 +834,7 @@
     registerMockedHttpURLLoad("viewport/viewport-41.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-41.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-41.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -852,7 +852,7 @@
     registerMockedHttpURLLoad("viewport/viewport-42.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-42.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-42.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -870,7 +870,7 @@
     registerMockedHttpURLLoad("viewport/viewport-43.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-43.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-43.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -888,7 +888,7 @@
     registerMockedHttpURLLoad("viewport/viewport-44.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-44.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-44.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -906,7 +906,7 @@
     registerMockedHttpURLLoad("viewport/viewport-45.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-45.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-45.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -924,7 +924,7 @@
     registerMockedHttpURLLoad("viewport/viewport-46.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-46.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-46.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -942,7 +942,7 @@
     registerMockedHttpURLLoad("viewport/viewport-47.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-47.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-47.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -960,7 +960,7 @@
     registerMockedHttpURLLoad("viewport/viewport-48.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-48.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-48.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -978,7 +978,7 @@
     registerMockedHttpURLLoad("viewport/viewport-49.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-49.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-49.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -996,7 +996,7 @@
     registerMockedHttpURLLoad("viewport/viewport-50.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-50.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-50.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1014,7 +1014,7 @@
     registerMockedHttpURLLoad("viewport/viewport-51.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-51.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-51.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1032,7 +1032,7 @@
     registerMockedHttpURLLoad("viewport/viewport-52.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-52.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-52.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1050,7 +1050,7 @@
     registerMockedHttpURLLoad("viewport/viewport-53.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-53.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-53.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1068,7 +1068,7 @@
     registerMockedHttpURLLoad("viewport/viewport-54.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-54.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-54.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1086,7 +1086,7 @@
     registerMockedHttpURLLoad("viewport/viewport-55.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-55.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-55.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1104,7 +1104,7 @@
     registerMockedHttpURLLoad("viewport/viewport-56.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-56.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-56.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1122,7 +1122,7 @@
     registerMockedHttpURLLoad("viewport/viewport-57.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-57.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-57.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1140,7 +1140,7 @@
     registerMockedHttpURLLoad("viewport/viewport-58.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-58.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-58.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1158,7 +1158,7 @@
     registerMockedHttpURLLoad("viewport/viewport-59.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-59.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-59.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1176,7 +1176,7 @@
     registerMockedHttpURLLoad("viewport/viewport-60.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-60.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-60.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1194,7 +1194,7 @@
     registerMockedHttpURLLoad("viewport/viewport-61.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-61.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-61.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1212,7 +1212,7 @@
     registerMockedHttpURLLoad("viewport/viewport-62.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-62.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-62.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1230,7 +1230,7 @@
     registerMockedHttpURLLoad("viewport/viewport-63.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-63.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-63.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1248,7 +1248,7 @@
     registerMockedHttpURLLoad("viewport/viewport-64.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-64.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-64.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1266,7 +1266,7 @@
     registerMockedHttpURLLoad("viewport/viewport-65.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-65.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-65.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1284,7 +1284,7 @@
     registerMockedHttpURLLoad("viewport/viewport-66.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-66.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-66.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1302,7 +1302,7 @@
     registerMockedHttpURLLoad("viewport/viewport-67.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-67.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-67.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1320,7 +1320,7 @@
     registerMockedHttpURLLoad("viewport/viewport-68.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-68.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-68.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1338,7 +1338,7 @@
     registerMockedHttpURLLoad("viewport/viewport-69.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-69.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-69.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1356,7 +1356,7 @@
     registerMockedHttpURLLoad("viewport/viewport-70.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-70.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-70.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1374,7 +1374,7 @@
     registerMockedHttpURLLoad("viewport/viewport-71.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-71.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-71.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1392,7 +1392,7 @@
     registerMockedHttpURLLoad("viewport/viewport-72.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-72.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-72.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1410,7 +1410,7 @@
     registerMockedHttpURLLoad("viewport/viewport-73.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-73.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-73.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1428,7 +1428,7 @@
     registerMockedHttpURLLoad("viewport/viewport-74.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-74.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-74.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1446,7 +1446,7 @@
     registerMockedHttpURLLoad("viewport/viewport-75.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-75.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-75.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1464,7 +1464,7 @@
     registerMockedHttpURLLoad("viewport/viewport-76.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-76.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-76.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1482,7 +1482,7 @@
     registerMockedHttpURLLoad("viewport/viewport-77.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-77.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-77.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1500,7 +1500,7 @@
     registerMockedHttpURLLoad("viewport/viewport-78.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-78.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-78.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1518,7 +1518,7 @@
     registerMockedHttpURLLoad("viewport/viewport-79.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-79.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-79.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1536,7 +1536,7 @@
     registerMockedHttpURLLoad("viewport/viewport-80.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-80.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-80.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1554,7 +1554,7 @@
     registerMockedHttpURLLoad("viewport/viewport-81.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-81.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-81.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1572,7 +1572,7 @@
     registerMockedHttpURLLoad("viewport/viewport-82.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-82.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-82.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1590,7 +1590,7 @@
     registerMockedHttpURLLoad("viewport/viewport-83.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-83.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-83.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1608,7 +1608,7 @@
     registerMockedHttpURLLoad("viewport/viewport-84.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-84.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-84.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1626,7 +1626,7 @@
     registerMockedHttpURLLoad("viewport/viewport-85.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-85.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-85.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1644,7 +1644,7 @@
     registerMockedHttpURLLoad("viewport/viewport-86.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-86.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-86.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1662,7 +1662,7 @@
     registerMockedHttpURLLoad("viewport/viewport-87.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-87.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-87.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1680,7 +1680,7 @@
     registerMockedHttpURLLoad("viewport/viewport-88.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-88.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-88.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1698,7 +1698,7 @@
     registerMockedHttpURLLoad("viewport/viewport-90.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-90.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-90.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1716,7 +1716,7 @@
     registerMockedHttpURLLoad("viewport/viewport-100.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-100.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-100.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1734,7 +1734,7 @@
     registerMockedHttpURLLoad("viewport/viewport-101.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-101.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-101.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1752,7 +1752,7 @@
     registerMockedHttpURLLoad("viewport/viewport-102.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-102.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-102.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1770,7 +1770,7 @@
     registerMockedHttpURLLoad("viewport/viewport-103.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-103.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-103.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1788,7 +1788,7 @@
     registerMockedHttpURLLoad("viewport/viewport-104.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-104.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-104.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1806,7 +1806,7 @@
     registerMockedHttpURLLoad("viewport/viewport-105.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-105.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-105.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1824,7 +1824,7 @@
     registerMockedHttpURLLoad("viewport/viewport-106.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-106.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-106.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1842,7 +1842,7 @@
     registerMockedHttpURLLoad("viewport/viewport-107.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-107.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-107.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1860,7 +1860,7 @@
     registerMockedHttpURLLoad("viewport/viewport-108.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-108.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-108.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1878,7 +1878,7 @@
     registerMockedHttpURLLoad("viewport/viewport-109.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-109.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-109.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1896,7 +1896,7 @@
     registerMockedHttpURLLoad("viewport/viewport-110.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-110.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-110.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1914,7 +1914,7 @@
     registerMockedHttpURLLoad("viewport/viewport-111.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-111.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-111.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1932,7 +1932,7 @@
     registerMockedHttpURLLoad("viewport/viewport-112.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-112.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-112.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1950,7 +1950,7 @@
     registerMockedHttpURLLoad("viewport/viewport-113.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-113.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-113.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1968,7 +1968,7 @@
     registerMockedHttpURLLoad("viewport/viewport-114.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-114.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-114.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -1986,7 +1986,7 @@
     registerMockedHttpURLLoad("viewport/viewport-115.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-115.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-115.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2004,7 +2004,7 @@
     registerMockedHttpURLLoad("viewport/viewport-116.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-116.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-116.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2022,7 +2022,7 @@
     registerMockedHttpURLLoad("viewport/viewport-117.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-117.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-117.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2040,7 +2040,7 @@
     registerMockedHttpURLLoad("viewport/viewport-118.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-118.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-118.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2058,7 +2058,7 @@
     registerMockedHttpURLLoad("viewport/viewport-119.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-119.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-119.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2076,7 +2076,7 @@
     registerMockedHttpURLLoad("viewport/viewport-120.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-120.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-120.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2094,7 +2094,7 @@
     registerMockedHttpURLLoad("viewport/viewport-121.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-121.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-121.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2112,7 +2112,7 @@
     registerMockedHttpURLLoad("viewport/viewport-122.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-122.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-122.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2130,7 +2130,7 @@
     registerMockedHttpURLLoad("viewport/viewport-123.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-123.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-123.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2148,7 +2148,7 @@
     registerMockedHttpURLLoad("viewport/viewport-124.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-124.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-124.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2166,7 +2166,7 @@
     registerMockedHttpURLLoad("viewport/viewport-125.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-125.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-125.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2184,7 +2184,7 @@
     registerMockedHttpURLLoad("viewport/viewport-126.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-126.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-126.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2202,7 +2202,7 @@
     registerMockedHttpURLLoad("viewport/viewport-127.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-127.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-127.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2220,7 +2220,7 @@
     registerMockedHttpURLLoad("viewport/viewport-129.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-129.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-129.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2238,7 +2238,7 @@
     registerMockedHttpURLLoad("viewport/viewport-130.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-130.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-130.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2256,7 +2256,7 @@
     registerMockedHttpURLLoad("viewport/viewport-131.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-131.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-131.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2274,7 +2274,7 @@
     registerMockedHttpURLLoad("viewport/viewport-132.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-132.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-132.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2292,7 +2292,7 @@
     registerMockedHttpURLLoad("viewport/viewport-133.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-133.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-133.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2310,7 +2310,7 @@
     registerMockedHttpURLLoad("viewport/viewport-134.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-134.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-134.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2328,7 +2328,7 @@
     registerMockedHttpURLLoad("viewport/viewport-135.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-135.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-135.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2346,7 +2346,7 @@
     registerMockedHttpURLLoad("viewport/viewport-136.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-136.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-136.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2364,7 +2364,7 @@
     registerMockedHttpURLLoad("viewport/viewport-137.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-137.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-137.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2382,7 +2382,7 @@
     registerMockedHttpURLLoad("viewport/viewport-138.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-138.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-138.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2400,7 +2400,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-handheldfriendly.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-handheldfriendly.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-handheldfriendly.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2426,7 +2426,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-merge-quirk-1.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-merge-quirk-1.html", true, 0, 0, setQuirkViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-merge-quirk-1.html", true, nullptr, nullptr, nullptr, setQuirkViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2444,7 +2444,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-merge-quirk-2.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-merge-quirk-2.html", true, 0, 0, setQuirkViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-merge-quirk-2.html", true, nullptr, nullptr, nullptr, setQuirkViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2465,7 +2465,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-mobileoptimized.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-mobileoptimized.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-mobileoptimized.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2484,7 +2484,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-mobileoptimized-2.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-mobileoptimized-2.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-mobileoptimized-2.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2503,7 +2503,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-mobileoptimized-2.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-mobileoptimized-2.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-mobileoptimized-2.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2522,7 +2522,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-2.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-2.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-2.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2541,7 +2541,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-3.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-3.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-3.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2560,7 +2560,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-4.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-4.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-4.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2579,7 +2579,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-5.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-5.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-5.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2598,7 +2598,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-6.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-6.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-6.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2617,7 +2617,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-7.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-7.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-7.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2636,7 +2636,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-8.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-8.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-8.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2655,7 +2655,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-ordering-10.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-10.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-ordering-10.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 800, 600);
@@ -2668,7 +2668,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-xhtmlmp.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2686,7 +2686,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-xhtmlmp-misplaced-doctype.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp-misplaced-doctype.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp-misplaced-doctype.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2704,7 +2704,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-xhtmlmp-ordering.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp-ordering.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp-ordering.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2722,7 +2722,7 @@
     registerMockedHttpURLLoad("viewport/viewport-legacy-xhtmlmp.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-legacy-xhtmlmp.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2765,7 +2765,7 @@
     registerMockedHttpURLLoad("viewport/viewport-limits-adjusted-for-no-user-scale.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-limits-adjusted-for-no-user-scale.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-limits-adjusted-for-no-user-scale.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2777,7 +2777,7 @@
     registerMockedHttpURLLoad("viewport/viewport-limits-adjusted-for-no-user-scale-control.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-limits-adjusted-for-no-user-scale-control.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-limits-adjusted-for-no-user-scale-control.html", true, nullptr, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
 
@@ -2788,32 +2788,32 @@
 {
     registerMockedHttpURLLoad("viewport/viewport-gpu-rasterization.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-gpu-rasterization.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-gpu-rasterization.html", true, nullptr, nullptr, nullptr, setViewportSettings);
     webViewHelper.webView()->resize(WebSize(640, 480));
     EXPECT_TRUE(webViewHelper.webViewImpl()->matchesHeuristicsForGpuRasterizationForTesting());
 
     registerMockedHttpURLLoad("viewport/viewport-gpu-rasterization-expanded-heuristics.html");
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-gpu-rasterization-expanded-heuristics.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-gpu-rasterization-expanded-heuristics.html", true, nullptr, nullptr, nullptr, setViewportSettings);
     webViewHelper.webView()->resize(WebSize(640, 480));
     EXPECT_TRUE(webViewHelper.webViewImpl()->matchesHeuristicsForGpuRasterizationForTesting());
 
     registerMockedHttpURLLoad("viewport/viewport-inferred-values-do-not-trigger-gpu-rasterization.html");
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-inferred-values-do-not-trigger-gpu-rasterization.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-inferred-values-do-not-trigger-gpu-rasterization.html", true, nullptr, nullptr, nullptr, setViewportSettings);
     webViewHelper.webView()->resize(WebSize(640, 480));
     EXPECT_FALSE(webViewHelper.webViewImpl()->matchesHeuristicsForGpuRasterizationForTesting());
 
     registerMockedHttpURLLoad("viewport/viewport-1.html");
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-1.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-1.html", true, nullptr, nullptr, nullptr, setViewportSettings);
     webViewHelper.webView()->resize(WebSize(640, 480));
     EXPECT_FALSE(webViewHelper.webViewImpl()->matchesHeuristicsForGpuRasterizationForTesting());
 
     registerMockedHttpURLLoad("viewport/viewport-15.html");
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-15.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-15.html", true, nullptr, nullptr, nullptr, setViewportSettings);
     webViewHelper.webView()->resize(WebSize(640, 480));
     EXPECT_FALSE(webViewHelper.webViewImpl()->matchesHeuristicsForGpuRasterizationForTesting());
 
     registerMockedHttpURLLoad("viewport/viewport-130.html");
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-130.html", true, 0, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-130.html", true, nullptr, nullptr, nullptr, setViewportSettings);
     webViewHelper.webView()->resize(WebSize(640, 480));
     EXPECT_FALSE(webViewHelper.webViewImpl()->matchesHeuristicsForGpuRasterizationForTesting());
 }
@@ -2835,7 +2835,7 @@
     registerMockedHttpURLLoad("viewport/viewport-warnings-1.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-1.html", true, &webFrameClient, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-1.html", true, &webFrameClient, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2857,7 +2857,7 @@
     registerMockedHttpURLLoad("viewport/viewport-warnings-2.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-2.html", true, &webFrameClient, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-2.html", true, &webFrameClient, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2881,7 +2881,7 @@
     registerMockedHttpURLLoad("viewport/viewport-warnings-3.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-3.html", true, &webFrameClient, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-3.html", true, &webFrameClient, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2906,7 +2906,7 @@
     registerMockedHttpURLLoad("viewport/viewport-warnings-4.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-4.html", true, &webFrameClient, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-4.html", true, &webFrameClient, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2931,7 +2931,7 @@
     registerMockedHttpURLLoad("viewport/viewport-warnings-5.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-5.html", true, &webFrameClient, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-5.html", true, &webFrameClient, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2973,7 +2973,7 @@
     registerMockedHttpURLLoad("viewport/viewport-warnings-6.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-6.html", true, &webFrameClient, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-6.html", true, &webFrameClient, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     PageScaleConstraints constraints = runViewportTest(page, 320, 352);
@@ -2998,7 +2998,7 @@
     registerMockedHttpURLLoad("viewport/viewport-warnings-7.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-7.html", true, &webFrameClient, 0, setViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-warnings-7.html", true, &webFrameClient, nullptr, nullptr, setViewportSettings);
 
     Page* page = webViewHelper.webViewImpl()->page();
     runViewportTest(page, 320, 352);
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
index 138c55a33..1e192b9 100644
--- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -119,7 +119,7 @@
     {
         if (!overrideSettingsFunc)
             overrideSettingsFunc = &configureSettings;
-        m_helper.initialize(true, 0, &m_mockWebViewClient, overrideSettingsFunc);
+        m_helper.initialize(true, nullptr, &m_mockWebViewClient, nullptr, overrideSettingsFunc);
         webViewImpl()->setDefaultPageScaleLimits(1, 4);
     }
 
@@ -127,7 +127,7 @@
     {
         if (!overrideSettingsFunc)
             overrideSettingsFunc = &configureAndroidSettings;
-        m_helper.initialize(true, 0, &m_mockWebViewClient, overrideSettingsFunc);
+        m_helper.initialize(true, nullptr, &m_mockWebViewClient, nullptr, overrideSettingsFunc);
         webViewImpl()->setDefaultPageScaleLimits(0.25f, 5);
     }
 
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 9d560a7..a6e1815 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -912,7 +912,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
 
     Document* document = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->document();
     document->settings()->setTextAutosizingEnabled(true);
@@ -938,7 +938,7 @@
     FixedLayoutTestWebViewClient client;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client, nullptr, configureAndroid);
 
     Document* document = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->document();
     document->settings()->setTextAutosizingEnabled(true);
@@ -960,7 +960,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, nullptr, &client, nullptr, enableViewportSettings);
 
     LocalFrame* mainFrame = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame());
     Document* document = mainFrame->document();
@@ -999,7 +999,7 @@
     int viewportHeight = 0;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client, enableViewportSettings);
+    webViewHelper.initialize(true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
@@ -1017,7 +1017,7 @@
     client.m_screenInfo.deviceScaleFactor = 2;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, nullptr, &client, nullptr, enableViewportSettings);
 
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -1045,7 +1045,7 @@
     // Make sure we initialize to minimum scale, even if the window size
     // only becomes available after the load begins.
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client, enableViewportSettings);
+    webViewHelper.initialize(true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "fixed_layout.html");
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1082,7 +1082,7 @@
     // Make sure we initialize to minimum scale, even if the window size
     // only becomes available after the load begins.
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client, enableViewportSettings);
+    webViewHelper.initialize(true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "wide_document.html");
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1117,7 +1117,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     EXPECT_EQ(0.25f, webViewHelper.webView()->pageScaleFactor());
@@ -1140,7 +1140,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1159,7 +1159,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
@@ -1179,7 +1179,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1199,7 +1199,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1220,7 +1220,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, nullptr, &client, nullptr, enableViewportSettings);
     applyViewportStyleOverride(&webViewHelper);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(true);
@@ -1240,7 +1240,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client, enableViewportSettings);
+    webViewHelper.initialize(true, nullptr, &client, nullptr, enableViewportSettings);
     applyViewportStyleOverride(&webViewHelper);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(true);
@@ -1261,7 +1261,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-height-1000.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-height-1000.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1279,7 +1279,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     applyViewportStyleOverride(&webViewHelper);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(true);
@@ -1299,7 +1299,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -1316,7 +1316,7 @@
     float enforcedPageScaleFactor = 2.0f;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
     applyViewportStyleOverride(&webViewHelper);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
@@ -1347,7 +1347,7 @@
     float enforcedPageScaleFactor = 0.5f;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
     webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1366,7 +1366,7 @@
     float enforcedPageScaleFactor = 0.5f;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -1396,7 +1396,7 @@
     for (size_t i = 0; i < WTF_ARRAY_LENGTH(pages); ++i) {
         for (int quirkEnabled = 0; quirkEnabled <= 1; ++quirkEnabled) {
             FrameTestHelpers::WebViewHelper webViewHelper(this);
-            webViewHelper.initializeAndLoad(m_baseURL + pages[i], true, 0, &client, enableViewportSettings);
+            webViewHelper.initializeAndLoad(m_baseURL + pages[i], true, nullptr, &client, nullptr, enableViewportSettings);
             applyViewportStyleOverride(&webViewHelper);
             webViewHelper.webView()->settings()->setClobberUserAgentInitialScaleQuirk(quirkEnabled);
             webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
@@ -1417,7 +1417,7 @@
     float enforcedPageScaleFactor = 0.5;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
@@ -1439,7 +1439,7 @@
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
 
-    webViewHelper.initializeAndLoad(m_baseURL + "0-by-0.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "0-by-0.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -1460,7 +1460,7 @@
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
 
-    webViewHelper.initializeAndLoad(m_baseURL + "0-by-0.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "0-by-0.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
     PaintLayerCompositor* compositor = webViewHelper.webViewImpl()->compositor();
     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
@@ -1502,7 +1502,7 @@
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
 
-    webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     EXPECT_LE(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
@@ -1539,7 +1539,7 @@
 
     FrameTestHelpers::WebViewHelper webViewHelper;
 
-    webViewHelper.initializeAndLoad(m_baseURL + "button.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "button.html", true, nullptr, &client, nullptr, configureAndroid);
     // set view height to zero so that if the height of the view is not
     // successfully updated during later resizes touch events will fail
     // (as in not hit content included in the view)
@@ -1637,7 +1637,7 @@
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
 
-    webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -1658,7 +1658,7 @@
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
 
-    webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(true);
     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
@@ -1678,7 +1678,7 @@
     int viewportHeight = 800;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(true);
     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
@@ -1703,7 +1703,7 @@
     int viewportHeight = 800;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
@@ -1726,7 +1726,7 @@
     int viewportHeight = 800;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(true);
     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
@@ -1777,7 +1777,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client, enableViewportSettings);
+    webViewHelper.initialize(true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
@@ -1803,7 +1803,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client);
+    webViewHelper.initialize(true, nullptr, &client, nullptr);
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "body-overflow-hidden.html");
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -1822,7 +1822,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client);
+    webViewHelper.initialize(true, nullptr, &client, nullptr);
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "body-overflow-hidden-short.html");
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -1845,7 +1845,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initialize(true, 0, &client);
+    webViewHelper.initialize(true, nullptr, &client, nullptr);
     webViewHelper.webView()->settings()->setIgnoreMainFrameOverflowHiddenQuirk(true);
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "body-overflow-hidden.html");
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1865,7 +1865,7 @@
     float expectedPageScaleFactor = 0.5f;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client, enableViewportSettings);
+    webViewHelper.initialize(true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport-nonzero-values.html");
@@ -1891,7 +1891,7 @@
     int viewportHeight = 48;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
@@ -1910,7 +1910,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
@@ -1930,7 +1930,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     webViewHelper.webView()->setPageScaleFactor(3);
@@ -1947,7 +1947,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &client, enableViewportSettings);
+    webViewHelper.initialize(true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "fixed_layout.html");
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -1968,7 +1968,7 @@
     int viewportHeight = 48;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
@@ -2006,7 +2006,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     webViewHelper.webView()->setPageScaleFactor(2);
@@ -2032,7 +2032,7 @@
         client.m_screenInfo.deviceScaleFactor = deviceScaleFactor;
 
         FrameTestHelpers::WebViewHelper webViewHelper(this);
-        webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-high.html", true, 0, &client, enableViewportSettings);
+        webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-high.html", true, nullptr, &client, nullptr, enableViewportSettings);
         webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
         webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
         webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -2060,7 +2060,7 @@
         client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];
 
         FrameTestHelpers::WebViewHelper webViewHelper(this);
-        webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device.html", true, 0, &client, enableViewportSettings);
+        webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device.html", true, nullptr, &client, nullptr, enableViewportSettings);
         webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
         webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
         webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
@@ -2085,7 +2085,7 @@
         client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];
 
         FrameTestHelpers::WebViewHelper webViewHelper(this);
-        webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device-and-fixed-width.html", true, 0, &client, enableViewportSettings);
+        webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device-and-fixed-width.html", true, nullptr, &client, nullptr, enableViewportSettings);
         webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
         webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
         webViewHelper.webView()->settings()->setUseWideViewport(true);
@@ -2107,7 +2107,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
@@ -2128,7 +2128,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1-device-width.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1-device-width.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
@@ -2150,7 +2150,7 @@
     float enforcedPageScaleFactor = 5.0f;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
@@ -2171,7 +2171,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -2190,7 +2190,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
     webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
@@ -2211,7 +2211,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale-non-user-scalable.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale-non-user-scalable.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(true);
@@ -2231,7 +2231,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setUseWideViewport(false);
@@ -2262,7 +2262,7 @@
         const float aspectRatio = static_cast<float>(viewportSize.width) / viewportSize.height;
 
         FrameTestHelpers::WebViewHelper webViewHelper(this);
-        webViewHelper.initializeAndLoad(m_baseURL + url, true, 0, 0, enableViewportSettings);
+        webViewHelper.initializeAndLoad(m_baseURL + url, true, nullptr, nullptr, nullptr, enableViewportSettings);
         webViewHelper.webViewImpl()->setDefaultPageScaleLimits(0.25f, 5);
 
         // Origin scrollOffsets preserved under resize.
@@ -2364,7 +2364,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
     FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
@@ -2387,7 +2387,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "no_scale_for_you.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "no_scale_for_you.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
 
@@ -2421,7 +2421,7 @@
 
     OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
+    webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(), nullptr, &configueCompositingWebView);
 
     webViewHelper.resize(WebSize(viewWidth, viewHeight));
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "large-div.html");
@@ -2472,7 +2472,7 @@
     int viewportHeight = 1280 / deviceScaleFactor;
     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_for_auto_zoom_into_div_test.html", false, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_for_auto_zoom_into_div_test.html", false, nullptr, nullptr, nullptr, configureAndroid);
     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
     webViewHelper.webView()->setDefaultPageScaleLimits(0.01f, 4);
     webViewHelper.webView()->setPageScaleFactor(0.5f);
@@ -2524,7 +2524,7 @@
     int viewportHeight = 1280 / deviceScaleFactor;
     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "get_wide_div_for_auto_zoom_test.html", false, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "get_wide_div_for_auto_zoom_test.html", false, nullptr, nullptr, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
     webViewHelper.webView()->setPageScaleFactor(1.0f);
@@ -2556,7 +2556,7 @@
     int viewportWidth = 640 / deviceScaleFactor;
     int viewportHeight = 1280 / deviceScaleFactor;
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "very_tall_div.html", true, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "very_tall_div.html", true, nullptr, nullptr, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
     webViewHelper.webView()->setPageScaleFactor(1.0f);
@@ -2582,7 +2582,7 @@
     int viewportHeight = 1280 / deviceScaleFactor;
     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "get_multiple_divs_for_auto_zoom_test.html", false, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "get_multiple_divs_for_auto_zoom_test.html", false, nullptr, nullptr, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
@@ -2631,7 +2631,7 @@
     int viewportHeight = 480;
     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false, nullptr, nullptr, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewHelper.webView()->setDeviceScaleFactor(1.5f);
     webViewHelper.webView()->setMaximumLegibleScale(1.f);
@@ -2694,7 +2694,7 @@
     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
     float maximumLegibleScaleFactor = 1.13f;
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false, nullptr, nullptr, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewHelper.webView()->setMaximumLegibleScale(maximumLegibleScaleFactor);
     webViewHelper.webView()->updateAllLifecyclePhases();
@@ -2773,7 +2773,7 @@
     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
     float accessibilityFontScaleFactor = 1.13f;
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false, nullptr, nullptr, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewHelper.webView()->setMaximumLegibleScale(1.f);
     webViewHelper.webView()->updateAllLifecyclePhases();
@@ -2848,7 +2848,7 @@
     registerMockedHttpURLLoad("block_bound.html");
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "block_bound.html", false, 0, 0, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "block_bound.html", false, nullptr, nullptr, nullptr, configureAndroid);
 
     IntRect rectBack = IntRect(0, 0, 200, 200);
     IntRect rectLeftTop = IntRect(10, 10, 80, 80);
@@ -4629,7 +4629,7 @@
         RuntimeEnabledFeatures::setCompositedSelectionUpdateEnabled(true);
         registerMockedHttpURLLoad("Ahem.ttf");
 
-        m_webViewHelper.initialize(true, 0, &m_fakeSelectionWebViewClient);
+        m_webViewHelper.initialize(true, nullptr, &m_fakeSelectionWebViewClient, nullptr);
         m_webViewHelper.webView()->settings()->setDefaultFontSize(12);
         m_webViewHelper.webView()->setDefaultPageScaleLimits(1, 1);
         m_webViewHelper.resize(WebSize(640, 480));
@@ -4748,7 +4748,7 @@
     CompositedSelectionBoundsTestLayerTreeView& fakeSelectionLayerTreeView = fakeSelectionWebViewClient.selectionLayerTreeView();
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initialize(true, 0, &fakeSelectionWebViewClient);
+    webViewHelper.initialize(true, nullptr, &fakeSelectionWebViewClient, nullptr);
     webViewHelper.webView()->settings()->setDefaultFontSize(12);
     webViewHelper.webView()->setDefaultPageScaleLimits(1, 1);
     webViewHelper.resize(WebSize(viewWidth, viewHeight));
@@ -4901,7 +4901,7 @@
     // Make sure we initialize to minimum scale, even if the window size
     // only becomes available after the load begins.
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(1000, 1000));
 
     client.resetTriggered();
@@ -4935,7 +4935,7 @@
     // Make sure we initialize to minimum scale, even if the window size
     // only becomes available after the load begins.
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.resize(WebSize(1000, 1000));
 
     client.resetTriggered();
@@ -4967,7 +4967,7 @@
     DisambiguationPopupTestWebViewClient client;
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client, nullptr, configureAndroid);
 
     WebViewImpl* webViewImpl = webViewHelper.webViewImpl();
     ASSERT_TRUE(webViewImpl);
@@ -6094,7 +6094,7 @@
     registerMockedHttpURLLoad("white-1x1.png");
     TestSameDocumentWithImageWebFrameClient client;
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "foo_with_image.html", true, &client, 0, &configureLoadsImagesAutomatically);
+    webViewHelper.initializeAndLoad(m_baseURL + "foo_with_image.html", true, &client, nullptr, nullptr, &configureLoadsImagesAutomatically);
 
     WebCache::clear();
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "foo_with_image.html");
@@ -6296,7 +6296,7 @@
     registerMockedHttpURLLoad("non-scrollable.html");
     OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
+    webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(), nullptr, &configueCompositingWebView);
 
     webViewHelper.resize(WebSize(100, 100));
     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "non-scrollable.html");
@@ -6375,7 +6375,7 @@
 {
     registerMockedHttpURLLoad("fixed-position-in-fixed-viewport.html");
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    webViewHelper.initializeAndLoad(m_baseURL + "fixed-position-in-fixed-viewport.html", true, 0, 0, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "fixed-position-in-fixed-viewport.html", true, nullptr, nullptr, nullptr, enableViewportSettings);
 
     WebView* webView = webViewHelper.webView();
     webViewHelper.resize(WebSize(100, 100));
@@ -6415,7 +6415,7 @@
     FakeCompositingWebViewClient client;
     registerMockedHttpURLLoad("long_scroll.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "long_scroll.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "long_scroll.html", true, nullptr, &client, nullptr, configureAndroid);
 
     WebViewImpl* webView = webViewHelper.webViewImpl();
     FrameView* frameView = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
@@ -6481,7 +6481,7 @@
     int viewportHeight = 480;
 
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "rtl-overview-mode.html", true, 0, &client, enableViewportSettings);
+    webViewHelper.initializeAndLoad(m_baseURL + "rtl-overview-mode.html", true, nullptr, &client, nullptr, enableViewportSettings);
     webViewHelper.webView()->setInitialPageScaleOverride(-1);
     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
     webViewHelper.webView()->settings()->setLoadWithOverviewMode(true);
@@ -6502,7 +6502,7 @@
     int viewportHeight = 480;
     client.m_screenInfo.rect.width = viewportWidth;
     client.m_screenInfo.rect.height = viewportHeight;
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_div.html", true, 0, &client, configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_div.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewImpl->updateAllLifecyclePhases();
 
@@ -6535,7 +6535,7 @@
     FrameTestHelpers::WebViewHelper webViewHelper;
     int viewportWidth = 640;
     int viewportHeight = 480;
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_div.html", true, 0, &client, configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_div.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewImpl->updateAllLifecyclePhases();
 
@@ -6573,7 +6573,7 @@
     FrameTestHelpers::WebViewHelper webViewHelper(this);
     int viewportWidth = 640;
     int viewportHeight = 480;
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_div.html", true, 0, &client, configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_div.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
     webViewImpl->updateAllLifecyclePhases();
 
@@ -6603,7 +6603,7 @@
     registerMockedHttpURLLoad("fullscreen_iframe.html");
     registerMockedHttpURLLoad("fullscreen_div.html");
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_iframe.html", true, 0, &client, configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_iframe.html", true, nullptr, &client, nullptr, configureAndroid);
     int viewportWidth = 640;
     int viewportHeight = 480;
     client.m_screenInfo.rect.width = viewportWidth;
@@ -6637,7 +6637,7 @@
     FakeCompositingWebViewClient client;
     registerMockedHttpURLLoad("viewport-tiny.html");
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "viewport-tiny.html", true, 0, &client, configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "viewport-tiny.html", true, nullptr, &client, nullptr, configureAndroid);
     int viewportWidth = 384;
     int viewportHeight = 640;
     client.m_screenInfo.rect.width = viewportWidth;
@@ -6677,7 +6677,7 @@
     FakeCompositingWebViewClient client;
     registerMockedHttpURLLoad("viewport-tiny.html");
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "viewport-tiny.html", true, 0, &client, configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "viewport-tiny.html", true, nullptr, &client, nullptr, configureAndroid);
     int viewportWidth = 384;
     int viewportHeight = 640;
     client.m_screenInfo.rect.width = viewportWidth;
@@ -6731,7 +6731,7 @@
     FakeCompositingWebViewClient client;
     registerMockedHttpURLLoad("fullscreen_restore_scale_factor.html");
     FrameTestHelpers::WebViewHelper webViewHelper(this);
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_restore_scale_factor.html", true, nullptr, &client, &configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "fullscreen_restore_scale_factor.html", true, nullptr, &client, nullptr, &configureAndroid);
     client.m_screenInfo.rect.width = screenSizeMinusStatusBarsMinusUrlBar.width;
     client.m_screenInfo.rect.height = screenSizeMinusStatusBarsMinusUrlBar.height;
     webViewHelper.resize(screenSizeMinusStatusBarsMinusUrlBar);
@@ -7841,7 +7841,7 @@
     WebLocalFrame* childFrame = FrameTestHelpers::createLocalChild(view->mainFrame()->toWebRemoteFrame());
 
     GestureEventTestWebViewClient childViewClient;
-    WebFrameWidget* widget = WebFrameWidget::create(&childViewClient, childFrame);
+    WebFrameWidget* widget = WebFrameWidget::create(childViewClient.widgetClient(), childFrame);
 
     view->resize(WebSize(1000, 1000));
 
@@ -8165,7 +8165,7 @@
     OverscrollWebViewClient client;
     registerMockedHttpURLLoad("overscroll/overscroll.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(200, 200));
 
     // Calculation of accumulatedRootOverscroll and unusedDelta on multiple scrollUpdate.
@@ -8207,7 +8207,7 @@
     OverscrollWebViewClient client;
     registerMockedHttpURLLoad("overscroll/div-overscroll.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/div-overscroll.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/div-overscroll.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(200, 200));
 
     ScrollBegin(&webViewHelper);
@@ -8250,7 +8250,7 @@
     OverscrollWebViewClient client;
     registerMockedHttpURLLoad("overscroll/div-overscroll.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/div-overscroll.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/div-overscroll.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(200, 200));
 
     ScrollBegin(&webViewHelper);
@@ -8275,7 +8275,7 @@
     registerMockedHttpURLLoad("overscroll/iframe-overscroll.html");
     registerMockedHttpURLLoad("overscroll/scrollable-iframe.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/iframe-overscroll.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/iframe-overscroll.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(200, 200));
 
     ScrollBegin(&webViewHelper);
@@ -8307,7 +8307,7 @@
     OverscrollWebViewClient client;
     registerMockedHttpURLLoad("overscroll/overscroll.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, 0, &client, configureAndroid);
+    WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(200, 200));
     webViewImpl->setPageScaleFactor(3.0);
 
@@ -8341,7 +8341,7 @@
     OverscrollWebViewClient client;
     registerMockedHttpURLLoad("overscroll/overscroll.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(200, 200));
 
     ScrollBegin(&webViewHelper);
@@ -8392,7 +8392,7 @@
     OverscrollWebViewClient client;
     registerMockedHttpURLLoad("overscroll/overscroll.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(200, 200));
 
     EXPECT_CALL(client, didOverscroll(WebFloatSize(-1000, -1000), WebFloatSize(-1000, -1000), WebFloatPoint(), WebFloatSize()));
@@ -8407,7 +8407,7 @@
     OverscrollWebViewClient client;
     registerMockedHttpURLLoad("mouse-wheel-overflow-body.html");
     FrameTestHelpers::WebViewHelper webViewHelper;
-    webViewHelper.initializeAndLoad(m_baseURL + "mouse-wheel-overflow-body.html", true, 0, &client, configureAndroid);
+    webViewHelper.initializeAndLoad(m_baseURL + "mouse-wheel-overflow-body.html", true, nullptr, &client, nullptr, configureAndroid);
     webViewHelper.resize(WebSize(800, 600));
 
     FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
@@ -8609,7 +8609,7 @@
 TEST(WebFrameGlobalReuseTest, ChildFrame)
 {
     FrameTestHelpers::WebViewHelper helper;
-    helper.initialize(true, nullptr, nullptr, enableGlobalReuseForUnownedMainFrames);
+    helper.initialize(true, nullptr, nullptr, nullptr, enableGlobalReuseForUnownedMainFrames);
 
     WebLocalFrame* mainFrame = helper.webView()->mainFrame()->toWebLocalFrame();
     FrameTestHelpers::loadFrame(mainFrame, "data:text/html,<iframe></iframe>");
@@ -8629,9 +8629,9 @@
 {
     FrameTestHelpers::TestWebViewClient openerWebViewClient;
     FrameTestHelpers::WebViewHelper openerHelper;
-    openerHelper.initialize(false, nullptr, &openerWebViewClient);
+    openerHelper.initialize(false, nullptr, &openerWebViewClient, nullptr);
     FrameTestHelpers::WebViewHelper helper;
-    helper.initializeWithOpener(openerHelper.webView()->mainFrame(), true, nullptr, nullptr, enableGlobalReuseForUnownedMainFrames);
+    helper.initializeWithOpener(openerHelper.webView()->mainFrame(), true, nullptr, nullptr, nullptr, enableGlobalReuseForUnownedMainFrames);
 
     WebLocalFrame* mainFrame = helper.webView()->mainFrame()->toWebLocalFrame();
     v8::HandleScope scope(v8::Isolate::GetCurrent());
@@ -8649,7 +8649,7 @@
 TEST(WebFrameGlobalReuseTest, ReuseForMainFrameIfEnabled)
 {
     FrameTestHelpers::WebViewHelper helper;
-    helper.initialize(true, nullptr, nullptr, enableGlobalReuseForUnownedMainFrames);
+    helper.initialize(true, nullptr, nullptr, nullptr, enableGlobalReuseForUnownedMainFrames);
 
     WebLocalFrame* mainFrame = helper.webView()->mainFrame()->toWebLocalFrame();
     v8::HandleScope scope(v8::Isolate::GetCurrent());
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
index ac776896..295b546 100644
--- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -1752,7 +1752,7 @@
 {
     OwnPtr<FrameTestHelpers::TestWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FrameTestHelpers::TestWebViewClient());
     FrameTestHelpers::WebViewHelper webViewHelper;
-    WebViewImpl* webViewImpl = webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
+    WebViewImpl* webViewImpl = webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(), nullptr, &configueCompositingWebView);
 
     int pageWidth = 640;
     int pageHeight = 480;
diff --git a/third_party/WebKit/Source/wtf/DEPS b/third_party/WebKit/Source/wtf/DEPS
index abbfb758..7062812 100644
--- a/third_party/WebKit/Source/wtf/DEPS
+++ b/third_party/WebKit/Source/wtf/DEPS
@@ -4,6 +4,7 @@
     "+base/debug",
     "+base/logging.h",
     "+base/numerics",
+    "+base/optional.h",
     "+base/rand_util.h",
     "+base/strings",
     "+base/time/time.h",
diff --git a/third_party/WebKit/Source/wtf/Optional.h b/third_party/WebKit/Source/wtf/Optional.h
index a28bd80..f522dba 100644
--- a/third_party/WebKit/Source/wtf/Optional.h
+++ b/third_party/WebKit/Source/wtf/Optional.h
@@ -5,68 +5,21 @@
 #ifndef Optional_h
 #define Optional_h
 
-#include "wtf/Alignment.h"
-#include "wtf/Allocator.h"
-#include "wtf/Assertions.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/StdLibExtras.h"
-
-#include <new>
-#include <utility>
+#include "base/optional.h"
+#include "wtf/TypeTraits.h"
 
 namespace WTF {
 
-// This is a lightweight template similar to std::experimental::optional.
-// It currently does not support assignment, swapping, comparison, etc.
+// WTF::Optional is base::Optional. See base/optional.h for documentation.
 //
-// Use this instead of OwnPtr for cases where you only want to conditionally
-// construct a "scope" object.
-//
-// Example:
-//   Optional<DrawingRecorder> recorder;
-//   if (shouldDraw)
-//       recorder.emplace(constructor, args, here);
-//   // recorder destroyed at end of scope
-//
-// It can be used in WTF::Vector.
-//
-// Note in particular that unlike a pointer, though, dereferencing a const
-// optional yields a const reference.
-
+// A clang plugin enforces that garbage collected types are not allocated
+// outside of the heap, similarly we enforce that one doesn't create garbage
+// collected types nested inside an Optional.
 template <typename T>
-class Optional final {
-    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
-    WTF_MAKE_NONCOPYABLE(Optional);
-public:
-    Optional() : m_ptr(nullptr) { }
-    ~Optional()
-    {
-        if (m_ptr)
-            m_ptr->~T();
-    }
+using Optional = typename std::enable_if<!IsGarbageCollectedType<T>::value, base::Optional<T>>::type;
 
-    typedef T* Optional::*UnspecifiedBoolType;
-    operator UnspecifiedBoolType() const { return m_ptr ? &Optional::m_ptr : nullptr; }
-
-    T& operator*() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; }
-    const T& operator*() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return *m_ptr; }
-    T* operator->() { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return m_ptr; }
-    const T* operator->() const { ASSERT_WITH_SECURITY_IMPLICATION(m_ptr); return m_ptr; }
-    T* get() { return m_ptr; }
-    const T* get() const { return m_ptr; }
-
-    template <typename... Args>
-    void emplace(Args&&... args)
-    {
-        RELEASE_ASSERT(!m_ptr);
-        m_ptr = reinterpret_cast_ptr<T*>(&m_storage.buffer);
-        new (m_ptr) T(std::forward<Args>(args)...);
-    }
-
-private:
-    T* m_ptr;
-    AlignedBuffer<sizeof(T), WTF_ALIGN_OF(T)> m_storage;
-};
+constexpr base::nullopt_t nullopt = base::nullopt;
+constexpr base::in_place_t in_place = base::in_place;
 
 } // namespace WTF
 
diff --git a/third_party/WebKit/Source/wtf/text/TextCodec.cpp b/third_party/WebKit/Source/wtf/text/TextCodec.cpp
index 191ebb5..b613f358 100644
--- a/third_party/WebKit/Source/wtf/text/TextCodec.cpp
+++ b/third_party/WebKit/Source/wtf/text/TextCodec.cpp
@@ -47,6 +47,10 @@
     case URLEncodedEntitiesForUnencodables:
         snprintf(replacement, sizeof(UnencodableReplacementArray), "%%26%%23%u%%3B", codePoint);
         return static_cast<int>(strlen(replacement));
+
+    case CSSEncodedEntitiesForUnencodables:
+        snprintf(replacement, sizeof(UnencodableReplacementArray), "\\%x ", codePoint);
+        return static_cast<int>(strlen(replacement));
     }
     ASSERT_NOT_REACHED();
     replacement[0] = 0;
diff --git a/third_party/WebKit/Source/wtf/text/TextCodec.h b/third_party/WebKit/Source/wtf/text/TextCodec.h
index 27e3128..28f547c 100644
--- a/third_party/WebKit/Source/wtf/text/TextCodec.h
+++ b/third_party/WebKit/Source/wtf/text/TextCodec.h
@@ -50,7 +50,11 @@
     // Encodes the character as en entity as above, but escaped
     // non-alphanumeric characters. This is used in URLs.
     // For example, U+6DE would be "%26%231758%3B".
-    URLEncodedEntitiesForUnencodables
+    URLEncodedEntitiesForUnencodables,
+
+    // Encodes the character as a CSS entity.  For example U+06DE
+    // would be \06de.  See: https://www.w3.org/TR/css-syntax-3/#escaping
+    CSSEncodedEntitiesForUnencodables,
 };
 
 typedef char UnencodableReplacementArray[32];
@@ -70,8 +74,7 @@
 static_assert(FetchEOF, "FetchEOF should be truthy");
 static_assert(DataEOF, "DataEOF should be truthy");
 
-
-class TextCodec {
+class WTF_EXPORT TextCodec {
     WTF_MAKE_NONCOPYABLE(TextCodec); USING_FAST_MALLOC(TextCodec);
 public:
     TextCodec() { }
diff --git a/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp b/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp
index b342359..b157bf9 100644
--- a/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp
+++ b/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp
@@ -409,22 +409,37 @@
 }
 #endif
 
-// Invalid character handler when writing escaped entities for unrepresentable
-// characters. See the declaration of TextCodec::encode for more.
-static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length,
-    UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err)
+// Generic helper for writing escaped entities using the specfied UnencodableHandling.
+static void formatEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length,
+    UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err, UnencodableHandling handling)
 {
     if (reason == UCNV_UNASSIGNED) {
         *err = U_ZERO_ERROR;
 
         UnencodableReplacementArray entity;
-        int entityLen = TextCodec::getUnencodableReplacement(codePoint, URLEncodedEntitiesForUnencodables, entity);
+        int entityLen = TextCodec::getUnencodableReplacement(codePoint, handling, entity);
         ucnv_cbFromUWriteBytes(fromUArgs, entity, entityLen, 0, err);
     } else {
         UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, reason, err);
     }
 }
 
+// Invalid character handler when writing escaped entities in CSS encoding for
+// unrepresentable characters. See the declaration of TextCodec::encode for more.
+static void cssEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length,
+    UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err)
+{
+    formatEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, reason, err, CSSEncodedEntitiesForUnencodables);
+}
+
+// Invalid character handler when writing escaped entities in HTML/XML encoding for
+// unrepresentable characters. See the declaration of TextCodec::encode for more.
+static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length,
+    UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err)
+{
+    formatEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, reason, err, URLEncodedEntitiesForUnencodables);
+}
+
 #if defined(USING_SYSTEM_ICU)
 // Substitutes special GBK characters, escaping all other unassigned entities.
 static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length,
@@ -440,6 +455,23 @@
     UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, reason, err);
 }
 
+// Combines both gbkCssEscapedEntityCallback and GBK character substitution.
+static void gbkCssEscapedEntityCallack(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length,
+    UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err)
+{
+    if (reason == UCNV_UNASSIGNED) {
+        if (UChar outChar = fallbackForGBK(codePoint)) {
+            const UChar* source = &outChar;
+            *err = U_ZERO_ERROR;
+            ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err);
+            return;
+        }
+        cssEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, reason, err);
+        return;
+    }
+    UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, reason, err);
+}
+
 // Combines both gbkUrlEscapedEntityCallback and GBK character substitution.
 static void gbkUrlEscapedEntityCallack(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length,
     UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err)
@@ -527,6 +559,13 @@
         ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkUrlEscapedEntityCallack : urlEscapedEntityCallback, 0, 0, 0, &err);
 #endif
         break;
+    case CSSEncodedEntitiesForUnencodables:
+#if !defined(USING_SYSTEM_ICU)
+        ucnv_setFromUCallBack(m_converterICU, cssEscapedEntityCallback, 0, 0, 0, &err);
+#else
+        ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkCssEscapedEntityCallack : cssEscapedEntityCallback, 0, 0, 0, &err);
+#endif
+        break;
     }
 
     ASSERT(U_SUCCESS(err));
diff --git a/third_party/WebKit/Source/wtf/text/TextCodecTest.cpp b/third_party/WebKit/Source/wtf/text/TextCodecTest.cpp
new file mode 100644
index 0000000..2541e20
--- /dev/null
+++ b/third_party/WebKit/Source/wtf/text/TextCodecTest.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "wtf/text/TextCodec.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace WTF {
+
+namespace {
+
+    TEST(TextCodec, QuestionMarkEncoding)
+    {
+        UnencodableReplacementArray replacement;
+        int size = TextCodec::getUnencodableReplacement(0xE003,
+            QuestionMarksForUnencodables,
+            replacement);
+        EXPECT_EQ(size, 1);
+        EXPECT_EQ(replacement[0], '?');
+        EXPECT_EQ(replacement[1], 0);
+    }
+
+    TEST(TextCodec, HTMLEntityEncoding)
+    {
+        UnencodableReplacementArray replacement;
+        int size = TextCodec::getUnencodableReplacement(0xE003,
+            EntitiesForUnencodables,
+            replacement);
+        EXPECT_EQ(size, 8);
+        EXPECT_EQ(std::string(replacement), "&#57347;");
+        EXPECT_EQ(replacement[8], 0);
+    }
+
+    TEST(TextCodec, URLEntityEncoding)
+    {
+        UnencodableReplacementArray replacement;
+        int size = TextCodec::getUnencodableReplacement(
+            0xE003,
+            URLEncodedEntitiesForUnencodables,
+            replacement);
+        EXPECT_EQ(size, 14);
+        EXPECT_EQ(std::string(replacement), "%26%2357347%3B");
+        EXPECT_EQ(replacement[14], 0);
+    }
+
+    TEST(TextCodec, CSSEntityEncoding)
+    {
+        UnencodableReplacementArray replacement;
+        int size = TextCodec::getUnencodableReplacement(
+            0xE003,
+            CSSEncodedEntitiesForUnencodables,
+            replacement);
+        EXPECT_EQ(size, 6);
+        EXPECT_EQ(std::string(replacement), "\\e003 ");
+        EXPECT_EQ(replacement[6], 0);
+    }
+
+} // anonymous namespace
+} // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/wtf.gypi b/third_party/WebKit/Source/wtf/wtf.gypi
index 1a65dfe..33f7a84 100644
--- a/third_party/WebKit/Source/wtf/wtf.gypi
+++ b/third_party/WebKit/Source/wtf/wtf.gypi
@@ -155,6 +155,7 @@
             'text/StringStatics.cpp',
             'text/StringUTF8Adaptor.h',
             'text/StringView.h',
+            'text/TextCodec.h',
             'text/TextCodec.cpp',
             'text/TextCodecASCIIFastPath.h',
             'text/TextCodecICU.cpp',
@@ -223,6 +224,7 @@
             'text/StringBuilderTest.cpp',
             'text/StringImplTest.cpp',
             'text/StringOperatorsTest.cpp',
+            'text/TextCodecTest.cpp',
             'text/TextCodecReplacementTest.cpp',
             'text/TextCodecUTF8Test.cpp',
             "text/UTF8Test.cpp",
diff --git a/third_party/WebKit/public/OWNERS b/third_party/WebKit/public/OWNERS
index 77161b3..99d64f69 100644
--- a/third_party/WebKit/public/OWNERS
+++ b/third_party/WebKit/public/OWNERS
@@ -10,7 +10,6 @@
 mkwst@chromium.org
 pdr@chromium.org
 pfeldman@chromium.org
-philipj@opera.com
 rbyers@chromium.org
 tkent@chromium.org
 
diff --git a/third_party/WebKit/public/platform/WebDisplayItemList.h b/third_party/WebKit/public/platform/WebDisplayItemList.h
index b71d422..99bdac3 100644
--- a/third_party/WebKit/public/platform/WebDisplayItemList.h
+++ b/third_party/WebKit/public/platform/WebDisplayItemList.h
@@ -12,16 +12,16 @@
 #include "WebSize.h"
 #include "WebVector.h"
 
-#include "third_party/skia/include/core/SkColorFilter.h"
-#include "third_party/skia/include/core/SkRRect.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "third_party/skia/include/core/SkXfermode.h"
-#include "third_party/skia/include/utils/SkMatrix44.h"
 
+class SkColorFilter;
 class SkImageFilter;
 class SkMatrix44;
 class SkPicture;
+struct SkRect;
+class SkRRect;
 
 namespace cc {
 class FilterOperations;
diff --git a/third_party/WebKit/public/web/WebDevToolsAgent.h b/third_party/WebKit/public/web/WebDevToolsAgent.h
index 4a6019e..b875655 100644
--- a/third_party/WebKit/public/web/WebDevToolsAgent.h
+++ b/third_party/WebKit/public/web/WebDevToolsAgent.h
@@ -49,7 +49,7 @@
 
     virtual void continueProgram() = 0;
 
-    virtual void dispatchOnInspectorBackend(int sessionId, const WebString& message) = 0;
+    virtual void dispatchOnInspectorBackend(int sessionId, int callId, const WebString& method, const WebString& message) = 0;
 
     virtual void inspectElementAt(const WebPoint&) = 0;
     virtual void failedToRequestDevTools() = 0;
@@ -65,7 +65,7 @@
     };
     // Asynchronously request debugger to pause immediately and run the command.
     BLINK_EXPORT static void interruptAndDispatch(int sessionId, MessageDescriptor*);
-    BLINK_EXPORT static bool shouldInterruptForMessage(const WebString&);
+    BLINK_EXPORT static bool shouldInterruptForMethod(const WebString&);
 
 };
 
diff --git a/third_party/WebKit/public/web/WebEmbeddedWorker.h b/third_party/WebKit/public/web/WebEmbeddedWorker.h
index 89fd878..4e9d753 100644
--- a/third_party/WebKit/public/web/WebEmbeddedWorker.h
+++ b/third_party/WebKit/public/web/WebEmbeddedWorker.h
@@ -67,7 +67,7 @@
     virtual void attachDevTools(const WebString& hostId, int sessionId) = 0;
     virtual void reattachDevTools(const WebString& hostId, int sessionId, const WebString& savedState) = 0;
     virtual void detachDevTools() = 0;
-    virtual void dispatchDevToolsMessage(int sessionId, const WebString&) = 0;
+    virtual void dispatchDevToolsMessage(int sessionId, int callId, const WebString& method, const WebString& message) = 0;
     virtual void addMessageToConsole(const WebConsoleMessage&) = 0;
 };
 
diff --git a/third_party/WebKit/public/web/WebFrameWidget.h b/third_party/WebKit/public/web/WebFrameWidget.h
index 72092e4..5607bbec 100644
--- a/third_party/WebKit/public/web/WebFrameWidget.h
+++ b/third_party/WebKit/public/web/WebFrameWidget.h
@@ -76,6 +76,7 @@
     // blink.
     virtual bool forSubframe() const { return true; }
     virtual void scheduleAnimation() = 0;
+    virtual WebWidgetClient* client() const = 0;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/public/web/WebSharedWorker.h b/third_party/WebKit/public/web/WebSharedWorker.h
index f4e216d4..22b25f0 100644
--- a/third_party/WebKit/public/web/WebSharedWorker.h
+++ b/third_party/WebKit/public/web/WebSharedWorker.h
@@ -67,7 +67,7 @@
     virtual void attachDevTools(const WebString& hostId, int sessionId) = 0;
     virtual void reattachDevTools(const WebString& hostId, int sessionId, const WebString& savedState) = 0;
     virtual void detachDevTools() = 0;
-    virtual void dispatchDevToolsMessage(int sessionId, const WebString&) = 0;
+    virtual void dispatchDevToolsMessage(int sessionId, int callId, const WebString& method, const WebString& message) = 0;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/public/web/WebViewClient.h b/third_party/WebKit/public/web/WebViewClient.h
index a5e2f198..e98ed97a 100644
--- a/third_party/WebKit/public/web/WebViewClient.h
+++ b/third_party/WebKit/public/web/WebViewClient.h
@@ -69,7 +69,7 @@
 // Since a WebView is a WebWidget, a WebViewClient is a WebWidgetClient.
 // Virtual inheritance allows an implementation of WebWidgetClient to be
 // easily reused as part of an implementation of WebViewClient.
-class WebViewClient : virtual public WebWidgetClient {
+class WebViewClient : protected WebWidgetClient {
 public:
     // Factory methods -----------------------------------------------------
 
@@ -270,6 +270,41 @@
     // Informs the browser that the draggable regions have been updated.
     virtual void draggableRegionsChanged() { }
 
+    // TODO(lfg): These methods are only exposed through WebViewClient while we
+    // refactor WebView to not inherit from WebWidget.
+    // WebWidgetClient overrides.
+    bool allowsBrokenNullLayerTreeView() const override { return false; }
+    void closeWidgetSoon() override {}
+    void convertViewportToWindow(WebRect* rect) override {}
+    void convertWindowToViewport(WebFloatRect* rect) override {}
+    void didAutoResize(const WebSize& newSize) override {}
+    void didChangeCursor(const WebCursorInfo&) override {}
+    void didFocus() override {}
+    void didHandleGestureEvent(const WebGestureEvent& event, bool eventCancelled) override {}
+    void didInvalidateRect(const WebRect&) override {}
+    void didMeaningfulLayout(WebMeaningfulLayout) override {}
+    void didOverscroll(const WebFloatSize& overscrollDelta, const WebFloatSize& accumulatedOverscroll, const WebFloatPoint& positionInViewport, const WebFloatSize& velocityInViewport) override {}
+    void didUpdateTextOfFocusedElementByNonUserInput() override {}
+    void hasTouchEventHandlers(bool) override {}
+    void initializeLayerTreeView() override {}
+    bool isPointerLocked() override { return false; }
+    WebLayerTreeView* layerTreeView() override { return 0; }
+    void onMouseDown(const WebNode& mouseDownNode) override {}
+    bool requestPointerLock() override { return false; }
+    void requestPointerUnlock() override {}
+    void resetInputMethod() override {}
+    WebRect rootWindowRect() override { return WebRect(); }
+    void scheduleAnimation() override {}
+    WebScreenInfo screenInfo() override { return WebScreenInfo(); }
+    void setToolTipText(const WebString&, WebTextDirection hint) override {}
+    void setTouchAction(WebTouchAction touchAction) override {}
+    void setWindowRect(const WebRect&) override {}
+    void showImeIfNeeded() override {}
+    void showUnhandledTapUIIfNeeded(const WebPoint& tappedPosition, const WebNode& tappedNode, bool pageChanged) override {}
+    void show(WebNavigationPolicy) override {}
+    WebRect windowRect() override { return WebRect(); }
+    WebRect windowResizerRect() override { return WebRect(); }
+
 protected:
     ~WebViewClient() { }
 };
diff --git a/third_party/android_protobuf/BUILD.gn b/third_party/android_protobuf/BUILD.gn
index d43a63d..c7d03b8d 100644
--- a/third_party/android_protobuf/BUILD.gn
+++ b/third_party/android_protobuf/BUILD.gn
@@ -19,7 +19,6 @@
 
       # Does not compile with sanitizers.
       "//build/config/sanitizers:default_sanitizer_flags",
-      "//build/config/sanitizers:default_sanitizer_coverage_flags",
     ]
 
     configs += [
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni
index 09e33e9..65ed90a 100644
--- a/third_party/boringssl/BUILD.generated.gni
+++ b/third_party/boringssl/BUILD.generated.gni
@@ -110,8 +110,6 @@
   "src/crypto/dh/params.c",
   "src/crypto/digest/digest.c",
   "src/crypto/digest/digests.c",
-  "src/crypto/directory_posix.c",
-  "src/crypto/directory_win.c",
   "src/crypto/dsa/dsa.c",
   "src/crypto/dsa/dsa_asn1.c",
   "src/crypto/ec/ec.c",
diff --git a/third_party/boringssl/BUILD.generated_tests.gni b/third_party/boringssl/BUILD.generated_tests.gni
index 60d1a18..75c3610 100644
--- a/third_party/boringssl/BUILD.generated_tests.gni
+++ b/third_party/boringssl/BUILD.generated_tests.gni
@@ -16,6 +16,9 @@
       "src/crypto/aes/aes_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -25,6 +28,9 @@
       "src/crypto/asn1/asn1_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -34,6 +40,9 @@
       "src/crypto/base64/base64_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -43,6 +52,9 @@
       "src/crypto/bio/bio_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -52,6 +64,9 @@
       "src/crypto/bn/bn_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -61,6 +76,9 @@
       "src/crypto/bytestring/bytestring_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -70,6 +88,9 @@
       "src/crypto/chacha/chacha_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -79,6 +100,9 @@
       "src/crypto/cipher/aead_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -88,6 +112,9 @@
       "src/crypto/cipher/cipher_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -97,6 +124,9 @@
       "src/crypto/cmac/cmac_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -106,6 +136,9 @@
       "src/crypto/constant_time_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -115,6 +148,9 @@
       "src/crypto/curve25519/ed25519_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -124,6 +160,9 @@
       "src/crypto/curve25519/spake25519_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -133,6 +172,9 @@
       "src/crypto/curve25519/x25519_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -142,6 +184,9 @@
       "src/crypto/dh/dh_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -151,6 +196,9 @@
       "src/crypto/digest/digest_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -160,6 +208,9 @@
       "src/crypto/dsa/dsa_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -169,6 +220,9 @@
       "src/crypto/ec/ec_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -178,6 +232,9 @@
       "src/crypto/ec/example_mul.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -187,6 +244,9 @@
       "src/crypto/ecdsa/ecdsa_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -196,6 +256,9 @@
       "src/crypto/err/err_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -205,6 +268,9 @@
       "src/crypto/evp/evp_extra_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -214,6 +280,9 @@
       "src/crypto/evp/evp_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -223,6 +292,9 @@
       "src/crypto/evp/pbkdf_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -232,6 +304,9 @@
       "src/crypto/hkdf/hkdf_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -241,6 +316,9 @@
       "src/crypto/hmac/hmac_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -250,6 +328,9 @@
       "src/crypto/lhash/lhash_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -259,6 +340,9 @@
       "src/crypto/modes/gcm_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -268,6 +352,9 @@
       "src/crypto/newhope/newhope_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -277,6 +364,9 @@
       "src/crypto/obj/obj_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -286,6 +376,9 @@
       "src/crypto/pkcs8/pkcs12_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -295,6 +388,9 @@
       "src/crypto/pkcs8/pkcs8_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -304,6 +400,9 @@
       "src/crypto/poly1305/poly1305_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -313,6 +412,9 @@
       "src/crypto/refcount_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -322,6 +424,9 @@
       "src/crypto/rsa/rsa_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -331,6 +436,9 @@
       "src/crypto/thread_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -340,6 +448,9 @@
       "src/crypto/x509/pkcs7_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -349,6 +460,9 @@
       "src/crypto/x509/x509_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -358,6 +472,9 @@
       "src/crypto/x509v3/tab_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -367,6 +484,9 @@
       "src/crypto/x509v3/v3name_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -376,6 +496,9 @@
       "src/ssl/pqueue/pqueue_test.c",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
@@ -385,6 +508,9 @@
       "src/ssl/ssl_test.cc",
     ]
     sources += _test_support_sources
+    if (defined(invoker.configs_exclude)) {
+      configs -= invoker.configs_exclude
+    }
     configs += invoker.configs
     deps = invoker.deps
   }
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
index 8ad626b..11e9829 100644
--- a/third_party/boringssl/BUILD.gn
+++ b/third_party/boringssl/BUILD.gn
@@ -127,7 +127,11 @@
 
 if (build_with_chromium) {
   create_tests("boringssl_tests") {
-    configs = [ ":internal_config" ]
+    configs_exclude = [ "//build/config/compiler:chromium_code" ]
+    configs = [
+      ":internal_config",
+      "//build/config/compiler:no_chromium_code",
+    ]
     deps = [
       ":boringssl",
     ]
diff --git a/third_party/boringssl/boringssl.gypi b/third_party/boringssl/boringssl.gypi
index faede5a8d..4efb2c1 100644
--- a/third_party/boringssl/boringssl.gypi
+++ b/third_party/boringssl/boringssl.gypi
@@ -145,8 +145,6 @@
       'src/crypto/dh/params.c',
       'src/crypto/digest/digest.c',
       'src/crypto/digest/digests.c',
-      'src/crypto/directory_posix.c',
-      'src/crypto/directory_win.c',
       'src/crypto/dsa/dsa.c',
       'src/crypto/dsa/dsa_asn1.c',
       'src/crypto/ec/ec.c',
diff --git a/third_party/kasko/BUILD.gn b/third_party/kasko/BUILD.gn
index 6c1fc766..603c7043 100644
--- a/third_party/kasko/BUILD.gn
+++ b/third_party/kasko/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/buildflag_header.gni")
+import("//build/config/chrome_build.gni")
 import("//third_party/kasko/kasko.gni")
 
 # GYP version: target 'kasko_features' in third_party/kasko/kasko.gyp
diff --git a/third_party/libFuzzer/BUILD.gn b/third_party/libFuzzer/BUILD.gn
index daf86c6..449114f 100644
--- a/third_party/libFuzzer/BUILD.gn
+++ b/third_party/libFuzzer/BUILD.gn
@@ -4,7 +4,8 @@
 
 source_set("libfuzzer") {
   # libfuzzer should be compiled without coverage (infinite loop in trace_cmp).
-  configs -= [ "//build/config/sanitizers:default_sanitizer_coverage_flags" ]
+  configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
+  configs += [ "//build/config/sanitizers:default_sanitizer_flags_but_coverage" ]
   sources = [
     "src/FuzzerCrossOver.cpp",
     "src/FuzzerDriver.cpp",
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium
index a7accdf..5049f9f 100644
--- a/third_party/libjingle/README.chromium
+++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@
 Name: libjingle
 URL: http://www.webrtc.org
 Version: unknown
-Revision: 12534
+Revision: 12556
 License: BSD
 License File: source/talk/COPYING
 Security Critical: yes
diff --git a/third_party/libwebm/BUILD.gn b/third_party/libwebm/BUILD.gn
index 0827b07..c21b0125 100644
--- a/third_party/libwebm/BUILD.gn
+++ b/third_party/libwebm/BUILD.gn
@@ -2,10 +2,21 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+config("libwebm_config") {
+  include_dirs = [ "./source" ]
+}
+
 source_set("libwebm") {
+  configs += [ ":libwebm_config" ]
+  public_configs = [ ":libwebm_config" ]
+
+  if (!is_win) {
+    cflags = [ "-Wno-deprecated-declarations" ]  # libwebm uses std::auto_ptr
+  }
+
   sources = [
-    "source/mkvmuxer.cpp",
-    "source/mkvmuxerutil.cpp",
-    "source/mkvwriter.cpp",
+    "source/mkvmuxer/mkvmuxer.cc",
+    "source/mkvmuxer/mkvmuxerutil.cc",
+    "source/mkvmuxer/mkvwriter.cc",
   ]
 }
diff --git a/third_party/libwebm/libwebm.gyp b/third_party/libwebm/libwebm.gyp
index 7213eca..b3188158 100644
--- a/third_party/libwebm/libwebm.gyp
+++ b/third_party/libwebm/libwebm.gyp
@@ -7,10 +7,25 @@
     {
       'target_name': 'libwebm',
       'type': 'static_library',
+      'conditions': [
+        ['OS!="win"', {
+          'cflags': [
+            '-Wno-deprecated-declarations',  # libwebm uses std::auto_ptr
+          ],
+        }],
+      ],
+      'include_dirs': [
+        './source',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          './source',
+        ],
+      },
       'sources': [
-        'source/mkvmuxer.cpp',
-        'source/mkvmuxerutil.cpp',
-        'source/mkvwriter.cpp',
+        'source/mkvmuxer/mkvmuxer.cc',
+        'source/mkvmuxer/mkvmuxerutil.cc',
+        'source/mkvmuxer/mkvwriter.cc',
       ],
     },  # target libwebm
   ]
diff --git a/third_party/mesa/BUILD.gn b/third_party/mesa/BUILD.gn
index 01e4ad42..e23f64b 100644
--- a/third_party/mesa/BUILD.gn
+++ b/third_party/mesa/BUILD.gn
@@ -745,10 +745,14 @@
     ":mesa",
     ":mesa_headers",
     ":mesa_libglslcommon",
-    "//base",  # Required for the allocator implementation.
     "//build/config/sanitizers:deps",
   ]
 
+  # Required for the allocator implementation, which is not used on Mac.
+  if (!is_mac) {
+    deps += [ "//base" ]
+  }
+
   if (is_win) {
     defines = [
       "BUILD_GL32",
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn
index e4520ec1..82116629 100644
--- a/third_party/protobuf/BUILD.gn
+++ b/third_party/protobuf/BUILD.gn
@@ -306,6 +306,10 @@
     "src/google/protobuf/wrappers.pb.h",
   ]
 
+  deps = [
+    "//build/config/sanitizers:deps",
+  ]
+
   configs -= [ "//build/config/compiler:chromium_code" ]
   configs += [
     "//build/config/compiler:no_chromium_code",
@@ -329,7 +333,10 @@
 
 # Only compile the compiler for the host architecture.
 if (current_toolchain == host_toolchain) {
-  executable("protoc") {
+  # protoc compiler is separated into protoc library and executable targets to
+  # support protoc plugins that need to link libprotoc, but not the main()
+  # itself. See src/google/protobuf/compiler/plugin.h
+  source_set("protoc_lib") {
     sources = [
       "src/google/protobuf/compiler/code_generator.cc",
       "src/google/protobuf/compiler/code_generator.h",
@@ -476,7 +483,6 @@
       "src/google/protobuf/compiler/javanano/javanano_primitive_field.h",
       "src/google/protobuf/compiler/js/js_generator.cc",
       "src/google/protobuf/compiler/js/js_generator.h",
-      "src/google/protobuf/compiler/main.cc",
       "src/google/protobuf/compiler/objectivec/objectivec_enum.cc",
       "src/google/protobuf/compiler/objectivec/objectivec_enum.h",
       "src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc",
@@ -528,16 +534,31 @@
       configs -= [ "//build/config/win:lean_and_mean" ]
     }
 
+    public_configs = [ ":protobuf_config" ]
+
+    cflags = protobuf_lite_cflags
+
+    public_deps = [
+      ":protobuf_full",
+    ]
+  }
+
+  executable("protoc") {
+    sources = [
+      "src/google/protobuf/compiler/main.cc",
+    ]
+
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+
     cflags = protobuf_lite_cflags
 
     deps = [
-      ":protobuf_full",
-      "//build/config/sanitizers:deps",
+      ":protoc_lib",
 
       # Default manifest on Windows (a no-op elsewhere).
       "//build/win:default_exe_manifest",
     ]
-    deps += [ "//build/config/sanitizers:deps" ]
   }
 }
 
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium
index 3453b84..0af6f79 100644
--- a/third_party/protobuf/README.chromium
+++ b/third_party/protobuf/README.chromium
@@ -87,3 +87,12 @@
 
   These patches uninline some functions, resulting in a significant reduction
   (somewhere between 500 KB and 1 MB) of binary size.
+- 0011-use-offsetof-for-clang.patch
+
+  This patch replaces a few invalid reinterpret_casts with __builtin_offsetof,
+  if compiled with Clang. This is a temporary patch, it should be deletd, when
+  the official github repo is updates with this changes already submitted to
+  the internal Google repo.
+
+  See also: https://crbug.com/607751 and
+  https://github.com/google/protobuf/issues/1450
diff --git a/third_party/protobuf/patches/0011-use-offsetof-for-clang.patch b/third_party/protobuf/patches/0011-use-offsetof-for-clang.patch
new file mode 100644
index 0000000..9a6e58a
--- /dev/null
+++ b/third_party/protobuf/patches/0011-use-offsetof-for-clang.patch
@@ -0,0 +1,49 @@
+diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
+index 9baaa35..0917537 100644
+--- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
++++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
+@@ -2372,8 +2372,16 @@ GenerateClear(io::Printer* printer) {
+   // positions of two fields in the Message.
+   // ZR_ zeroes a non-empty range of fields via memset.
+   const char* macros =
++      "#if defined(__clang__)\n"
++      "#define ZR_HELPER_(f) \\\n"
++      "  _Pragma(\"clang diagnostic push\") \\\n"
++      "  _Pragma(\"clang diagnostic ignored \\\"-Winvalid-offsetof\\\"\") \\\n"
++      "  __builtin_offsetof($classname$, f) \\\n"
++      "  _Pragma(\"clang diagnostic pop\")\n"
++      "#else\n"
+       "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
+-      "  &reinterpret_cast<$classname$*>(16)->f)\n\n"
++      "  &reinterpret_cast<$classname$*>(16)->f)\n"
++      "#endif\n\n"
+       "#define ZR_(first, last) do {\\\n"
+       "  ::memset(&first, 0,\\\n"
+       "           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
+diff --git a/third_party/protobuf/src/google/protobuf/generated_message_reflection.h b/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
+index 9ef7871..b26bbbc 100644
+--- a/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
++++ b/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
+@@ -587,11 +587,22 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
+ // just use zero, GCC complains about dereferencing a NULL pointer.  We
+ // choose 16 rather than some other number just in case the compiler would
+ // be confused by an unaligned pointer.
++#if defined(__clang__)
++// For Clang we use __builtin_offsetof() and suppress the warning,
++// to avoid Control Flow Integrity and UBSan vptr sanitizers from
++// crashing while trying to validate the invalid reinterpet_casts.
++#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
++  _Pragma("clang diagnostic push")                            \
++  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"")  \
++  __builtin_offsetof(TYPE, FIELD)                             \
++  _Pragma("clang diagnostic pop")
++#else
+ #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
+   static_cast<int>(                                           \
+       reinterpret_cast<const char*>(                          \
+           &reinterpret_cast<const TYPE*>(16)->FIELD) -        \
+       reinterpret_cast<const char*>(16))
++#endif
+ 
+ #define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD)     \
+   static_cast<int>(                                                   \
diff --git a/third_party/protobuf/protobuf.gyp b/third_party/protobuf/protobuf.gyp
index 38ad1aad..e77e179 100644
--- a/third_party/protobuf/protobuf.gyp
+++ b/third_party/protobuf/protobuf.gyp
@@ -246,206 +246,219 @@
           ],
         },
         {
+          'target_name': 'protoc_lib',
+          'type': 'static_library',
+          'toolsets': ['host'],
+          'sources': [
+            "src/google/protobuf/compiler/code_generator.cc",
+            "src/google/protobuf/compiler/code_generator.h",
+            "src/google/protobuf/compiler/command_line_interface.cc",
+            "src/google/protobuf/compiler/command_line_interface.h",
+            "src/google/protobuf/compiler/cpp/cpp_enum.cc",
+            "src/google/protobuf/compiler/cpp/cpp_enum.h",
+            "src/google/protobuf/compiler/cpp/cpp_enum_field.cc",
+            "src/google/protobuf/compiler/cpp/cpp_enum_field.h",
+            "src/google/protobuf/compiler/cpp/cpp_extension.cc",
+            "src/google/protobuf/compiler/cpp/cpp_extension.h",
+            "src/google/protobuf/compiler/cpp/cpp_field.cc",
+            "src/google/protobuf/compiler/cpp/cpp_field.h",
+            "src/google/protobuf/compiler/cpp/cpp_file.cc",
+            "src/google/protobuf/compiler/cpp/cpp_file.h",
+            "src/google/protobuf/compiler/cpp/cpp_generator.cc",
+            "src/google/protobuf/compiler/cpp/cpp_generator.h",
+            "src/google/protobuf/compiler/cpp/cpp_helpers.cc",
+            "src/google/protobuf/compiler/cpp/cpp_helpers.h",
+            "src/google/protobuf/compiler/cpp/cpp_map_field.cc",
+            "src/google/protobuf/compiler/cpp/cpp_map_field.h",
+            "src/google/protobuf/compiler/cpp/cpp_message.cc",
+            "src/google/protobuf/compiler/cpp/cpp_message.h",
+            "src/google/protobuf/compiler/cpp/cpp_message_field.cc",
+            "src/google/protobuf/compiler/cpp/cpp_message_field.h",
+            "src/google/protobuf/compiler/cpp/cpp_options.h",
+            "src/google/protobuf/compiler/cpp/cpp_primitive_field.cc",
+            "src/google/protobuf/compiler/cpp/cpp_primitive_field.h",
+            "src/google/protobuf/compiler/cpp/cpp_service.cc",
+            "src/google/protobuf/compiler/cpp/cpp_service.h",
+            "src/google/protobuf/compiler/cpp/cpp_string_field.cc",
+            "src/google/protobuf/compiler/cpp/cpp_string_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_doc_comment.cc",
+            "src/google/protobuf/compiler/csharp/csharp_doc_comment.h",
+            "src/google/protobuf/compiler/csharp/csharp_enum.cc",
+            "src/google/protobuf/compiler/csharp/csharp_enum.h",
+            "src/google/protobuf/compiler/csharp/csharp_enum_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_enum_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_field_base.cc",
+            "src/google/protobuf/compiler/csharp/csharp_field_base.h",
+            "src/google/protobuf/compiler/csharp/csharp_generator.cc",
+            "src/google/protobuf/compiler/csharp/csharp_generator.h",
+            "src/google/protobuf/compiler/csharp/csharp_helpers.cc",
+            "src/google/protobuf/compiler/csharp/csharp_helpers.h",
+            "src/google/protobuf/compiler/csharp/csharp_map_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_map_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_message.cc",
+            "src/google/protobuf/compiler/csharp/csharp_message.h",
+            "src/google/protobuf/compiler/csharp/csharp_message_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_message_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_primitive_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_primitive_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_reflection_class.cc",
+            "src/google/protobuf/compiler/csharp/csharp_reflection_class.h",
+            "src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h",
+            "src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc",
+            "src/google/protobuf/compiler/csharp/csharp_source_generator_base.h",
+            "src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc",
+            "src/google/protobuf/compiler/csharp/csharp_wrapper_field.h",
+            "src/google/protobuf/compiler/java/java_context.cc",
+            "src/google/protobuf/compiler/java/java_context.h",
+            "src/google/protobuf/compiler/java/java_doc_comment.cc",
+            "src/google/protobuf/compiler/java/java_doc_comment.h",
+            "src/google/protobuf/compiler/java/java_enum.cc",
+            "src/google/protobuf/compiler/java/java_enum.h",
+            "src/google/protobuf/compiler/java/java_enum_field.cc",
+            "src/google/protobuf/compiler/java/java_enum_field.h",
+            "src/google/protobuf/compiler/java/java_enum_field_lite.cc",
+            "src/google/protobuf/compiler/java/java_enum_field_lite.h",
+            "src/google/protobuf/compiler/java/java_enum_lite.cc",
+            "src/google/protobuf/compiler/java/java_enum_lite.h",
+            "src/google/protobuf/compiler/java/java_extension.cc",
+            "src/google/protobuf/compiler/java/java_extension.h",
+            "src/google/protobuf/compiler/java/java_field.cc",
+            "src/google/protobuf/compiler/java/java_field.h",
+            "src/google/protobuf/compiler/java/java_file.cc",
+            "src/google/protobuf/compiler/java/java_file.h",
+            "src/google/protobuf/compiler/java/java_generator.cc",
+            "src/google/protobuf/compiler/java/java_generator.h",
+            "src/google/protobuf/compiler/java/java_generator_factory.cc",
+            "src/google/protobuf/compiler/java/java_generator_factory.h",
+            "src/google/protobuf/compiler/java/java_helpers.cc",
+            "src/google/protobuf/compiler/java/java_helpers.h",
+            "src/google/protobuf/compiler/java/java_lazy_message_field.cc",
+            "src/google/protobuf/compiler/java/java_lazy_message_field.h",
+            "src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc",
+            "src/google/protobuf/compiler/java/java_lazy_message_field_lite.h",
+            "src/google/protobuf/compiler/java/java_map_field.cc",
+            "src/google/protobuf/compiler/java/java_map_field.h",
+            "src/google/protobuf/compiler/java/java_map_field_lite.cc",
+            "src/google/protobuf/compiler/java/java_map_field_lite.h",
+            "src/google/protobuf/compiler/java/java_message.cc",
+            "src/google/protobuf/compiler/java/java_message.h",
+            "src/google/protobuf/compiler/java/java_message_builder.cc",
+            "src/google/protobuf/compiler/java/java_message_builder.h",
+            "src/google/protobuf/compiler/java/java_message_builder_lite.cc",
+            "src/google/protobuf/compiler/java/java_message_builder_lite.h",
+            "src/google/protobuf/compiler/java/java_message_field.cc",
+            "src/google/protobuf/compiler/java/java_message_field.h",
+            "src/google/protobuf/compiler/java/java_message_field_lite.cc",
+            "src/google/protobuf/compiler/java/java_message_field_lite.h",
+            "src/google/protobuf/compiler/java/java_message_lite.cc",
+            "src/google/protobuf/compiler/java/java_message_lite.h",
+            "src/google/protobuf/compiler/java/java_name_resolver.cc",
+            "src/google/protobuf/compiler/java/java_name_resolver.h",
+            "src/google/protobuf/compiler/java/java_primitive_field.cc",
+            "src/google/protobuf/compiler/java/java_primitive_field.h",
+            "src/google/protobuf/compiler/java/java_primitive_field_lite.cc",
+            "src/google/protobuf/compiler/java/java_primitive_field_lite.h",
+            "src/google/protobuf/compiler/java/java_service.cc",
+            "src/google/protobuf/compiler/java/java_service.h",
+            "src/google/protobuf/compiler/java/java_shared_code_generator.cc",
+            "src/google/protobuf/compiler/java/java_shared_code_generator.h",
+            "src/google/protobuf/compiler/java/java_string_field.cc",
+            "src/google/protobuf/compiler/java/java_string_field.h",
+            "src/google/protobuf/compiler/java/java_string_field_lite.cc",
+            "src/google/protobuf/compiler/java/java_string_field_lite.h",
+            "src/google/protobuf/compiler/javanano/javanano_enum.cc",
+            "src/google/protobuf/compiler/javanano/javanano_enum.h",
+            "src/google/protobuf/compiler/javanano/javanano_enum_field.cc",
+            "src/google/protobuf/compiler/javanano/javanano_enum_field.h",
+            "src/google/protobuf/compiler/javanano/javanano_extension.cc",
+            "src/google/protobuf/compiler/javanano/javanano_extension.h",
+            "src/google/protobuf/compiler/javanano/javanano_field.cc",
+            "src/google/protobuf/compiler/javanano/javanano_field.h",
+            "src/google/protobuf/compiler/javanano/javanano_file.cc",
+            "src/google/protobuf/compiler/javanano/javanano_file.h",
+            "src/google/protobuf/compiler/javanano/javanano_generator.cc",
+            "src/google/protobuf/compiler/javanano/javanano_generator.h",
+            "src/google/protobuf/compiler/javanano/javanano_helpers.cc",
+            "src/google/protobuf/compiler/javanano/javanano_helpers.h",
+            "src/google/protobuf/compiler/javanano/javanano_map_field.cc",
+            "src/google/protobuf/compiler/javanano/javanano_map_field.h",
+            "src/google/protobuf/compiler/javanano/javanano_message.cc",
+            "src/google/protobuf/compiler/javanano/javanano_message.h",
+            "src/google/protobuf/compiler/javanano/javanano_message_field.cc",
+            "src/google/protobuf/compiler/javanano/javanano_message_field.h",
+            "src/google/protobuf/compiler/javanano/javanano_primitive_field.cc",
+            "src/google/protobuf/compiler/javanano/javanano_primitive_field.h",
+            "src/google/protobuf/compiler/js/js_generator.cc",
+            "src/google/protobuf/compiler/js/js_generator.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_enum.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_enum.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_enum_field.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_extension.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_extension.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_field.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_field.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_file.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_file.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_generator.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_generator.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_helpers.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_helpers.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_map_field.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_map_field.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_message.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_message.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_message_field.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_message_field.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_oneof.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_oneof.h",
+            "src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc",
+            "src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h",
+            "src/google/protobuf/compiler/plugin.cc",
+            "src/google/protobuf/compiler/plugin.h",
+            "src/google/protobuf/compiler/plugin.pb.cc",
+            "src/google/protobuf/compiler/plugin.pb.h",
+            "src/google/protobuf/compiler/python/python_generator.cc",
+            "src/google/protobuf/compiler/python/python_generator.h",
+            "src/google/protobuf/compiler/ruby/ruby_generator.cc",
+            "src/google/protobuf/compiler/ruby/ruby_generator.h",
+            "src/google/protobuf/compiler/subprocess.cc",
+            "src/google/protobuf/compiler/subprocess.h",
+            "src/google/protobuf/compiler/zip_writer.cc",
+            "src/google/protobuf/compiler/zip_writer.h",
+          ],
+          'variables': {
+            'clang_warning_flags': [
+              # protobuf-3 contains a few functions that are unused.
+              '-Wno-unused-function',
+            ],
+          },
+          'dependencies': [
+            'protobuf_full_do_not_use',
+          ],
+          'include_dirs': [
+            'src',
+          ],
+        },
+        {
           'target_name': 'protoc',
           'conditions': [
             ['OS!="ios" or "<(GENERATOR)"!="xcode" or "<(GENERATOR_FLAVOR)"=="ninja"', {
               'type': 'executable',
               'toolsets': ['host'],
               'sources': [
-                "src/google/protobuf/compiler/code_generator.cc",
-                "src/google/protobuf/compiler/code_generator.h",
-                "src/google/protobuf/compiler/command_line_interface.cc",
-                "src/google/protobuf/compiler/command_line_interface.h",
-                "src/google/protobuf/compiler/cpp/cpp_enum.cc",
-                "src/google/protobuf/compiler/cpp/cpp_enum.h",
-                "src/google/protobuf/compiler/cpp/cpp_enum_field.cc",
-                "src/google/protobuf/compiler/cpp/cpp_enum_field.h",
-                "src/google/protobuf/compiler/cpp/cpp_extension.cc",
-                "src/google/protobuf/compiler/cpp/cpp_extension.h",
-                "src/google/protobuf/compiler/cpp/cpp_field.cc",
-                "src/google/protobuf/compiler/cpp/cpp_field.h",
-                "src/google/protobuf/compiler/cpp/cpp_file.cc",
-                "src/google/protobuf/compiler/cpp/cpp_file.h",
-                "src/google/protobuf/compiler/cpp/cpp_generator.cc",
-                "src/google/protobuf/compiler/cpp/cpp_generator.h",
-                "src/google/protobuf/compiler/cpp/cpp_helpers.cc",
-                "src/google/protobuf/compiler/cpp/cpp_helpers.h",
-                "src/google/protobuf/compiler/cpp/cpp_map_field.cc",
-                "src/google/protobuf/compiler/cpp/cpp_map_field.h",
-                "src/google/protobuf/compiler/cpp/cpp_message.cc",
-                "src/google/protobuf/compiler/cpp/cpp_message.h",
-                "src/google/protobuf/compiler/cpp/cpp_message_field.cc",
-                "src/google/protobuf/compiler/cpp/cpp_message_field.h",
-                "src/google/protobuf/compiler/cpp/cpp_options.h",
-                "src/google/protobuf/compiler/cpp/cpp_primitive_field.cc",
-                "src/google/protobuf/compiler/cpp/cpp_primitive_field.h",
-                "src/google/protobuf/compiler/cpp/cpp_service.cc",
-                "src/google/protobuf/compiler/cpp/cpp_service.h",
-                "src/google/protobuf/compiler/cpp/cpp_string_field.cc",
-                "src/google/protobuf/compiler/cpp/cpp_string_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_doc_comment.cc",
-                "src/google/protobuf/compiler/csharp/csharp_doc_comment.h",
-                "src/google/protobuf/compiler/csharp/csharp_enum.cc",
-                "src/google/protobuf/compiler/csharp/csharp_enum.h",
-                "src/google/protobuf/compiler/csharp/csharp_enum_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_enum_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_field_base.cc",
-                "src/google/protobuf/compiler/csharp/csharp_field_base.h",
-                "src/google/protobuf/compiler/csharp/csharp_generator.cc",
-                "src/google/protobuf/compiler/csharp/csharp_generator.h",
-                "src/google/protobuf/compiler/csharp/csharp_helpers.cc",
-                "src/google/protobuf/compiler/csharp/csharp_helpers.h",
-                "src/google/protobuf/compiler/csharp/csharp_map_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_map_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_message.cc",
-                "src/google/protobuf/compiler/csharp/csharp_message.h",
-                "src/google/protobuf/compiler/csharp/csharp_message_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_message_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_primitive_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_primitive_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_reflection_class.cc",
-                "src/google/protobuf/compiler/csharp/csharp_reflection_class.h",
-                "src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h",
-                "src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc",
-                "src/google/protobuf/compiler/csharp/csharp_source_generator_base.h",
-                "src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc",
-                "src/google/protobuf/compiler/csharp/csharp_wrapper_field.h",
-                "src/google/protobuf/compiler/java/java_context.cc",
-                "src/google/protobuf/compiler/java/java_context.h",
-                "src/google/protobuf/compiler/java/java_doc_comment.cc",
-                "src/google/protobuf/compiler/java/java_doc_comment.h",
-                "src/google/protobuf/compiler/java/java_enum.cc",
-                "src/google/protobuf/compiler/java/java_enum.h",
-                "src/google/protobuf/compiler/java/java_enum_field.cc",
-                "src/google/protobuf/compiler/java/java_enum_field.h",
-                "src/google/protobuf/compiler/java/java_enum_field_lite.cc",
-                "src/google/protobuf/compiler/java/java_enum_field_lite.h",
-                "src/google/protobuf/compiler/java/java_enum_lite.cc",
-                "src/google/protobuf/compiler/java/java_enum_lite.h",
-                "src/google/protobuf/compiler/java/java_extension.cc",
-                "src/google/protobuf/compiler/java/java_extension.h",
-                "src/google/protobuf/compiler/java/java_field.cc",
-                "src/google/protobuf/compiler/java/java_field.h",
-                "src/google/protobuf/compiler/java/java_file.cc",
-                "src/google/protobuf/compiler/java/java_file.h",
-                "src/google/protobuf/compiler/java/java_generator.cc",
-                "src/google/protobuf/compiler/java/java_generator.h",
-                "src/google/protobuf/compiler/java/java_generator_factory.cc",
-                "src/google/protobuf/compiler/java/java_generator_factory.h",
-                "src/google/protobuf/compiler/java/java_helpers.cc",
-                "src/google/protobuf/compiler/java/java_helpers.h",
-                "src/google/protobuf/compiler/java/java_lazy_message_field.cc",
-                "src/google/protobuf/compiler/java/java_lazy_message_field.h",
-                "src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc",
-                "src/google/protobuf/compiler/java/java_lazy_message_field_lite.h",
-                "src/google/protobuf/compiler/java/java_map_field.cc",
-                "src/google/protobuf/compiler/java/java_map_field.h",
-                "src/google/protobuf/compiler/java/java_map_field_lite.cc",
-                "src/google/protobuf/compiler/java/java_map_field_lite.h",
-                "src/google/protobuf/compiler/java/java_message.cc",
-                "src/google/protobuf/compiler/java/java_message.h",
-                "src/google/protobuf/compiler/java/java_message_builder.cc",
-                "src/google/protobuf/compiler/java/java_message_builder.h",
-                "src/google/protobuf/compiler/java/java_message_builder_lite.cc",
-                "src/google/protobuf/compiler/java/java_message_builder_lite.h",
-                "src/google/protobuf/compiler/java/java_message_field.cc",
-                "src/google/protobuf/compiler/java/java_message_field.h",
-                "src/google/protobuf/compiler/java/java_message_field_lite.cc",
-                "src/google/protobuf/compiler/java/java_message_field_lite.h",
-                "src/google/protobuf/compiler/java/java_message_lite.cc",
-                "src/google/protobuf/compiler/java/java_message_lite.h",
-                "src/google/protobuf/compiler/java/java_name_resolver.cc",
-                "src/google/protobuf/compiler/java/java_name_resolver.h",
-                "src/google/protobuf/compiler/java/java_primitive_field.cc",
-                "src/google/protobuf/compiler/java/java_primitive_field.h",
-                "src/google/protobuf/compiler/java/java_primitive_field_lite.cc",
-                "src/google/protobuf/compiler/java/java_primitive_field_lite.h",
-                "src/google/protobuf/compiler/java/java_service.cc",
-                "src/google/protobuf/compiler/java/java_service.h",
-                "src/google/protobuf/compiler/java/java_shared_code_generator.cc",
-                "src/google/protobuf/compiler/java/java_shared_code_generator.h",
-                "src/google/protobuf/compiler/java/java_string_field.cc",
-                "src/google/protobuf/compiler/java/java_string_field.h",
-                "src/google/protobuf/compiler/java/java_string_field_lite.cc",
-                "src/google/protobuf/compiler/java/java_string_field_lite.h",
-                "src/google/protobuf/compiler/javanano/javanano_enum.cc",
-                "src/google/protobuf/compiler/javanano/javanano_enum.h",
-                "src/google/protobuf/compiler/javanano/javanano_enum_field.cc",
-                "src/google/protobuf/compiler/javanano/javanano_enum_field.h",
-                "src/google/protobuf/compiler/javanano/javanano_extension.cc",
-                "src/google/protobuf/compiler/javanano/javanano_extension.h",
-                "src/google/protobuf/compiler/javanano/javanano_field.cc",
-                "src/google/protobuf/compiler/javanano/javanano_field.h",
-                "src/google/protobuf/compiler/javanano/javanano_file.cc",
-                "src/google/protobuf/compiler/javanano/javanano_file.h",
-                "src/google/protobuf/compiler/javanano/javanano_generator.cc",
-                "src/google/protobuf/compiler/javanano/javanano_generator.h",
-                "src/google/protobuf/compiler/javanano/javanano_helpers.cc",
-                "src/google/protobuf/compiler/javanano/javanano_helpers.h",
-                "src/google/protobuf/compiler/javanano/javanano_map_field.cc",
-                "src/google/protobuf/compiler/javanano/javanano_map_field.h",
-                "src/google/protobuf/compiler/javanano/javanano_message.cc",
-                "src/google/protobuf/compiler/javanano/javanano_message.h",
-                "src/google/protobuf/compiler/javanano/javanano_message_field.cc",
-                "src/google/protobuf/compiler/javanano/javanano_message_field.h",
-                "src/google/protobuf/compiler/javanano/javanano_primitive_field.cc",
-                "src/google/protobuf/compiler/javanano/javanano_primitive_field.h",
-                "src/google/protobuf/compiler/js/js_generator.cc",
-                "src/google/protobuf/compiler/js/js_generator.h",
                 "src/google/protobuf/compiler/main.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_enum.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_enum.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_enum_field.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_extension.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_extension.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_field.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_field.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_file.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_file.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_generator.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_generator.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_helpers.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_helpers.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_map_field.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_map_field.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_message.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_message.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_message_field.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_message_field.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_oneof.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_oneof.h",
-                "src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc",
-                "src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h",
-                "src/google/protobuf/compiler/plugin.cc",
-                "src/google/protobuf/compiler/plugin.h",
-                "src/google/protobuf/compiler/plugin.pb.cc",
-                "src/google/protobuf/compiler/plugin.pb.h",
-                "src/google/protobuf/compiler/python/python_generator.cc",
-                "src/google/protobuf/compiler/python/python_generator.h",
-                "src/google/protobuf/compiler/ruby/ruby_generator.cc",
-                "src/google/protobuf/compiler/ruby/ruby_generator.h",
-                "src/google/protobuf/compiler/subprocess.cc",
-                "src/google/protobuf/compiler/subprocess.h",
-                "src/google/protobuf/compiler/zip_writer.cc",
-                "src/google/protobuf/compiler/zip_writer.h",
               ],
-              'variables': {
-                'clang_warning_flags': [
-                  # protobuf-3 contains a few functions that are unused.
-                  '-Wno-unused-function',
-                ],
-              },
               'dependencies': [
-                'protobuf_full_do_not_use',
+                'protoc_lib',
               ],
               'include_dirs': [
-                'src/src',
+                'src',
               ],
             }, {  # else, OS=="ios" and "<(GENERATOR)"=="xcode" and "<(GENERATOR_FLAVOR)"!="ninja"
               'type': 'none',
diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
index 9baaa35..0917537 100644
--- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -2372,8 +2372,16 @@
   // positions of two fields in the Message.
   // ZR_ zeroes a non-empty range of fields via memset.
   const char* macros =
+      "#if defined(__clang__)\n"
+      "#define ZR_HELPER_(f) \\\n"
+      "  _Pragma(\"clang diagnostic push\") \\\n"
+      "  _Pragma(\"clang diagnostic ignored \\\"-Winvalid-offsetof\\\"\") \\\n"
+      "  __builtin_offsetof($classname$, f) \\\n"
+      "  _Pragma(\"clang diagnostic pop\")\n"
+      "#else\n"
       "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
-      "  &reinterpret_cast<$classname$*>(16)->f)\n\n"
+      "  &reinterpret_cast<$classname$*>(16)->f)\n"
+      "#endif\n\n"
       "#define ZR_(first, last) do {\\\n"
       "  ::memset(&first, 0,\\\n"
       "           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
diff --git a/third_party/protobuf/src/google/protobuf/generated_message_reflection.h b/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
index 9ef78710..b26bbbc8 100644
--- a/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
+++ b/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
@@ -587,11 +587,22 @@
 // just use zero, GCC complains about dereferencing a NULL pointer.  We
 // choose 16 rather than some other number just in case the compiler would
 // be confused by an unaligned pointer.
+#if defined(__clang__)
+// For Clang we use __builtin_offsetof() and suppress the warning,
+// to avoid Control Flow Integrity and UBSan vptr sanitizers from
+// crashing while trying to validate the invalid reinterpet_casts.
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
+  _Pragma("clang diagnostic push")                            \
+  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"")  \
+  __builtin_offsetof(TYPE, FIELD)                             \
+  _Pragma("clang diagnostic pop")
+#else
 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
   static_cast<int>(                                           \
       reinterpret_cast<const char*>(                          \
           &reinterpret_cast<const TYPE*>(16)->FIELD) -        \
       reinterpret_cast<const char*>(16))
+#endif
 
 #define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD)     \
   static_cast<int>(                                                   \
diff --git a/third_party/qcms/README.chromium b/third_party/qcms/README.chromium
index a62e37d..b19c0058 100644
--- a/third_party/qcms/README.chromium
+++ b/third_party/qcms/README.chromium
@@ -153,6 +153,10 @@
    - https://bugs.chromium.org/p/chromium/issues/detail?id=600338
  - Make build_output_lut output 4096 points for parametric curves
    - https://bugs.chromium.org/p/chromium/issues/detail?id=600338
+ - Use a static table in build_output_lut to invert para curves
+   - https://bugs.chromium.org/p/chromium/issues/detail?id=600338
+ - Make qcms_test_output_trc handle normal gamma curves
+   - https://bugs.chromium.org/p/chromium/issues/detail?id=600338
 
 For the Chromium changes, since the import, in a patch format run:
   git diff b8456f38 src
diff --git a/third_party/qcms/src/tests/qcms_test_output_trc.c b/third_party/qcms/src/tests/qcms_test_output_trc.c
index 771033f7..049141b 100644
--- a/third_party/qcms/src/tests/qcms_test_output_trc.c
+++ b/third_party/qcms/src/tests/qcms_test_output_trc.c
@@ -94,28 +94,28 @@
         const char *out_path,
         const int force_software)
 {
+    uint16_t *gamma_table_out = NULL;
+    size_t output_size = 0;
     qcms_profile *profile;
-    uint16_t *gamma_table_out;
-    size_t output_size;
+    long time_stamp = (long)time(NULL);
+    char output_file_name[1024];
+    float scale_factor;
     size_t i;
 
-    printf("Test qcms output gamma curve table integrity.\n");
-
     if (!in_path) {
         fprintf(stderr, "%s: please provide valid ICC profiles via -i option\n", __FUNCTION__);
         return EXIT_FAILURE;
     }
 
-    // Create profiles and transforms, get table and then free resources to make sure none
-    // of the internal tables are initialized by previous calls.
-    gamma_table_out = NULL;
-    output_size = 0;
+    printf("Test color profile gamma curves\n");
+    fflush(stdout);
+
     if (get_output_gamma_table(in_path, &gamma_table_out, &output_size) != 0) {
         fprintf(stderr, "Unable to extract output gamma table\n");
         return EXIT_FAILURE;
     }
 
-    printf("Output gamma LUT size = %zu\n", output_size);
+    printf("Output gamma table size = %zu\n", output_size);
 
     profile = qcms_profile_from_path(in_path);
     if (!profile) {
@@ -124,61 +124,118 @@
         return EXIT_FAILURE;
     }
 
-    // Check only for red curve for now.
     if (profile->redTRC->type == PARAMETRIC_CURVE_TYPE) {
+        // Check the red TRC curve only for now.
         int type = - (int)(profile->redTRC->count + 1);
         uint16_t *gamma_table_in = NULL;
         size_t input_size = 0;
-        float scale_factor;
         FILE *output_file;
-        char output_file_name[1024];
-        long int time_stamp = (long int)time(NULL);
 
         printf("Detected parametric curve type = %d\n", profile->redTRC->count);
 
-        sprintf(output_file_name, "qcms-test-%ld-parametric-gamma-output-%s.csv", time_stamp, profile->description);
+        if (get_input_gamma_table(in_path, &gamma_table_in, &input_size) != 0) {
+            fprintf(stderr, "Failed to compute input gamma table\n");
+            qcms_profile_release(profile);
+            free(gamma_table_out);
+            return EXIT_FAILURE;
+        }
+
+        // Write output to stdout and tables into a csv file.
+        sprintf(output_file_name, "qcms-test-%ld-parametric-gamma-output-%s.csv",
+                time_stamp, profile->description);
         printf("Writing output gamma tables to %s\n", output_file_name);
+        output_file = fopen(output_file_name, "w");
+
+        printf("Parametric gamma values for profile %s description [%s]\n",
+               in_path, profile->description);
+        fprintf(output_file, "Parametric gamma values for profile %s description [%s]\n",
+                in_path, profile->description);
 
         printf("gamma = %.6f, a = %.6f, b = %.6f, c = %.6f, d = %.6f, e = %.6f, f = %.6f\n",
                 profile->redTRC->parameter[0], profile->redTRC->parameter[1], profile->redTRC->parameter[2],
                 profile->redTRC->parameter[3], profile->redTRC->parameter[4], profile->redTRC->parameter[5],
                 profile->redTRC->parameter[6]);
 
-        // Write output to stdout and tables into a csv file.
-        output_file = fopen(output_file_name, "w");
-        fprintf(output_file, "Parametric gamma values for %s\n", profile->description);
         fprintf(output_file, "gamma, a, b, c, d, e, f\n");
         fprintf(output_file, "%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f\n",
                 profile->redTRC->parameter[0], profile->redTRC->parameter[1], profile->redTRC->parameter[2],
                 profile->redTRC->parameter[3], profile->redTRC->parameter[4], profile->redTRC->parameter[5],
                 profile->redTRC->parameter[6]);
 
-        get_input_gamma_table(in_path, &gamma_table_in, &input_size);
-        if (!gamma_table_in) {
-            fprintf(stderr, "Unable to compute input trc. Aborting\n");
-            fclose(output_file);
+        fprintf(output_file, "\nInput curve size: %zu", input_size);
+        fprintf(output_file, "\nOutput curve size: %zu", output_size);
+
+        fprintf(output_file, "\n\nInput gamma, Output gamma, LCMS Output gamma, Output gamma error\n");
+        // Output gamma curve down-sample factor.
+        scale_factor = (float)(output_size - 1) / (input_size - 1);
+
+        for (i = 0; i < input_size; ++i) {
+            float input = gamma_table_in[i * 4] * inverse65535;
+            size_t out_index = (size_t)floor(i * scale_factor + 0.5);
+            float output = gamma_table_out[out_index * 4] * inverse65535;
+            float x = out_index / (float)(output_size - 1);
+            float reference = clamp_float(evaluate_parametric_curve(type, profile->redTRC->parameter, x));
+            float difference = fabs(output - reference);
+
+            fprintf(output_file, "%.6f, %.6f, %6f, %6f\n", input, output, reference, difference);
+        }
+
+        fprintf(output_file, "\nNote: the output gamma curves are down-sampled by a factor of %zu / %zu\n",
+                output_size, input_size);
+
+        fclose(output_file);
+        free(gamma_table_in);
+    } else {
+        uint16_t *gamma_table_in = NULL;
+        size_t input_size = 0;
+        FILE *output_file;
+
+        if (get_input_gamma_table(in_path, &gamma_table_in, &input_size) != 0) {
+            fprintf(stderr, "Failed to compute input gamma table\n");
             qcms_profile_release(profile);
             free(gamma_table_out);
             return EXIT_FAILURE;
         }
 
-        scale_factor = (float)(output_size - 1) / (input_size - 1);
+        // Write output to stdout and tables into a csv file.
+        sprintf(output_file_name, "qcms-test-%ld-gamma-output-%s.csv",
+                time_stamp, profile->description);
+        printf("Writing gamma tables to %s\n", output_file_name);
+        output_file = fopen(output_file_name, "w");
 
-        fprintf(output_file, "\nInput curve size: %zu\nOutput curve size: %zu\n", input_size, output_size);
-        fprintf(output_file, "\n\nInput gamma, Output gamma, LCMS Output gamma, Output gamma error\n");
+        printf("Gamma values for profile %s description [%s]\n",
+               in_path, profile->description);
+        fprintf(output_file, "Gamma values for profile %s description [%s]\n",
+                in_path, profile->description);
+
+        if (profile->redTRC->count == 0) {
+            printf("Gamma LUT type 0: linear gamma\n");
+            fprintf(output_file, "Gamma LUT type 0: linear gamma\n");
+        } else if (profile->redTRC->count == 1) {
+            float gamma = profile->redTRC->data[0] / 256.0f;
+            printf("Gamma LUT type 1: gamma = %.6f\n", gamma);
+            fprintf(output_file, "Gamma LUT type 1: gamma = %.6f\n", gamma);
+        } else {
+            printf("Gamma LUT table size = %u\n", profile->redTRC->count);
+            fprintf(output_file, "Gamma LUT table size = %u\n", profile->redTRC->count);
+        }
+
+        fprintf(output_file, "\nInput curve size: %zu", input_size);
+        fprintf(output_file, "\nOutput curve size: %zu", output_size);
+
+        fprintf(output_file, "\n\nInput gamma, Output gamma\n");
+        // Output gamma curve down-sample factor.
+        scale_factor = (float)(output_size - 1) / (input_size - 1);
 
         for (i = 0; i < input_size; ++i) {
             float input = gamma_table_in[i * 4] * inverse65535;
             size_t out_index = (size_t)floor(i * scale_factor + 0.5);
-            float p = out_index / (float)(output_size - 1);
-            float reference = clamp_float(evaluate_parametric_curve(type, profile->redTRC->parameter, p));
-            float actual = gamma_table_out[out_index * 4] * inverse65535;
-            float difference = fabs(actual - reference);
+            float output = gamma_table_out[out_index * 4] * inverse65535;
 
-            fprintf(output_file, "%.6f, %.6f, %6f, %6f\n", input, actual, reference, difference);
+            fprintf(output_file, "%.6f, %.6f\n", input, output);
         }
 
-        fprintf(output_file, "\nNote: the output curves we down sampled by a factor of %zu / %zu\n",
+        fprintf(output_file, "\nNote: the output gamma curves are down-sampled by a factor of %zu / %zu\n",
                 output_size, input_size);
 
         fclose(output_file);
diff --git a/third_party/qcms/src/transform_util.c b/third_party/qcms/src/transform_util.c
index 3b2dcef7..e607447 100644
--- a/third_party/qcms/src/transform_util.c
+++ b/third_party/qcms/src/transform_util.c
@@ -598,32 +598,25 @@
 {
         if (trc->type == PARAMETRIC_CURVE_TYPE) {
                 float gamma_table[256];
+                uint16_t gamma_table_uint[256];
                 uint16_t i;
-                uint16_t *output = malloc(sizeof(uint16_t)*256);
                 uint16_t *inverted;
                 int inverted_size = 4096;
 
-                if (!output) {
-                        *output_gamma_lut = NULL;
-                        return;
-                }
-
                 compute_curve_gamma_table_type_parametric(gamma_table, trc->parameter, trc->count);
-
                 for(i = 0; i < 256; i++) {
-                        output[i] = (uint16_t)(gamma_table[i] * 65535);
+                        gamma_table_uint[i] = (uint16_t)(gamma_table[i] * 65535);
                 }
 
                 //XXX: the choice of a minimum of 256 here is not backed by any theory,
                 //     measurement or data, however it is what lcms uses.
                 //     the maximum number we would need is 65535 because that's the
                 //     accuracy used for computing the pre cache table
-                inverted = invert_lut(output, 256, inverted_size);
+                inverted = invert_lut(gamma_table_uint, 256, inverted_size);
                 if (!inverted)
                         return;
                 *output_gamma_lut = inverted;
                 *output_gamma_lut_length = inverted_size;
-                free(output);
         } else {
                 if (trc->count == 0) {
                         *output_gamma_lut = build_linear_table(4096);
diff --git a/tools/android/loading/cloud/backend/worker.py b/tools/android/loading/cloud/backend/worker.py
index ff0d473..cef7044 100644
--- a/tools/android/loading/cloud/backend/worker.py
+++ b/tools/android/loading/cloud/backend/worker.py
@@ -8,7 +8,6 @@
 import os
 import re
 import sys
-import time
 
 from googleapiclient import discovery
 from oauth2client.client import GoogleCredentials
@@ -123,10 +122,21 @@
         project=project_name, taskqueue=queue_name, numTasks=1, leaseSecs=600,
         groupByTag=True, tag=self._taskqueue_tag).execute()
     if (not response.get('items')) or (len(response['items']) < 1):
-      return (None, None)
+      return (None, None)  # The task queue is empty.
 
     google_task = response['items'][0]
     task_id = google_task['id']
+
+    # Delete the task without processing if it already failed multiple times.
+    # TODO(droger): This is a workaround for internal bug b/28442122, revisit
+    # once it is fixed.
+    retry_count = google_task['retry_count']
+    max_retry_count = 3
+    if retry_count >= max_retry_count:
+      task_api.tasks().delete(project=project_name, taskqueue=queue_name,
+                              task=task_id).execute()
+      return self._FetchClovisTask(project_name, task_api, queue_name)
+
     clovis_task = ClovisTask.FromBase64(google_task['payloadBase64'])
     return (clovis_task, task_id)
 
diff --git a/tools/android/loading/cloud/frontend/clovis_frontend.py b/tools/android/loading/cloud/frontend/clovis_frontend.py
index 42b7b09..cb2f2c2d 100644
--- a/tools/android/loading/cloud/frontend/clovis_frontend.py
+++ b/tools/android/loading/cloud/frontend/clovis_frontend.py
@@ -217,7 +217,6 @@
   Google Compute Engine.
   """
   q = taskqueue.Queue('clovis-queue')
-  retry_options = taskqueue.TaskRetryOptions(task_retry_limit=3)
   # Add tasks to the queue by groups.
   # TODO(droger): This supports thousands of tasks, but maybe not millions.
   # Defer the enqueuing if it times out.
@@ -228,7 +227,7 @@
       group = tasks[i:i+group_size]
       taskqueue_tasks = [
           taskqueue.Task(payload=task.ToJsonString(), method='PULL',
-                         tag=task_tag, retry_options=retry_options)
+                         tag=task_tag)
           for task in group]
       rpc = taskqueue.create_rpc()
       q.add_async(task=taskqueue_tasks, rpc=rpc)
diff --git a/tools/android/loading/options.py b/tools/android/loading/options.py
index 3ea91b7..f7e8ee266 100644
--- a/tools/android/loading/options.py
+++ b/tools/android/loading/options.py
@@ -113,6 +113,7 @@
     self._parsed_args = parsed_args
 
   def _MakeParser(self, description=None, extra=None, group=None):
+    self._arg_set = set()
     add_help = True if group is None else False
     parser = argparse.ArgumentParser(
         description=description, add_help=add_help)
diff --git a/tools/android/loading/sandwich.py b/tools/android/loading/sandwich.py
index d7ec1a1a..0b72c73c 100755
--- a/tools/android/loading/sandwich.py
+++ b/tools/android/loading/sandwich.py
@@ -50,16 +50,14 @@
 
 def _ArgumentParser():
   """Build a command line argument's parser."""
-  # Command parser when dealing with jobs.
-  common_job_parser = argparse.ArgumentParser(add_help=False)
-  common_job_parser.add_argument('--job', required=True,
-                                 help='JSON file with job description.')
-  common_job_parser.add_argument('--android', default=None, type=str,
-                                 dest='android_device_serial',
-                                 help='Android device\'s serial to use.')
-
   task_parser = task_manager.CommandLineParser()
 
+  # Command parser when dealing with SandwichRunner.
+  sandwich_runner_parser = argparse.ArgumentParser(add_help=False)
+  sandwich_runner_parser.add_argument('--android', default=None, type=str,
+                                      dest='android_device_serial',
+                                      help='Android device\'s serial to use.')
+
   # Plumbing parser to configure OPTIONS.
   plumbing_parser = OPTIONS.GetParentParser('plumbing options')
 
@@ -67,109 +65,12 @@
   parser = argparse.ArgumentParser(parents=[plumbing_parser])
   subparsers = parser.add_subparsers(dest='subcommand', help='subcommand line')
 
-  # Record WPR subcommand.
-  record_wpr = subparsers.add_parser('record-wpr', parents=[common_job_parser],
-                                     help='Record WPR from sandwich job.')
-  record_wpr.add_argument('--wpr-archive', required=True, type=str,
-                          dest='wpr_archive_path',
-                          help='Web page replay archive to generate.')
-
-  # Patch WPR subcommand.
-  patch_wpr = subparsers.add_parser('patch-wpr',
-                                     help='Patch WPR response headers.')
-  patch_wpr.add_argument('--wpr-archive', required=True, type=str,
-                         dest='wpr_archive_path',
-                         help='Web page replay archive to patch.')
-
-  # Create cache subcommand.
-  create_cache_parser = subparsers.add_parser('create-cache',
-      parents=[common_job_parser],
-      help='Create cache from sandwich job.')
-  create_cache_parser.add_argument('--cache-archive', required=True, type=str,
-                                   dest='cache_archive_path',
-                                   help='Cache archive destination path.')
-  create_cache_parser.add_argument('--wpr-archive', default=None, type=str,
-                                   dest='wpr_archive_path',
-                                   help='Web page replay archive to create ' +
-                                       'the cache from.')
-
-  # Run subcommand.
-  run_parser = subparsers.add_parser('run', parents=[common_job_parser],
-                                     help='Run sandwich benchmark.')
-  run_parser.add_argument('--output', required=True, type=str,
-                          dest='trace_output_directory',
-                          help='Path of output directory to create.')
-  run_parser.add_argument('--cache-archive', type=str,
-                          dest='cache_archive_path',
-                          help='Cache archive destination path.')
-  run_parser.add_argument('--cache-op',
-                          choices=['clear', 'push', 'reload'],
-                          dest='cache_operation',
-                          default='clear',
-                          help='Configures cache operation to do before '
-                              +'launching Chrome. (Default is clear). The push'
-                              +' cache operation requires --cache-archive to '
-                              +'set.')
-  run_parser.add_argument('--disable-wpr-script-injection',
-                          action='store_true',
-                          help='Disable WPR default script injection such as ' +
-                              'overriding javascript\'s Math.random() and ' +
-                              'Date() with deterministic implementations.')
-  run_parser.add_argument('--network-condition', default=None,
-      choices=sorted(emulation.NETWORK_CONDITIONS.keys()),
-      help='Set a network profile.')
-  run_parser.add_argument('--network-emulator', default='browser',
-      choices=['browser', 'wpr'],
-      help='Set which component is emulating the network condition.' +
-          ' (Default to browser). Wpr network emulator requires --wpr-archive' +
-          ' to be set.')
-  run_parser.add_argument('--job-repeat', default=1, type=int,
-                          help='How many times to run the job.')
-  run_parser.add_argument('--record-video', action='store_true',
-                          help='Configures either to record or not a video of '
-                              +'chrome loading the web pages.')
-  run_parser.add_argument('--wpr-archive', default=None, type=str,
-                          dest='wpr_archive_path',
-                          help='Web page replay archive to load job\'s urls ' +
-                              'from.')
-
-  # Pull metrics subcommand.
-  create_cache_parser = subparsers.add_parser('extract-metrics',
-      help='Extracts metrics from a loading trace and saves as CSV.')
-  create_cache_parser.add_argument('--trace-directory', required=True,
-                                   dest='trace_output_directory', type=str,
-                                   help='Path of loading traces directory.')
-  create_cache_parser.add_argument('--out-metrics', default=None, type=str,
-                                   dest='metrics_csv_path',
-                                   help='Path where to save the metrics\'s '+
-                                      'CSV.')
-
-  # Filter cache subcommand.
-  filter_cache_parser = subparsers.add_parser('filter-cache',
-      help='Cache filtering that keeps only resources discoverable by the HTML'+
-          ' document parser.')
-  filter_cache_parser.add_argument('--cache-archive', type=str, required=True,
-                                   dest='cache_archive_path',
-                                   help='Path of the cache archive to filter.')
-  filter_cache_parser.add_argument('--subresource-discoverer', required=True,
-      help='Strategy for populating the cache with a subset of resources, '
-           'according to the way they can be discovered',
-      choices=sandwich_misc.SUBRESOURCE_DISCOVERERS)
-  filter_cache_parser.add_argument('--output', type=str, required=True,
-                                   dest='output_cache_archive_path',
-                                   help='Path of filtered cache archive.')
-  filter_cache_parser.add_argument('loading_trace_paths', type=str, nargs='+',
-      metavar='LOADING_TRACE',
-      help='A list of loading traces generated by a sandwich run for a given' +
-          ' url. This is used to have a resource dependency graph to white-' +
-          'list the ones discoverable by the HTML pre-scanner for that given ' +
-          'url.')
-
   # Record test trace subcommand.
   record_trace_parser = subparsers.add_parser('record-test-trace',
+      parents=[sandwich_runner_parser],
       help='Record a test trace using the trace_test.webserver_test.')
   record_trace_parser.add_argument('--source-dir', type=str, required=True,
-                                   help='Base path where the files are opened'
+                                   help='Base path where the files are opened '
                                         'by the web server.')
   record_trace_parser.add_argument('--page', type=str, required=True,
                                    help='Source page in source-dir to navigate '
@@ -177,93 +78,38 @@
   record_trace_parser.add_argument('-o', '--output', type=str, required=True,
                                    help='Output path of the generated trace.')
 
-  # Run all subcommand.
-  run_all = subparsers.add_parser('run-all',
-                       parents=[common_job_parser, task_parser],
-                       help='Run all steps using the task manager '
-                            'infrastructure.')
-  run_all.add_argument('-m', '--measure', default=[], dest='optional_measures',
-                       choices=[_SPEED_INDEX_MEASUREMENT, _MEMORY_MEASUREMENT],
-                       nargs='+', help='Enable optional measurements.')
-  run_all.add_argument('-g', '--gen-full', action='store_true',
-                       help='Generate the full graph with all possible'
-                            'benchmarks.')
-  run_all.add_argument('--wpr-archive', default=None, type=str,
-                       dest='wpr_archive_path',
-                       help='WebPageReplay archive to use, instead of '
-                            'generating one.')
-  run_all.add_argument('--url-repeat', default=1, type=int,
-                       help='How many times to repeat the urls.')
+  # Run subcommand.
+  run_parser = subparsers.add_parser('run',
+      parents=[sandwich_runner_parser, task_parser],
+      help='Run all steps using the task manager infrastructure.')
+  run_parser.add_argument('-g', '--gen-full', action='store_true',
+                          help='Generate the full graph with all possible '
+                               'benchmarks.')
+  run_parser.add_argument('--job', required=True,
+      help='JSON file with job description such as in sandwich_jobs/.')
+  run_parser.add_argument('-m', '--measure', default=[], nargs='+',
+      choices=[_SPEED_INDEX_MEASUREMENT, _MEMORY_MEASUREMENT],
+      dest='optional_measures', help='Enable optional measurements.')
+  run_parser.add_argument('--wpr-archive', default=None, type=str,
+                          dest='wpr_archive_path',
+                          help='WebPageReplay archive to use, instead of '
+                               'generating one.')
+  run_parser.add_argument('--url-repeat', default=1, type=int,
+                          help='How many times to repeat the urls.')
 
   return parser
 
 
-def _CreateSandwichRunner(args):
-  sandwich_runner = SandwichRunner()
-  sandwich_runner.LoadJob(args.job)
-  sandwich_runner.PullConfigFromArgs(args)
-  if args.android_device_serial is not None:
-    sandwich_runner.android_device = \
-        device_setup.GetDeviceFromSerial(args.android_device_serial)
-  return sandwich_runner
-
-
-def _RecordWprMain(args):
-  sandwich_runner = _CreateSandwichRunner(args)
-  sandwich_runner.wpr_record = True
-  sandwich_runner.PrintConfig()
-  if not os.path.isdir(os.path.dirname(args.wpr_archive_path)):
-    os.makedirs(os.path.dirname(args.wpr_archive_path))
-  sandwich_runner.Run()
-  return 0
-
-
-def _CreateCacheMain(args):
-  sandwich_runner = _CreateSandwichRunner(args)
-  sandwich_runner.cache_operation = 'save'
-  sandwich_runner.PrintConfig()
-  if not os.path.isdir(os.path.dirname(args.cache_archive_path)):
-    os.makedirs(os.path.dirname(args.cache_archive_path))
-  sandwich_runner.Run()
-  return 0
-
-
-def _RunJobMain(args):
-  sandwich_runner = _CreateSandwichRunner(args)
-  sandwich_runner.PrintConfig()
-  sandwich_runner.Run()
-  return 0
-
-
-def _ExtractMetricsMain(args):
-  run_metrics_list = sandwich_metrics.ExtractMetricsFromRunnerOutputDirectory(
-      args.trace_output_directory)
-  run_metrics_list.sort(key=lambda e: e['repeat_id'])
-  with open(args.metrics_csv_path, 'w') as csv_file:
-    writer = csv.DictWriter(csv_file,
-                            fieldnames=sandwich_metrics.CSV_FIELD_NAMES)
-    writer.writeheader()
-    for run_metrics in run_metrics_list:
-      writer.writerow(run_metrics)
-  return 0
-
-
-def _FilterCacheMain(args):
-  whitelisted_urls = set()
-  for loading_trace_path in args.loading_trace_paths:
-    whitelisted_urls.update(sandwich_misc.ExtractDiscoverableUrls(
-        loading_trace_path, args.subresource_discoverer))
-  if not os.path.isdir(os.path.dirname(args.output_cache_archive_path)):
-    os.makedirs(os.path.dirname(args.output_cache_archive_path))
-  chrome_cache.ApplyUrlWhitelistToCacheArchive(args.cache_archive_path,
-                                               whitelisted_urls,
-                                               args.output_cache_archive_path)
-  return 0
+def _GetAndroidDeviceFromArgs(args):
+  if args.android_device_serial:
+    return device_setup.GetDeviceFromSerial(args.android_device_serial)
+  return None
 
 
 def _RecordWebServerTestTrace(args):
   with common_util.TemporaryDirectory() as out_path:
     sandwich_runner = SandwichRunner()
+    sandwich_runner.android_device = _GetAndroidDeviceFromArgs(args)
     # Reuse the WPR's forwarding to access the webpage from Android.
     sandwich_runner.wpr_record = True
     sandwich_runner.wpr_archive_path = os.path.join(out_path, 'wpr')
@@ -280,13 +126,9 @@
 
 
 def _RunAllMain(args):
-  android_device = None
-  if args.android_device_serial:
-    android_device = \
-        device_setup.GetDeviceFromSerial(args.android_device_serial)
   builder = sandwich_task_builder.SandwichTaskBuilder(
       output_directory=args.output,
-      android_device=android_device,
+      android_device=_GetAndroidDeviceFromArgs(args),
       job_path=args.job)
   if args.wpr_archive_path:
     builder.OverridePathToWprArchive(args.wpr_archive_path)
@@ -330,22 +172,9 @@
   args = _ArgumentParser().parse_args(command_line_args)
   OPTIONS.SetParsedArgs(args)
 
-  if args.subcommand == 'record-wpr':
-    return _RecordWprMain(args)
-  if args.subcommand == 'patch-wpr':
-    sandwich_misc.PatchWpr(args.wpr_archive_path)
-    return 0
-  if args.subcommand == 'create-cache':
-    return _CreateCacheMain(args)
-  if args.subcommand == 'run':
-    return _RunJobMain(args)
-  if args.subcommand == 'extract-metrics':
-    return _ExtractMetricsMain(args)
-  if args.subcommand == 'filter-cache':
-    return _FilterCacheMain(args)
   if args.subcommand == 'record-test-trace':
     return _RecordWebServerTestTrace(args)
-  if args.subcommand == 'run-all':
+  if args.subcommand == 'run':
     return _RunAllMain(args)
   assert False
 
diff --git a/tools/android/loading/sandwich_misc.py b/tools/android/loading/sandwich_misc.py
index 5df6351..5ecc064 100644
--- a/tools/android/loading/sandwich_misc.py
+++ b/tools/android/loading/sandwich_misc.py
@@ -5,6 +5,7 @@
 import logging
 import json
 import os
+from urlparse import urlparse
 
 import chrome_cache
 import common_util
@@ -199,6 +200,7 @@
   benchmark_setup = json.load(open(benchmark_setup_path))
   cache_whitelist = set(benchmark_setup['cache_whitelist'])
   url_resources = set(benchmark_setup['url_resources'])
+  all_sent_url_requests = set()
 
   # Verify requests from traces.
   run_id = -1
@@ -218,9 +220,36 @@
     _PrintUrlSetComparison(url_resources.intersection(cache_whitelist),
         _ListUrlRequests(trace, _RequestOutcome.ServedFromCache),
         'Cached resources')
+    sent_url_requests = \
+        _ListUrlRequests(trace, _RequestOutcome.NotServedFromCache)
     _PrintUrlSetComparison(url_resources.difference(cache_whitelist),
-        _ListUrlRequests(trace, _RequestOutcome.NotServedFromCache),
-        'Non cached resources')
+        sent_url_requests, 'Non cached resources')
+    all_sent_url_requests.update(sent_url_requests)
+
+  # Verify requests from WPR.
+  wpr_log_path = os.path.join(
+      benchmark_output_directory_path, sandwich_runner.WPR_LOG_FILENAME)
+  logging.info('verifying requests from %s' % wpr_log_path)
+  all_wpr_requests = wpr_backend.ExtractRequestsFromLog(wpr_log_path)
+  all_wpr_urls = set()
+  unserved_wpr_urls = set()
+  wpr_command_colliding_urls = set()
+
+  for request in all_wpr_requests:
+    if request.is_wpr_host:
+      continue
+    if urlparse(request.url).path.startswith('/web-page-replay'):
+      wpr_command_colliding_urls.add(request.url)
+    elif request.is_served is False:
+      unserved_wpr_urls.add(request.url)
+    all_wpr_urls.add(request.url)
+
+  _PrintUrlSetComparison(set(), unserved_wpr_urls,
+                         'Distinct unserved resources from WPR')
+  _PrintUrlSetComparison(set(), wpr_command_colliding_urls,
+                         'Distinct resources colliding to WPR commands')
+  _PrintUrlSetComparison(all_wpr_urls, all_sent_url_requests,
+                         'Distinct resources requests to WPR')
 
 
 def ReadSubresourceMapFromBenchmarkOutput(benchmark_output_directory_path):
diff --git a/tools/android/loading/sandwich_runner.py b/tools/android/loading/sandwich_runner.py
index 3dc0415..665824b3 100644
--- a/tools/android/loading/sandwich_runner.py
+++ b/tools/android/loading/sandwich_runner.py
@@ -25,6 +25,7 @@
 # Standard filenames in the sandwich runner's output directory.
 TRACE_FILENAME = 'trace.json'
 VIDEO_FILENAME = 'video.mp4'
+WPR_LOG_FILENAME = 'wpr.log'
 
 # Memory dump category used to get memory metrics.
 MEMORY_DUMP_CATEGORY = 'disabled-by-default-memory-infra'
@@ -264,12 +265,16 @@
       chrome_cache.UnzipDirectoryContent(
           self.cache_archive_path, self._local_cache_directory_path)
 
+    out_log_path = None
+    if self.trace_output_directory:
+      out_log_path = os.path.join(self.trace_output_directory, WPR_LOG_FILENAME)
+
     ran_urls = []
     with self._chrome_ctl.OpenWprHost(self.wpr_archive_path,
         record=self.wpr_record,
         network_condition_name=self._GetEmulatorNetworkCondition('wpr'),
-        disable_script_injection=self.disable_wpr_script_injection
-        ):
+        disable_script_injection=self.disable_wpr_script_injection,
+        out_log_path=out_log_path):
       for _ in xrange(self.job_repeat):
         for url in self.urls:
           self._RunUrl(url, run_id=len(ran_urls))
diff --git a/tools/android/loading/trace_test/webserver_unittest.py b/tools/android/loading/trace_test/webserver_unittest.py
index d687b13..f4b232c 100644
--- a/tools/android/loading/trace_test/webserver_unittest.py
+++ b/tools/android/loading/trace_test/webserver_unittest.py
@@ -24,8 +24,7 @@
 
 class WebServerTestCase(unittest.TestCase):
   def setUp(self):
-    if not OPTIONS._parsed_args:
-      OPTIONS.ParseArgs('', extra=[('--noisy', False)])
+    OPTIONS.ParseArgs('', extra=[('--noisy', False)])
     self._temp_dir = tempfile.mkdtemp()
     self._server = webserver_test.WebServer(self._temp_dir, self._temp_dir)
 
diff --git a/tools/android/loading/wpr_backend.py b/tools/android/loading/wpr_backend.py
index e9835727..a24d282 100644
--- a/tools/android/loading/wpr_backend.py
+++ b/tools/android/loading/wpr_backend.py
@@ -9,6 +9,7 @@
 import os
 import re
 import sys
+from urlparse import urlparse
 
 
 _SRC_DIR = os.path.abspath(os.path.join(
@@ -23,6 +24,15 @@
 # Regex used to parse httparchive.py stdout's when listing all urls.
 _PARSE_WPR_REQUEST_REGEX = re.compile(r'^\S+\s+(?P<url>\S+)')
 
+# Regex used to extract WPR domain from WPR log.
+_PARSE_WPR_DOMAIN_REGEX = re.compile(r'^\(WARNING\)\s.*\sHTTP server started on'
+                                     r' (?P<netloc>\S+)\s*$')
+
+# Regex used to extract URLs requests from WPR log.
+_PARSE_WPR_URL_REGEX = re.compile(
+    r'^\((?P<level>\S+)\)\s.*\shttpproxy\..*\s(?P<method>[A-Z]+)\s+'
+    r'(?P<url>https?://[a-zA-Z0-9\-_:.]+/?\S*)\s.*$')
+
 
 class WprUrlEntry(object):
   """Wpr url entry holding request and response infos. """
@@ -114,6 +124,51 @@
     self._http_archive.Persist(self._wpr_archive_path)
 
 
+# WPR request seen by the WPR's HTTP proxy.
+#   is_served: Boolean whether WPR has found a matching resource in the archive.
+#   method: HTTP method of the request ['GET', 'POST' and so on...].
+#   url: The requested URL.
+#   is_wpr_host: Whether the requested url have WPR has an host such as:
+#     http://127.0.0.1:<WPR's HTTP listening port>/web-page-replay-command-exit
+WprRequest = collections.namedtuple('WprRequest',
+    ['is_served', 'method', 'url', 'is_wpr_host'])
+
+
+def ExtractRequestsFromLog(log_path):
+  """Extract list of requested handled by the WPR's HTTP proxy from a WPR log.
+
+  Args:
+    log_path: The path of the WPR log to parse.
+
+  Returns:
+    List of WprRequest.
+  """
+  requests = []
+  wpr_http_netloc = None
+  with open(log_path) as log_file:
+    for line in log_file.readlines():
+      # Extract WPR's HTTP proxy's listening network location.
+      match = _PARSE_WPR_DOMAIN_REGEX.match(line)
+      if match:
+        wpr_http_netloc = match.group('netloc')
+        assert wpr_http_netloc.startswith('127.0.0.1:')
+        continue
+      # Extract the WPR requested URLs.
+      match = _PARSE_WPR_URL_REGEX.match(line)
+      if match:
+        parsed_url = urlparse(match.group('url'))
+        # Ignore strange URL requests such as http://ousvtzkizg/
+        # TODO(gabadie): Find and terminate the location where they are queried.
+        if '.' not in parsed_url.netloc and ':' not in parsed_url.netloc:
+          continue
+        assert wpr_http_netloc
+        request = WprRequest(is_served=(match.group('level') == 'DEBUG'),
+            method=match.group('method'), url=match.group('url'),
+            is_wpr_host=parsed_url.netloc == wpr_http_netloc)
+        requests.append(request)
+  return requests
+
+
 if __name__ == '__main__':
   import argparse
   parser = argparse.ArgumentParser(description='Tests cache back-end.')
diff --git a/tools/android/loading/wpr_backend_unittest.py b/tools/android/loading/wpr_backend_unittest.py
index 3cdf5811..f744c10 100644
--- a/tools/android/loading/wpr_backend_unittest.py
+++ b/tools/android/loading/wpr_backend_unittest.py
@@ -2,9 +2,20 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import contextlib
+import httplib
+import os
+import shutil
+import tempfile
 import unittest
 
-from wpr_backend import WprUrlEntry
+from device_setup import _WprHost
+from options import OPTIONS
+from trace_test.webserver_test import WebServer
+from wpr_backend import WprUrlEntry, WprRequest, ExtractRequestsFromLog
+
+
+LOADING_DIR = os.path.dirname(__file__)
 
 
 class MockWprResponse(object):
@@ -122,5 +133,123 @@
     self.assertEquals(2, len(entry.GetResponseHeadersDict()))
 
 
+class WprHostTest(unittest.TestCase):
+  def setUp(self):
+    OPTIONS.ParseArgs([])
+    self._server_address = None
+    self._wpr_http_port = None
+    self._tmp_directory = tempfile.mkdtemp(prefix='tmp_test_')
+
+  def tearDown(self):
+    shutil.rmtree(self._tmp_directory)
+
+  def _TmpPath(self, name):
+    return os.path.join(self._tmp_directory, name)
+
+  def _LogPath(self):
+    return self._TmpPath('wpr.log')
+
+  def _ArchivePath(self):
+    return self._TmpPath('wpr')
+
+  @contextlib.contextmanager
+  def RunWebServer(self):
+    assert self._server_address is None
+    with WebServer.Context(
+        source_dir=os.path.join(LOADING_DIR, 'trace_test', 'tests'),
+        communication_dir=self._tmp_directory) as server:
+      self._server_address = server.Address()
+      yield
+
+  @contextlib.contextmanager
+  def RunWpr(self, record):
+    assert self._server_address is not None
+    assert self._wpr_http_port is None
+    with _WprHost(self._ArchivePath(), record=record,
+                  out_log_path=self._LogPath()) as (http_port, https_port):
+      del https_port # unused
+      self._wpr_http_port = http_port
+      yield http_port
+
+  def DoHttpRequest(self, path, expected_status=200, destination='wpr'):
+    assert self._server_address is not None
+    if destination == 'wpr':
+      assert self._wpr_http_port is not None
+      connection = httplib.HTTPConnection('127.0.0.1', self._wpr_http_port)
+    elif destination == 'server':
+      connection = httplib.HTTPConnection(self._server_address)
+    else:
+      assert False
+    try:
+      connection.request(
+          "GET", '/' + path, headers={'Host': self._server_address})
+      response = connection.getresponse()
+    finally:
+      connection.close()
+    self.assertEquals(expected_status, response.status)
+
+  def _GenRawWprRequest(self, path):
+    assert self._wpr_http_port is not None
+    url = 'http://127.0.0.1:{}/web-page-replay-{}'.format(
+        self._wpr_http_port, path)
+    return WprRequest(is_served=True, method='GET', is_wpr_host=True, url=url)
+
+  def GenRawRequest(self, path, is_served):
+    assert self._server_address is not None
+    return WprRequest(is_served=is_served, method='GET', is_wpr_host=False,
+        url='http://{}/{}'.format(self._server_address, path))
+
+  def AssertWprParsedRequests(self, ref_requests):
+    all_ref_requests = []
+    all_ref_requests.append(self._GenRawWprRequest('generate-200'))
+    all_ref_requests.extend(ref_requests)
+    all_ref_requests.append(self._GenRawWprRequest('generate-200'))
+    all_ref_requests.append(self._GenRawWprRequest('command-exit'))
+    requests = ExtractRequestsFromLog(self._LogPath())
+    self.assertEquals(all_ref_requests, requests)
+    self._wpr_http_port = None
+
+  def testExtractRequestsFromLog(self):
+    with self.RunWebServer():
+      with self.RunWpr(record=True):
+        self.DoHttpRequest('1.html')
+        self.DoHttpRequest('2.html')
+        ref_requests = [
+            self.GenRawRequest('1.html', is_served=True),
+            self.GenRawRequest('2.html', is_served=True)]
+    self.AssertWprParsedRequests(ref_requests)
+
+    with self.RunWpr(record=False):
+      self.DoHttpRequest('2.html')
+      self.DoHttpRequest('1.html')
+      ref_requests = [
+          self.GenRawRequest('2.html', is_served=True),
+          self.GenRawRequest('1.html', is_served=True)]
+    self.AssertWprParsedRequests(ref_requests)
+
+  def testExtractRequestsFromLogHaveCorrectIsServed(self):
+    with self.RunWebServer():
+      with self.RunWpr(record=True):
+        self.DoHttpRequest('4.html', expected_status=404)
+        ref_requests = [self.GenRawRequest('4.html', is_served=True)]
+    self.AssertWprParsedRequests(ref_requests)
+
+    with self.RunWpr(record=False):
+      self.DoHttpRequest('4.html', expected_status=404)
+      self.DoHttpRequest('5.html', expected_status=404)
+      ref_requests = [self.GenRawRequest('4.html', is_served=True),
+                      self.GenRawRequest('5.html', is_served=False)]
+    self.AssertWprParsedRequests(ref_requests)
+
+  def testExtractRequestsFromLogHaveCorrectIsWprHost(self):
+    PATH = 'web-page-replay-generate-200'
+    with self.RunWebServer():
+      self.DoHttpRequest(PATH, expected_status=404, destination='server')
+      with self.RunWpr(record=True):
+        self.DoHttpRequest(PATH)
+      ref_requests = [self.GenRawRequest(PATH, is_served=True)]
+    self.AssertWprParsedRequests(ref_requests)
+
+
 if __name__ == '__main__':
   unittest.main()
diff --git a/tools/checkbins/checkbins.py b/tools/checkbins/checkbins.py
index 74ed0ae..ec955781 100755
--- a/tools/checkbins/checkbins.py
+++ b/tools/checkbins/checkbins.py
@@ -31,6 +31,7 @@
 # Windows guru for advice.
 EXCLUDED_FILES = ['chrome_frame_mini_installer.exe',
                   'mini_installer.exe',
+                  'next_version_mini_installer.exe',
                   'wow_helper.exe'
                   ]
 
diff --git a/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp b/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp
index e609a9706..e5d69f0 100644
--- a/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp
+++ b/tools/clang/blink_gc_plugin/CheckFieldsVisitor.cpp
@@ -86,7 +86,7 @@
 
   // Disallow  OwnPtr<T>, RefPtr<T> and T* to stack-allocated types.
   if (Parent()->IsOwnPtr() ||
-      (Parent()->IsRefPtr() && !edge->value()->IsGCRefCounted()) ||
+      Parent()->IsRefPtr() ||
       (stack_allocated_host_ && Parent()->IsRawPtr())) {
     invalid_fields_.push_back(std::make_pair(
         current_, InvalidSmartPtr(Parent())));
diff --git a/tools/clang/blink_gc_plugin/Config.h b/tools/clang/blink_gc_plugin/Config.h
index 7ca8ea4c..8d331e5 100644
--- a/tools/clang/blink_gc_plugin/Config.h
+++ b/tools/clang/blink_gc_plugin/Config.h
@@ -133,14 +133,7 @@
   }
 
   static bool IsGCFinalizedBase(const std::string& name) {
-    return name == "GarbageCollectedFinalized" ||
-           name == "RefCountedGarbageCollected" ||
-           name == "ThreadSafeRefCountedGarbageCollected";
-  }
-
-  static bool IsGCRefCountedBase(const std::string& name) {
-    return name == "RefCountedGarbageCollected" ||
-           name == "ThreadSafeRefCountedGarbageCollected";
+    return name == "GarbageCollectedFinalized";
   }
 
   static bool IsGCBase(const std::string& name) {
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp
index 2f17234..f0e2ade 100644
--- a/tools/clang/blink_gc_plugin/RecordInfo.cpp
+++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
@@ -186,16 +186,6 @@
   return is_eagerly_finalized_;
 }
 
-bool RecordInfo::IsGCRefCounted() {
-  if (!IsGCDerived())
-    return false;
-  for (const auto& gc_base : gc_base_names_) {
-    if (Config::IsGCRefCountedBase(gc_base))
-      return true;
-  }
-  return false;
-}
-
 bool RecordInfo::HasDefinition() {
   return record_->hasDefinition();
 }
diff --git a/tools/clang/blink_gc_plugin/RecordInfo.h b/tools/clang/blink_gc_plugin/RecordInfo.h
index b294ffe0..39c13f0 100644
--- a/tools/clang/blink_gc_plugin/RecordInfo.h
+++ b/tools/clang/blink_gc_plugin/RecordInfo.h
@@ -101,7 +101,6 @@
   bool IsNonNewable();
   bool IsOnlyPlacementNewable();
   bool IsEagerlyFinalized();
-  bool IsGCRefCounted();
 
   bool HasDefinition();
 
diff --git a/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.cpp b/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.cpp
index 22e59d5..e0a200f 100644
--- a/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.cpp
+++ b/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.cpp
@@ -8,6 +8,4 @@
 
 void HeapObject::trace(Visitor*) { }
 
-void RefHeapObject::trace(Visitor*) { }
-
 }
diff --git a/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.h b/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.h
index 405732e..0dba311 100644
--- a/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.h
+++ b/tools/clang/blink_gc_plugin/tests/ref_ptr_to_gc_managed_class.h
@@ -25,14 +25,6 @@
     Vector<RefPtr<HeapObject> > m_objs;
 };
 
-class RefHeapObject : public RefCountedGarbageCollected<HeapObject> {
-public:
-    void trace(Visitor*);
-private:
-    PartObject m_part;
-    Vector<RefPtr<RefHeapObject> > m_objs;
-};
-
 }
 
 #endif
diff --git a/tools/clang/scripts/blink_gc_plugin_flags.py b/tools/clang/scripts/blink_gc_plugin_flags.py
index 0b3e82b..c2b8762 100755
--- a/tools/clang/scripts/blink_gc_plugin_flags.py
+++ b/tools/clang/scripts/blink_gc_plugin_flags.py
@@ -16,26 +16,14 @@
 FLAGS = '-Xclang -add-plugin -Xclang blink-gc-plugin'
 PREFIX= ' -Xclang -plugin-arg-blink-gc-plugin -Xclang '
 
-warn_raw_pointers = None
 for arg in sys.argv[1:]:
-  if arg == 'enable-oilpan=1':
-    FLAGS += PREFIX + 'enable-oilpan'
-    if warn_raw_pointers is None:
-      warn_raw_pointers = True
-  elif arg == 'dump-graph=1':
+  if arg == 'dump-graph=1':
     FLAGS += PREFIX + 'dump-graph'
-  elif arg == 'warn-raw-ptr=1':
-    warn_raw_pointers = True
-  elif arg == 'warn-raw-ptr=0':
-    warn_raw_pointers = False
   elif arg == 'warn-unneeded-finalizer=1':
     FLAGS += PREFIX + 'warn-unneeded-finalizer'
   elif arg.startswith('custom_clang_lib_path='):
     CLANG_LIB_PATH = arg[len('custom_clang_lib_path='):]
 
-if warn_raw_pointers is True:
-  FLAGS += PREFIX + 'warn-raw-ptr'
-
 if not sys.platform in ['win32', 'cygwin']:
   LIBSUFFIX = 'dylib' if sys.platform == 'darwin' else 'so'
   FLAGS = ('-Xclang -load -Xclang "%s/libBlinkGCPlugin.%s" ' + FLAGS) % \
diff --git a/tools/gn/args.cc b/tools/gn/args.cc
index 496ba18..d83c678 100644
--- a/tools/gn/args.cc
+++ b/tools/gn/args.cc
@@ -242,7 +242,7 @@
     arch = kX86;
   else if (os_arch == "x86_64")
     arch = kX64;
-  else if (os_arch.substr(3) == "arm")
+  else if (os_arch.substr(0, 3) == "arm")
     arch = kArm;
   else if (os_arch == "mips")
     arch = kMips;
diff --git a/tools/ipc_fuzzer/message_lib/BUILD.gn b/tools/ipc_fuzzer/message_lib/BUILD.gn
index 413deb6..a362de8 100644
--- a/tools/ipc_fuzzer/message_lib/BUILD.gn
+++ b/tools/ipc_fuzzer/message_lib/BUILD.gn
@@ -11,6 +11,7 @@
     "//components/content_settings/content/common",
     "//components/nacl/common",
     "//components/network_hints/common",
+    "//components/page_load_metrics/common",
     "//components/pdf/common",
     "//content/child",
     "//content/public/child",
diff --git a/tools/ipc_fuzzer/message_lib/DEPS b/tools/ipc_fuzzer/message_lib/DEPS
index b2aa999..46cdff2 100644
--- a/tools/ipc_fuzzer/message_lib/DEPS
+++ b/tools/ipc_fuzzer/message_lib/DEPS
@@ -5,6 +5,7 @@
   "+components/dns_prefetch/common",
   "+components/nacl/common",
   "+components/network_hints/common",
+  "+components/page_load_metrics/common",
   "+components/password_manager/content/common",
   "+components/pdf/common",
   "+components/tracing",
diff --git a/tools/ipc_fuzzer/message_lib/all_messages.h b/tools/ipc_fuzzer/message_lib/all_messages.h
index b9b8355..6cead53f 100644
--- a/tools/ipc_fuzzer/message_lib/all_messages.h
+++ b/tools/ipc_fuzzer/message_lib/all_messages.h
@@ -19,6 +19,7 @@
 #include "components/content_settings/content/common/content_settings_message_generator.h"
 #include "components/nacl/common/nacl_host_messages.h"
 #include "components/network_hints/common/network_hints_message_generator.h"
+#include "components/page_load_metrics/common/page_load_metrics_messages.h"
 #include "components/pdf/common/pdf_message_generator.h"
 #include "components/tracing/tracing_messages.h"
 #include "components/translate/content/common/translate_messages.h"
diff --git a/tools/ipc_fuzzer/message_lib/message_lib.gyp b/tools/ipc_fuzzer/message_lib/message_lib.gyp
index da6ddd2..cf9d18b 100644
--- a/tools/ipc_fuzzer/message_lib/message_lib.gyp
+++ b/tools/ipc_fuzzer/message_lib/message_lib.gyp
@@ -11,6 +11,7 @@
       '../../../chrome/chrome.gyp:safe_browsing_proto',
       '../../../components/components.gyp:content_settings_content_common',
       '../../../components/components.gyp:network_hints_common',
+      '../../../components/components.gyp:page_load_metrics_common',
       '../../../components/components.gyp:pdf_common',
       '../../../components/nacl.gyp:nacl_common',
       '../../../content/content.gyp:content_child',
diff --git a/tools/mb/mb.py b/tools/mb/mb.py
index b03f03a..2e575cd5 100755
--- a/tools/mb/mb.py
+++ b/tools/mb/mb.py
@@ -782,9 +782,10 @@
         self.Print('GN gen failed: %d' % ret)
         return ret
 
+    android = 'target_os="android"' in vals['gn_args']
     for target in swarming_targets:
-      if target.endswith('_apk'):
-        # "_apk" targets may be either android_apk or executable. The former
+      if android:
+        # Android targets may be either android_apk or executable. The former
         # will result in runtime_deps associated with the stamp file, while the
         # latter will result in runtime_deps associated with the executable.
         target_name = self.GNTargetName(target)
@@ -1326,7 +1327,7 @@
     self.Print(json.dumps(obj, indent=2, sort_keys=True))
 
   def GNTargetName(self, target):
-    return target[:-len('_apk')] if target.endswith('_apk') else target
+    return target
 
   def Build(self, target):
     build_dir = self.ToSrcRelPath(self.args.path[0])
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 10dda22..b145df34 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -68,8 +68,8 @@
 
     'chromium.chromiumos': {
       'ChromiumOS amd64-generic Compile': 'cros_chrome_sdk_gn',
-      'ChromiumOS daisy Compile': 'cros_chrome_sdk_gyp',
-      'ChromiumOS x86-generic Compile': 'cros_chrome_sdk_gyp',
+      'ChromiumOS daisy Compile': 'cros_chrome_sdk_gn',
+      'ChromiumOS x86-generic Compile': 'cros_chrome_sdk_gn',
       'Linux ChromiumOS Builder': 'swarming_chromeos_gyp_release_bot',
       'Linux ChromiumOS Builder (dbg)': 'swarming_chromeos_gyp_debug_bot',
       'Linux ChromiumOS Full': 'swarming_chromeos_gyp_release_bot',
@@ -131,8 +131,8 @@
       'ClangToTLinux':
         'swarming_gyp_clang_tot_linux_dump_symbols_shared_release',
       'ClangToTLinux tester': 'none',
-      'ClangToTLinux (dbg)': 'swarming_gyp_clang_tot_shared_debug',
-      'ClangToTLinuxASan': 'swarming_gyp_clang_tot_asan_lsan_static_release',
+      'ClangToTLinux (dbg)': 'swarming_clang_tot_shared_debug',
+      'ClangToTLinuxASan': 'swarming_clang_tot_asan_lsan_static_release',
       'ClangToTLinuxASan tester': 'none',
       'ClangToTLinuxUBSanVptr':
         'swarming_gyp_clang_tot_edge_ubsan_no_recover_hack_static_release',
@@ -257,7 +257,6 @@
         'swarming_gpu_tests_deqp_gles_gyp_release_bot_minimal_symbols_x64',
       'GPU Win x64 Builder (dbg)':
         'swarming_gpu_tests_deqp_gles_gyp_debug_bot_minimal_symbols_x64',
-      'Linux Audio': 'release_static_gyp',
       'Linux ChromiumOS Builder':
         'swarming_gpu_fyi_tests_chromeos_gyp_release_bot',
       'Linux Debug (NVIDIA)': 'none',
@@ -274,7 +273,6 @@
       'Mac 10.10 Retina Release (AMD)': 'none',
       'Mac Retina Debug': 'none',
       'Mac Retina Release': 'none',
-      'Win7 Audio': 'release_static_gyp_minimal_symbols_x86',
       'Win7 Debug (ATI)': 'none',
       'Win7 Debug (NVIDIA)': 'none',
       'Win7 Debug (New Intel)': 'none',
@@ -521,6 +519,10 @@
       'Linux Debug Builder': 'gn_debug_bot',
       'V8 Android GN (dbg)': 'android_gn_debug_bot',
       'V8 Linux GN': 'gn_release_bot',
+      'V8-Blink Linux 64': 'noswarming_gn_release_bot_x64',
+      'V8-Blink Linux 64 (dbg)': 'noswarming_gn_debug_bot_x64',
+      'V8-Blink Mac': 'noswarming_gyp_release_bot_x64',
+      'V8-Blink Win': 'noswarming_gyp_release_bot_minimal_symbols_x86',
     },
 
     'chromium.webkit': {
@@ -580,8 +582,6 @@
       'Win Builder (dbg)': 'swarming_gyp_debug_bot_minimal_symbols_x86',
       'Win x64 Builder': 'swarming_gn_release_bot_minimal_symbols_x64',
       'Win x64 Builder (dbg)': 'swarming_gn_debug_bot_minimal_symbols_x64',
-      'Win x64 GN (dbg)': 'gn_debug_bot_minimal_symbols',
-      'Win x64 GN': 'gn_release_bot_minimal_symbols',
       'Win 7 Tests x64 (1)': 'none',
       'Win10 Tests x64': 'none',
       'Win7 (32) Tests': 'none',
@@ -692,11 +692,12 @@
       'cast_shell_linux': 'cast_gn_release_trybot',
       'chromeos_amd64-generic_variable': 'findit',
       'chromeos_amd64-generic_chromium_compile_only_ng': 'cros_chrome_sdk_gn',
-      'chromeos_daisy_chromium_compile_only_ng': 'cros_chrome_sdk_gyp',
+      'chromeos_daisy_chromium_compile_only_ng': 'cros_chrome_sdk_gn',
       'chromeos_daisy_variable': 'findit',
-      'chromeos_x86-generic_chromium_compile_only_ng': 'cros_chrome_sdk_gyp',
+      'chromeos_x86-generic_chromium_compile_only_ng': 'cros_chrome_sdk_gn',
       'chromeos_x86-generic_variable': 'findit',
       'chromium_presubmit': 'none',
+      'closure_compilation': 'closure_compilation',
       'linux_arm': 'swarming_gyp_release_trybot_arm',
       'linux_chromium_archive_rel_ng': 'noswarming_gn_release_bot',
       'linux_chromium_asan_rel_ng': 'swarming_asan_lsan_gyp_release_trybot',
@@ -731,7 +732,6 @@
       'linux_chromium_gn_chromeos_variable': 'findit',
       'linux_chromium_gn_upload': 'gn_linux_upload',
       'linux_chromium_msan_rel_ng': 'swarming_msan_gyp_release_trybot',
-      'linux_chromium_practice_rel_ng': 'gyp_release_trybot',
       'linux_chromium_rel_ng': 'swarming_gpu_tests_gn_release_trybot',
       'linux_chromium_tsan_rel_ng': 'swarming_tsan_gyp_release_trybot',
       'linux_chromium_tsan_rel_ng':
@@ -746,7 +746,6 @@
       'linux_chromium_webkit_leak_variable': 'findit',
       'linux_chromium_webkit_msan_variable': 'findit',
       'linux_chromium_webkit_variable': 'findit',
-      'linux_full_bisect_builder': 'swarming_gyp_release_bot',
       'linux_nacl_sdk': 'nacl_annotator',
       'linux_nacl_sdk_build': 'nacl_annotator',
       'linux_optional_gpu_tests_rel':
@@ -833,6 +832,8 @@
     'tryserver.chromium.win': {
       'win10_chromium_x64_rel_ng':
         'swarming_gn_release_trybot_minimal_symbols_x64',
+      'win10_chromium_x64_rel_ng_exp':
+        'swarming_gn_release_trybot_minimal_symbols_x64',
       'win8_chromium_gn_dbg': 'gn_debug_bot_minimal_symbols_x86',
       'win8_chromium_gn_upload': 'gn_release_bot_minimal_symbols_x86',
       'win8_chromium_ng': 'gn_release_trybot_x86',
@@ -843,8 +844,6 @@
         'swarming_gyp_debug_bot_minimal_symbols_x86',
       'win_chromium_compile_rel_ng':
         'swarming_gpu_tests_gyp_release_trybot_minimal_symbols_x86',
-      'win_chromium_gn_x64_dbg': 'gn_debug_bot_minimal_symbols',
-      'win_chromium_gn_x64_rel': 'gn_release_trybot',
       'win_chromium_dbg_ng': 'swarming_gyp_debug_bot_minimal_symbols_x86',
       'win_chromium_rel_ng':
         'swarming_gpu_tests_gyp_release_trybot_minimal_symbols_x86',
@@ -1074,10 +1073,6 @@
       'gn', 'cros_chrome_sdk',
     ],
 
-    'cros_chrome_sdk_gyp': [
-      'gyp', 'cros_chrome_sdk',
-    ],
-
     # The 'findit' config is used by the *_variable_* bots, which run
     # the 'FindIt' recipes and code to bisect failures that happen on the
     # other waterfall bots. The findit recipes actually override and
@@ -1103,10 +1098,6 @@
       'gn', 'debug_bot',
     ],
 
-    'gn_debug_bot_minimal_symbols': [
-      'gn', 'debug_bot_minimal_symbols',
-    ],
-
     'gn_debug_bot_minimal_symbols_x86': [
       'gn', 'debug_bot_minimal_symbols', 'x86',
     ],
@@ -1141,10 +1132,6 @@
       'gn', 'release_bot',
     ],
 
-    'gn_release_bot_minimal_symbols': [
-      'gn', 'release_bot_minimal_symbols',
-    ],
-
     'gn_release_bot_minimal_symbols_x86': [
       'gn', 'release_bot_minimal_symbols', 'x86',
     ],
@@ -1397,6 +1384,10 @@
       'error',
     ],
 
+    'noswarming_gn_debug_bot_x64': [
+      'noswarming', 'gn', 'debug_bot', 'x64',
+    ],
+
     'noswarming_gn_release_bot': [
       'noswarming', 'gn', 'release_bot',
     ],
@@ -1405,6 +1396,10 @@
       'noswarming', 'gn', 'release_bot', 'minimal_symbols', 'x64',
     ],
 
+    'noswarming_gn_release_bot_x64': [
+      'noswarming', 'gn', 'release_bot', 'x64',
+    ],
+
     'noswarming_gyp_release_bot_mac_strip': [
       'noswarming', 'gyp', 'release_bot', 'mac_strip',
     ],
@@ -1413,6 +1408,10 @@
       'noswarming', 'gyp', 'release_bot', 'minimal_symbols', 'x86',
     ],
 
+    'noswarming_gyp_release_bot_x64': [
+      'noswarming', 'gyp', 'release_bot', 'x64',
+    ],
+
     'noswarming_gyp_release_trybot': [
       'noswarming', 'gyp', 'release_trybot',
     ],
@@ -1425,14 +1424,6 @@
       'noswarming', 'gyp', 'release_trybot', 'minimal_symbols', 'x86',
     ],
 
-    'release_static_gyp': [
-      'release', 'static', 'gyp',
-    ],
-
-    'release_static_gyp_minimal_symbols_x86': [
-      'release', 'static', 'gyp', 'minimal_symbols', 'x86',
-    ],
-
     'swarming_android_gn_release_bot_minimal_symbols': [
       'swarming', 'android', 'gn', 'release_bot_minimal_symbols',
     ],
@@ -1593,12 +1584,12 @@
       'static', 'release',
     ],
 
-    'swarming_gyp_clang_tot_asan_lsan_static_release': [
-      'swarming', 'gyp', 'clang_tot', 'asan', 'lsan', 'static', 'release',
+    'swarming_clang_tot_asan_lsan_static_release': [
+      'swarming', 'gn', 'clang_tot', 'asan', 'lsan', 'static', 'release',
     ],
 
-    'swarming_gyp_clang_tot_shared_debug': [
-      'swarming', 'gyp', 'clang_tot', 'shared', 'debug',
+    'swarming_clang_tot_shared_debug': [
+      'swarming', 'gn', 'clang_tot', 'shared', 'debug',
     ],
 
     'swarming_gyp_clang_tot_linux_dump_symbols_shared_release': [
@@ -1844,10 +1835,6 @@
       'swarming', 'gyp', 'msan', 'release_bot',
     ],
 
-    'swarming_gyp_release_bot': [
-      'swarming', 'gyp', 'release_bot',
-    ],
-
     'swarming_gyp_release_bot_minimal_symbols_x64': [
       'swarming', 'gyp', 'release_bot_minimal_symbols', 'x64',
     ],
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 7155726..bfa3a81 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -22641,9 +22641,12 @@
 <histogram name="MemoryAndroid.LowRamDevice" enum="Boolean">
   <owner>mariakhomenko@chromium.org</owner>
   <summary>
-    Whether the OS is running in low_ram mode. This histogram is reported on
-    every upload by Android devices. The low_ram status is configured by the OS
-    and reported via ActivityManager.isLowRamDevice().
+    Whether Chrome is running in low ram mode. This histogram is reported on
+    every upload by Android devices. A device is considered low-RAM if it has
+    512MiB of RAM or lower (see SysUtils.detectLowEndDevice()).
+
+    Note: The low-RAM determination has changed in M-49, it used to be given
+    directly by the Android OS.
   </summary>
 </histogram>
 
@@ -32333,7 +32336,9 @@
 
 <histogram name="NewTabPage.AnimatedLogoDownloadTime" units="ms">
   <owner>ianwen@chromium.org</owner>
-  <summary>The amount of time it takes to download the animated logo.</summary>
+  <summary>
+    The amount of time it takes to download the animated logo. Android only.
+  </summary>
 </histogram>
 
 <histogram name="NewTabPage.AppsPageDragSource" enum="AppsPageDragSource">
@@ -32391,6 +32396,7 @@
   <summary>
     The number of most visited tiles on the new tab page that are displayed
     using a fallback color (as opposed to having an icon, or simply being gray).
+    Android only.
   </summary>
 </histogram>
 
@@ -32398,7 +32404,7 @@
   <owner>newt@chromium.org</owner>
   <summary>
     The number of most visited tiles on the new tab page that are displayed as
-    gray (as opposed to having an icon, or a fallback color).
+    gray (as opposed to having an icon, or a fallback color). Android only.
   </summary>
 </histogram>
 
@@ -32406,7 +32412,8 @@
   <owner>newt@chromium.org</owner>
   <summary>
     The number of most visited tiles on the new tab page that are displayed with
-    the site's icon (as opposed using a fallback color or just gray).
+    the site's icon (as opposed using a fallback color or just gray). Android
+    only.
   </summary>
 </histogram>
 
@@ -32449,12 +32456,15 @@
   <summary>
     Outcome of downloading search provider's logos. It measures whether
     download/parsing is successful, revalidation and parsing work properly, etc.
+    Android only.
   </summary>
 </histogram>
 
 <histogram name="NewTabPage.LogoDownloadTime" units="ms">
   <owner>ianwen@chromium.org</owner>
-  <summary>The amount of time it takes to download the static logo.</summary>
+  <summary>
+    The amount of time it takes to download the static logo. Android only.
+  </summary>
 </histogram>
 
 <histogram name="NewTabPage.MobileIsUserOnline" enum="Boolean">
@@ -32789,8 +32799,8 @@
 <histogram name="NewTabPage.Snippets.NumArticles" units="articles">
   <owner>knn@chromium.org</owner>
   <summary>
-    Android: The number of snippet articles available to show on the NTP logged
-    once per NTP load.
+    Android: The number of snippet articles available to show on the NTP, logged
+    once every time the list is updated.
   </summary>
 </histogram>
 
@@ -39751,6 +39761,14 @@
   </summary>
 </histogram>
 
+<histogram name="PreloadScanner.ExternalCSS.PreloadCount" units="preloads">
+  <owner>csharrison@chromium.org</owner>
+  <summary>
+    The number of preloads generated by scanning an external preloaded CSS
+    resource. As of 4/25/2016 this only includes @import declarations.
+  </summary>
+</histogram>
+
 <histogram name="Prerender.AbandonTimeUntilUsed" units="ms">
   <owner>davidben@chromium.org</owner>
   <owner>pasko@chromium.org</owner>
@@ -55506,6 +55524,15 @@
   </summary>
 </histogram>
 
+<histogram name="UMA.Debug.EnableCrashUpload.Uptime" units="ms">
+  <owner>asvitkine@chromium.org</owner>
+  <summary>
+    Measures how much time since start up it took before crash reporting was
+    enabled via enablePotentialCrashUploading() as part of deferred start up.
+    Only logged on Android.
+  </summary>
+</histogram>
+
 <histogram name="UMA.Discarded Log Events">
   <owner>asvitkine@chromium.org</owner>
   <summary>
@@ -59655,6 +59682,15 @@
   </summary>
 </histogram>
 
+<histogram name="WebRTC.Video.CurrentDelayInMs" units="ms">
+  <owner>asapersson@chromium.org</owner>
+  <summary>
+    Average current delay for a received video stream. This is the actual delay
+    imposed on frames (where the goal is to reach the target delay (see
+    WebRTC.Video.TargetDelayInMs)). Recorded when a stream is removed.
+  </summary>
+</histogram>
+
 <histogram name="WebRTC.Video.Decoded.Vp8.Qp" units="qp value">
   <owner>asapersson@chromium.org</owner>
   <summary>
@@ -59824,6 +59860,14 @@
   </summary>
 </histogram>
 
+<histogram name="WebRTC.Video.JitterBufferDelayInMs" units="ms">
+  <owner>asapersson@chromium.org</owner>
+  <summary>
+    Average jitter buffer delay for a received video stream. Recorded when a
+    stream is removed.
+  </summary>
+</histogram>
+
 <histogram name="WebRTC.Video.KeyFramesReceivedInPermille" units="permille">
   <owner>asapersson@chromium.org</owner>
   <summary>
@@ -60346,6 +60390,14 @@
   </summary>
 </histogram>
 
+<histogram name="WebRTC.Video.TargetDelayInMs" units="ms">
+  <owner>asapersson@chromium.org</owner>
+  <summary>
+    Average target delay (jitter delay + decode time + render delay) for a
+    received video stream. Recorded when a stream is removed.
+  </summary>
+</histogram>
+
 <histogram name="WebRTC.Video.UniqueNackRequestsReceivedInPercent" units="%">
   <owner>asapersson@chromium.org</owner>
   <summary>
@@ -86389,6 +86441,8 @@
   <int value="8" label="EPHEMERAL_MISMATCH"/>
   <int value="9" label="PERSISTENT_MATCH"/>
   <int value="10" label="PERSISTENT_MISMATCH"/>
+  <int value="11" label="EPHEMERAL_UNKNOWN"/>
+  <int value="12" label="PERSISTENT_UNKNOWN"/>
 </enum>
 
 <enum name="TokenBinding.Support" type="int">
diff --git a/tools/perf/benchmarks/memory_infra.py b/tools/perf/benchmarks/memory_infra.py
index 1b62c17..ff90333 100644
--- a/tools/perf/benchmarks/memory_infra.py
+++ b/tools/perf/benchmarks/memory_infra.py
@@ -102,6 +102,27 @@
     return 'memory.top_10_mobile_tbmv2'
 
 
+# Benchmark is disabled by default because it takes too long to run.
+@benchmark.Disabled('all')
+class DualBrowserBenchmark(_MemoryInfra):
+  """Measures memory usage while interacting with two different browsers.
+
+  The user story involves going back and forth between doing Google searches
+  on a webview-based browser (a stand in for the Search app), and loading
+  pages on a select browser.
+  """
+  page_set = page_sets.DualBrowserStorySet
+  options = {'pageset_repeat': 5}
+
+  @classmethod
+  def Name(cls):
+    return 'memory.dual_browser_test'
+
+  def SetupBenchmarkDefaultTraceRerunOptions(self, tbm_options):
+    # This is a TBMv2 benchmark.
+    tbm_options.SetTimelineBasedMetric('memoryMetric')
+
+
 # TODO(bashi): Workaround for http://crbug.com/532075
 # @benchmark.Enabled('android') shouldn't be needed.
 @benchmark.Enabled('android')
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py
index d5e857cb5..70d3ca3 100644
--- a/tools/perf/benchmarks/v8.py
+++ b/tools/perf/benchmarks/v8.py
@@ -17,10 +17,6 @@
 from telemetry import story
 from telemetry.timeline import tracing_category_filter
 from telemetry.web_perf import timeline_based_measurement
-from telemetry.web_perf.metrics import v8_gc_latency
-from telemetry.web_perf.metrics import v8_execution
-from telemetry.web_perf.metrics import smoothness
-from telemetry.web_perf.metrics import memory_timeline
 
 
 def CreateV8TimelineBasedMeasurementOptions():
@@ -106,31 +102,19 @@
         'blink.console', 'renderer.scheduler', 'v8', 'webkit.console']
     smoothness_categories = [
         'webkit.console', 'blink.console', 'benchmark', 'trace_event_overhead']
-    categories = list(set(v8_categories + smoothness_categories))
-    memory_categories = 'blink.console,disabled-by-default-memory-infra'
+    memory_categories = ['blink.console', 'disabled-by-default-memory-infra']
     category_filter = tracing_category_filter.TracingCategoryFilter(
-        memory_categories)
-    for category in categories:
-      category_filter.AddIncludedCategory(category)
+        ','.join(['-*'] + v8_categories +
+                 smoothness_categories + memory_categories))
     options = timeline_based_measurement.Options(category_filter)
-    options.SetLegacyTimelineBasedMetrics([v8_gc_latency.V8GCLatency(),
-                                     v8_execution.V8ExecutionMetric(),
-                                     smoothness.SmoothnessMetric(),
-                                     memory_timeline.MemoryTimelineMetric()])
+    # TODO(ulan): Add frame time discrepancy once it is ported to TBMv2,
+    # see crbug.com/606841.
+    options.SetTimelineBasedMetric('v8AndMemoryMetrics')
     return options
 
   @classmethod
   def ValueCanBeAddedPredicate(cls, value, _):
-    if value.tir_label in ['Load', 'Wait']:
-      return (value.name.startswith('v8_') and not
-              value.name.startswith('v8_gc'))
-    if value.tir_label in ['Begin', 'End']:
-      return (value.name.startswith('memory_') and
-              'v8_renderer' in value.name) or \
-             (value.name.startswith('v8_') and not
-              value.name.startswith('v8_gc'))
-    else:
-      return value.tir_label == 'Scrolling'
+    return 'v8' in value.name
 
   @classmethod
   def ShouldTearDownStateAfterEachStoryRun(cls):
diff --git a/tools/perf/page_sets/data/dual_browser_story.json b/tools/perf/page_sets/data/dual_browser_story.json
new file mode 100644
index 0000000..ad336fe9
--- /dev/null
+++ b/tools/perf/page_sets/data/dual_browser_story.json
@@ -0,0 +1,27 @@
+{
+    "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.", 
+    "archives": {
+        "dual_browser_story_000.wpr": [
+            "google_movies_94110", 
+            "https_m_facebook_com_rihanna", 
+            "http_m_taobao_com_channel_act_mobile_20131111_women_html", 
+            "google_sfo_jfk_flights", 
+            "google_tom_hanks", 
+            "http_yandex_ru_touchsearch_text_science", 
+            "https_www_google_com_hl_en_q_science", 
+            "http_search_yahoo_com_search__ylt_p_google", 
+            "http_www_amazon_com_gp_aw_s_k_nexus", 
+            "google_weather_94110", 
+            "google_tip_on_100_bill", 
+            "http_en_m_wikipedia_org_wiki_Science", 
+            "http_m_youtube_com_results_q_science", 
+            "google_cat_pictures", 
+            "https_mobile_twitter_com_justinbieber_skip_interstitial_true", 
+            "http_www_baidu_com_s_word_google", 
+            "google_science", 
+            "google_population_of_california", 
+            "google_1600_amphitheatre_pkwy_mountain_view_ca", 
+            "google_goog"
+        ]
+    }
+}
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/dual_browser_story_000.wpr.sha1 b/tools/perf/page_sets/data/dual_browser_story_000.wpr.sha1
new file mode 100644
index 0000000..85419235
--- /dev/null
+++ b/tools/perf/page_sets/data/dual_browser_story_000.wpr.sha1
@@ -0,0 +1 @@
+5aee1aa43e9e79b79a6cdd639101b0f2c8efbd69
\ No newline at end of file
diff --git a/tools/perf/page_sets/dual_browser_story.py b/tools/perf/page_sets/dual_browser_story.py
new file mode 100644
index 0000000..679f28f
--- /dev/null
+++ b/tools/perf/page_sets/dual_browser_story.py
@@ -0,0 +1,243 @@
+# 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 collections
+import logging
+import re
+import sys
+import urllib
+
+from telemetry import decorators
+from telemetry import story as story_module
+# TODO(perezju): Remove references to telementry.internal when
+# https://github.com/catapult-project/catapult/issues/2102 is resolved.
+from telemetry.internal.browser import browser_finder
+from telemetry.internal.browser import browser_finder_exceptions
+from telemetry.util import wpr_modes
+
+from page_sets.top_10_mobile import URL_LIST
+
+
+GOOGLE_SEARCH = 'https://www.google.com/search?'
+
+SEARCH_QUERIES = [
+  'science',
+  'cat pictures',
+  '1600 Amphitheatre Pkwy, Mountain View, CA',
+  'tom hanks',
+  'weather 94110',
+  'goog',
+  'population of california',
+  'sfo jfk flights',
+  'movies 94110',
+  'tip on 100 bill'
+]
+
+
+def _OptionsForBrowser(browser_type, finder_options):
+  """Return options used to get a browser of the given type.
+
+  TODO(perezju): Currently this clones the finder_options passed via the
+  command line to telemetry. When browser_options are split appart from
+  finder_options (crbug.com/570348) we will be able to construct our own
+  browser_options as needed.
+  """
+  finder_options = finder_options.Copy()
+  finder_options.browser_type = browser_type
+  finder_options.browser_executable = None
+  finder_options.browser_options.browser_type = browser_type
+  return finder_options
+
+
+class MultiBrowserSharedState(story_module.SharedState):
+  def __init__(self, test, finder_options, story_set):
+    """A shared state to run a test involving multiple browsers.
+
+    The story_set is expected to include SinglePage instances (class defined
+    below) mapping each page to a browser on which to run. The state
+    requires at least one page to run on the 'default' browser, i.e. the
+    browser selected from the command line by the user.
+    """
+    super(MultiBrowserSharedState, self).__init__(
+        test, finder_options, story_set)
+    self._platform = None
+    self._story_set = story_set
+    self._possible_browsers = {}
+    # We use an ordered dict to request memory dumps in a deterministic order.
+    self._browsers = collections.OrderedDict()
+    self._current_story = None
+    self._current_browser = None
+    self._current_tab = None
+
+    possible_browser = self._PrepareBrowser('default', finder_options)
+    if not possible_browser:
+      raise browser_finder_exceptions.BrowserFinderException(
+          'No browser found.\n\nAvailable browsers:\n%s\n' %
+          '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)))
+    if not finder_options.run_disabled_tests:
+      self._CheckTestEnabled(test, possible_browser)
+
+    extra_browser_types = set(story.browser_type for story in story_set)
+    extra_browser_types.remove('default')  # Must include 'default' browser.
+    for browser_type in extra_browser_types:
+      options = _OptionsForBrowser(browser_type, finder_options)
+      if not self._PrepareBrowser(browser_type, options):
+        logging.warning('Skipping %s (%s) because %s browser is not available',
+                        test.__name__, str(test), browser_type)
+        logging.warning('Install %s to be able to run the test.', browser_type)
+        sys.exit(0)
+
+    # TODO(crbug/404771): Move network controller options out of
+    # browser_options and into finder_options.
+    browser_options = finder_options.browser_options
+    if finder_options.use_live_sites:
+      wpr_mode = wpr_modes.WPR_OFF
+    elif browser_options.wpr_mode == wpr_modes.WPR_RECORD:
+      wpr_mode = wpr_modes.WPR_RECORD
+    else:
+      wpr_mode = wpr_modes.WPR_REPLAY
+
+    self.platform.network_controller.Open(wpr_mode,
+                                          browser_options.extra_wpr_args)
+
+  @property
+  def current_tab(self):
+    return self._current_tab
+
+  @property
+  def platform(self):
+    return self._platform
+
+  def _CheckTestEnabled(self, test, possible_browser):
+    should_skip, msg = decorators.ShouldSkip(test, possible_browser)
+    if should_skip:
+      logging.warning(msg)
+      logging.warning('You are trying to run a disabled test.')
+      logging.warning(
+          'Pass --also-run-disabled-tests to squelch this message.')
+      sys.exit(0)
+
+  def _PrepareBrowser(self, browser_type, options):
+    """Add a browser to the dict of possible browsers.
+
+    TODO(perezju): When available, use the GetBrowserForPlatform API instead.
+    See: crbug.com/570348
+
+    Returns:
+      The possible browser if found, or None otherwise.
+    """
+    possible_browser = browser_finder.FindBrowser(options)
+    if possible_browser is None:
+      return None
+
+    if self._platform is None:
+      self._platform = possible_browser.platform
+    else:
+      assert self._platform is possible_browser.platform
+    self._possible_browsers[browser_type] = (possible_browser, options)
+    return possible_browser
+
+  def _SetCurrentBrowser(self, browser_type):
+    """Select a browser of the given type and bring it to the foreground.
+
+    This launches the browser if it does not exist already or, otherwise, moves
+    the existing browser to the foreground.
+    """
+    if not browser_type in self._browsers:
+      possible_browser, options = self._possible_browsers[browser_type]
+      self._current_browser = possible_browser.Create(options)
+      self._browsers[browser_type] = self._current_browser
+    else:
+      self._current_browser = self._browsers[browser_type]
+      self._current_browser.Foreground()
+
+  def CanRunStory(self, _):
+    return True
+
+  def WillRunStory(self, story):
+    self._current_story = story
+
+    self.platform.network_controller.StartReplay(
+        self._story_set.WprFilePathForStory(story),
+        story.make_javascript_deterministic)
+
+    self._SetCurrentBrowser(self._current_story.browser_type)
+    self._current_tab = self._current_browser.foreground_tab
+
+  def RunStory(self, _):
+    self._current_story.Run(self)
+
+  def DidRunStory(self, _):
+    self._current_story = None
+
+  def TakeMemoryMeasurement(self):
+    self.current_tab.action_runner.ForceGarbageCollection()
+    self.platform.FlushEntireSystemCache()
+    if not self.platform.tracing_controller.is_tracing_running:
+      return  # Tracing is not running, e.g., when recording a WPR archive.
+    for browser_type, browser in self._browsers.iteritems():
+      if not browser.DumpMemory():
+        logging.error('Unable to dump memory for %s', browser_type)
+
+  def TearDownState(self):
+    self.platform.network_controller.Close()
+
+    for browser_type, browser in self._browsers.iteritems():
+      try:
+        browser.Close()
+      except Exception:
+        logging.exception('Error while closing browser: %s', browser_type)
+    self._browsers = None  # Not usable after tearing down.
+
+
+class SinglePage(story_module.Story):
+  def __init__(self, name, url, browser_type, phase):
+    """A story that associates a particular page with a browser to view it.
+
+    Args:
+      name: A string with the name of the page as it will appear reported,
+        e.g., on results and dashboards.
+      url: A string with the url of the page to load.
+      browser_type: A string identifying the browser where this page should be
+        displayed. Accepts the same strings as the command line --browser
+        option (e.g. 'android-webview'), and the special value 'default' to
+        select the browser chosen by the user on the command line.
+    """
+    super(SinglePage, self).__init__(MultiBrowserSharedState, name=name)
+    self._url = url
+    self._browser_type = browser_type
+    self.grouping_keys['phase'] = phase
+
+  @property
+  def browser_type(self):
+    return self._browser_type
+
+  def Run(self, shared_state):
+    shared_state.current_tab.Navigate(self._url)
+    shared_state.current_tab.WaitForDocumentReadyStateToBeComplete()
+    shared_state.TakeMemoryMeasurement()
+
+
+class DualBrowserStorySet(story_module.StorySet):
+  """A story set that switches back and forth between two browsers."""
+
+  def __init__(self):
+    super(DualBrowserStorySet, self).__init__(
+        archive_data_file='data/dual_browser_story.json',
+        cloud_storage_bucket=story_module.PARTNER_BUCKET)
+
+    for query, url in zip(SEARCH_QUERIES, URL_LIST):
+      # Stories that run on the android-webview browser.
+      self.AddStory(SinglePage(
+          name='google_%s' % re.sub('\W+', '_', query.lower()),
+          url=GOOGLE_SEARCH + urllib.urlencode({'q': query}),
+          browser_type='android-webview',
+          phase='on_webview'))
+
+      # Stories that run on the browser selected by command line options.
+      self.AddStory(SinglePage(
+          name=re.sub('\W+', '_', url),
+          url=url,
+          browser_type='default',
+          phase='on_chrome'))
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp
index 62fa29f..2372dca 100644
--- a/ui/aura/aura.gyp
+++ b/ui/aura/aura.gyp
@@ -117,6 +117,7 @@
             '../../build/linux/system.gyp:x11',
             '../../build/linux/system.gyp:xrandr',
             '../../build/linux/system.gyp:xi',
+            '../base/x/ui_base_x.gyp:ui_base_x',
             '../events/devices/events_devices.gyp:events_devices',
             '../events/devices/x11/events_devices_x11.gyp:events_devices_x11',
             '../events/platform/x11/x11_events_platform.gyp:x11_events_platform',
@@ -201,6 +202,13 @@
       ],
       # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       'msvs_disabled_warnings': [ 4267, ],
+      'conditions': [
+        ['use_x11==1', {
+          'dependencies': [
+            '../base/x/ui_base_x.gyp:ui_base_x',
+          ],
+        }],
+      ],
     },
     {
       'target_name': 'aura_demo',
diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc
index c5a2277..2161449 100644
--- a/ui/aura/test/aura_test_helper.cc
+++ b/ui/aura/test/aura_test_helper.cc
@@ -26,7 +26,7 @@
 
 #if defined(USE_X11)
 #include "ui/aura/window_tree_host_x11.h"
-#include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util.h"  // nogncheck
 #endif
 
 namespace aura {
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 8fe9f68b..4f8eb0a5 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -390,8 +390,27 @@
     deps += [ "//ui/events" ]
   }
 
+  if (use_x11) {
+    public_deps += [ "//ui/base/x" ]
+    configs += [ "//build/config/linux:x11" ]
+
+    if (!is_chromeos) {
+      sources += [
+        "idle/idle_query_x11.cc",
+        "idle/idle_query_x11.h",
+        "idle/screensaver_window_finder_x11.cc",
+        "idle/screensaver_window_finder_x11.h",
+      ]
+      configs += [ "//build/config/linux:xscrnsaver" ]
+      deps += [ "//ui/gfx/x" ]
+    }
+  }
+
   if (use_x11 && use_aura) {
     sources += [
+      "cursor/cursor_loader_x11.cc",
+      "cursor/cursor_loader_x11.h",
+      "cursor/cursor_x11.cc",
       "x/selection_owner.cc",
       "x/selection_owner.h",
       "x/selection_requestor.cc",
@@ -399,7 +418,18 @@
       "x/selection_utils.cc",
       "x/selection_utils.h",
     ]
-    deps += [ "//ui/events/platform/x11" ]
+    deps += [
+      "//ui/events/platform/x11",
+      "//ui/gfx/x",
+    ]
+
+    if (!is_chromeos) {
+      # These Aura X11 files aren't used on ChromeOS.
+      sources += [
+        "dragdrop/os_exchange_data_provider_aurax11.cc",
+        "dragdrop/os_exchange_data_provider_aurax11.h",
+      ]
+    }
   }
 
   if (use_aura) {
@@ -413,33 +443,6 @@
     ]
   }
 
-  # TODO(kylechar): remove ozone_platform_x11 from here.
-  if (use_x11 || ozone_platform_x11) {
-    sources += [
-      "x/x11_foreign_window_manager.cc",
-      "x/x11_foreign_window_manager.h",
-      "x/x11_menu_list.cc",
-      "x/x11_menu_list.h",
-      "x/x11_util.cc",
-      "x/x11_util.h",
-      "x/x11_util_internal.h",
-    ]
-    if (!is_chromeos) {
-      sources += [
-        "idle/idle_query_x11.cc",
-        "idle/idle_query_x11.h",
-        "idle/screensaver_window_finder_x11.cc",
-        "idle/screensaver_window_finder_x11.h",
-      ]
-      configs += [ "//build/config/linux:xscrnsaver" ]
-    }
-    deps += [
-      "//ui/events/devices/x11",
-      "//ui/events/keycodes:x11",
-      "//ui/gfx/x",
-    ]
-  }
-
   if (!use_aura || !is_linux) {
     sources -= [ "resource/resource_bundle_auralinux.cc" ]
   }
@@ -527,30 +530,7 @@
     ]
   }
 
-  if (use_x11 || ozone_platform_x11) {
-    #'all_dependent_settings': {
-    #'ldflags': [
-    #'-L<(PRODUCT_DIR)',
-    #],
-    #},
-    configs += [ "//build/config/linux:x11" ]
-  }
-
   if (use_aura) {
-    if (use_x11) {
-      sources += [
-        "cursor/cursor_loader_x11.cc",
-        "cursor/cursor_loader_x11.h",
-        "cursor/cursor_x11.cc",
-      ]
-      if (!is_chromeos) {
-        # These Aura X11 files aren't used on ChromeOS.
-        sources += [
-          "dragdrop/os_exchange_data_provider_aurax11.cc",
-          "dragdrop/os_exchange_data_provider_aurax11.h",
-        ]
-      }
-    }
     if (is_android) {
       sources += [ "cursor/cursor_loader_android.cc" ]
     }
@@ -615,10 +595,16 @@
   # Aura clipboard.
   if (use_aura) {
     if (use_x11) {
-      sources += [ "clipboard/clipboard_aurax11.cc" ]
+      sources += [
+        "clipboard/clipboard_aurax11.cc",
+        "clipboard/clipboard_aurax11.h",
+      ]
     } else if (!is_win && !is_android) {
       # This file is used for all non-X11, non-Windows, non-Android aura Builds.
-      sources += [ "clipboard/clipboard_aura.cc" ]
+      sources += [
+        "clipboard/clipboard_aura.cc",
+        "clipboard/clipboard_aura.h",
+      ]
     }
   }
 
diff --git a/ui/base/test/scoped_fake_nswindow_fullscreen.h b/ui/base/test/scoped_fake_nswindow_fullscreen.h
index 8424932..6a5e639 100644
--- a/ui/base/test/scoped_fake_nswindow_fullscreen.h
+++ b/ui/base/test/scoped_fake_nswindow_fullscreen.h
@@ -24,6 +24,9 @@
   ScopedFakeNSWindowFullscreen();
   ~ScopedFakeNSWindowFullscreen();
 
+  // Wait for any transition in progress to complete.
+  void FinishTransition();
+
  private:
   std::unique_ptr<Impl> impl_;
 
diff --git a/ui/base/test/scoped_fake_nswindow_fullscreen.mm b/ui/base/test/scoped_fake_nswindow_fullscreen.mm
index 1fcd8949..0dc9db7d 100644
--- a/ui/base/test/scoped_fake_nswindow_fullscreen.mm
+++ b/ui/base/test/scoped_fake_nswindow_fullscreen.mm
@@ -14,6 +14,7 @@
 #import "base/mac/sdk_forward_declarations.h"
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 
 // This method exists on NSWindowDelegate on 10.7+.
 // To build on 10.6, we just need to declare it somewhere. We'll test
@@ -175,6 +176,8 @@
     style_as_fullscreen_ = false;
   }
 
+  bool is_in_transition() { return is_in_transition_; }
+
  private:
   base::mac::ScopedObjCClassSwizzler toggle_fullscreen_swizzler_;
   base::mac::ScopedObjCClassSwizzler style_mask_swizzler_;
@@ -205,6 +208,13 @@
   g_fake_fullscreen_impl = nullptr;
 }
 
+void ScopedFakeNSWindowFullscreen::FinishTransition() {
+  if (impl_->is_in_transition())
+    base::RunLoop().RunUntilIdle();
+
+  DCHECK(!impl_->is_in_transition());
+}
+
 }  // namespace test
 }  // namespace ui
 
diff --git a/ui/base/ui_base.gyp b/ui/base/ui_base.gyp
index 6d8216f..58797100 100644
--- a/ui/base/ui_base.gyp
+++ b/ui/base/ui_base.gyp
@@ -393,13 +393,6 @@
         'x/selection_requestor.h',
         'x/selection_utils.cc',
         'x/selection_utils.h',
-        'x/x11_foreign_window_manager.cc',
-        'x/x11_foreign_window_manager.h',
-        'x/x11_menu_list.cc',
-        'x/x11_menu_list.h',
-        'x/x11_util.cc',
-        'x/x11_util.h',
-        'x/x11_util_internal.h',
       ],
       'target_conditions': [
         ['OS == "ios"', {
@@ -608,6 +601,7 @@
             '../events/devices/x11/events_devices_x11.gyp:events_devices_x11',
             '../events/platform/x11/x11_events_platform.gyp:x11_events_platform',
             '../gfx/x/gfx_x11.gyp:gfx_x11',
+            'x/ui_base_x.gyp:ui_base_x',
           ],
         }],
         ['use_x11==1 and chromeos==0', {
diff --git a/ui/base/ui_base_tests.gyp b/ui/base/ui_base_tests.gyp
index deae507..8e81b834 100644
--- a/ui/base/ui_base_tests.gyp
+++ b/ui/base/ui_base_tests.gyp
@@ -175,6 +175,7 @@
             '../../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck',
             '../events/platform/x11/x11_events_platform.gyp:x11_events_platform',
             '../gfx/x/gfx_x11.gyp:gfx_x11',
+            'x/ui_base_x.gyp:ui_base_x',
           ],
         }],
         ['OS!="win" or use_aura==0', {
diff --git a/ui/base/x/BUILD.gn b/ui/base/x/BUILD.gn
new file mode 100644
index 0000000..6be1ed61
--- /dev/null
+++ b/ui/base/x/BUILD.gn
@@ -0,0 +1,33 @@
+# 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.
+
+component("x") {
+  output_name = "ui_base_x"
+
+  sources = [
+    "ui_base_x_export.h",
+    "x11_foreign_window_manager.cc",
+    "x11_foreign_window_manager.h",
+    "x11_menu_list.cc",
+    "x11_menu_list.h",
+    "x11_util.cc",
+    "x11_util.h",
+    "x11_util_internal.h",
+  ]
+
+  configs += [ "//build/config/linux:x11" ]
+
+  defines = [ "UI_BASE_X_IMPLEMENTATION" ]
+
+  deps = [
+    "//base",
+    "//base:i18n",
+    "//skia",
+    "//ui/events",
+    "//ui/events/devices/x11",
+    "//ui/events/keycodes:x11",
+    "//ui/gfx",
+    "//ui/gfx/x",
+  ]
+}
diff --git a/ui/base/x/ui_base_x.gyp b/ui/base/x/ui_base_x.gyp
new file mode 100644
index 0000000..6b88e89
--- /dev/null
+++ b/ui/base/x/ui_base_x.gyp
@@ -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.
+
+{
+  'variables': {
+    'chromium_code': 1,
+  },
+  'targets': [
+    {
+      # GN version: //ui/base/x
+      'target_name': 'ui_base_x',
+      'type': '<(component)',
+      'all_dependent_settings': {
+        'ldflags': [
+          '-L<(PRODUCT_DIR)',
+        ],
+      },
+      'dependencies': [
+        '<(DEPTH)/base/base.gyp:base',
+        '<(DEPTH)/base/base.gyp:base_i18n',
+        '<(DEPTH)/build/linux/system.gyp:x11',
+        '<(DEPTH)/build/linux/system.gyp:xcursor',
+        '<(DEPTH)/build/linux/system.gyp:xext',
+        '<(DEPTH)/build/linux/system.gyp:xfixes',
+        '<(DEPTH)/build/linux/system.gyp:xrender',  # For XRender* function calls in x11_util.cc.
+        '<(DEPTH)/skia/skia.gyp:skia',
+        '../../events/events.gyp:events',
+        '../../events/devices/x11/events_devices_x11.gyp:events_devices_x11',
+        '../../gfx/gfx.gyp:gfx',
+        '../../gfx/gfx.gyp:gfx_geometry',
+        '../../gfx/x/gfx_x11.gyp:gfx_x11',
+      ],
+      'defines': [
+        'UI_BASE_X_IMPLEMENTATION',
+      ],
+      'sources': [
+        'ui_base_x_export.h',
+        'x11_foreign_window_manager.cc',
+        'x11_foreign_window_manager.h',
+        'x11_menu_list.cc',
+        'x11_menu_list.h',
+        'x11_util.cc',
+        'x11_util.h',
+        'x11_util_internal.h',
+      ],
+    },
+  ],
+}
diff --git a/ui/base/x/ui_base_x_export.h b/ui/base/x/ui_base_x_export.h
new file mode 100644
index 0000000..ddc5036
--- /dev/null
+++ b/ui/base/x/ui_base_x_export.h
@@ -0,0 +1,37 @@
+// 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 UI_BASE_X_UI_BASE_X_EXPORT_H_
+#define UI_BASE_X_UI_BASE_X_EXPORT_H_
+
+// Defines UI_BASE_X_EXPORT so that functionality implemented by the UI module
+// can be exported to consumers.
+
+#if defined(COMPONENT_BUILD)
+
+#if defined(WIN32)
+
+#if defined(UI_BASE_X_IMPLEMENTATION)
+#define UI_BASE_X_EXPORT __declspec(dllexport)
+#else
+#define UI_BASE_X_EXPORT __declspec(dllimport)
+#endif
+
+#else  // !defined(WIN32)
+
+#if defined(UI_BASE_X_IMPLEMENTATION)
+#define UI_BASE_X_EXPORT __attribute__((visibility("default")))
+#else
+#define UI_BASE_X_EXPORT
+#endif
+
+#endif
+
+#else  // !defined(COMPONENT_BUILD)
+
+#define UI_BASE_X_EXPORT
+
+#endif
+
+#endif  // UI_BASE_X_UI_BASE_X_EXPORT_H_
diff --git a/ui/base/x/x11_foreign_window_manager.h b/ui/base/x/x11_foreign_window_manager.h
index 55da51e..e09de7d 100644
--- a/ui/base/x/x11_foreign_window_manager.h
+++ b/ui/base/x/x11_foreign_window_manager.h
@@ -10,7 +10,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "ui/base/ui_base_export.h"
+#include "ui/base/x/ui_base_x_export.h"
 #include "ui/gfx/x/x11_types.h"
 
 // A process wide singleton for selecting events on X windows which were not
@@ -24,7 +24,7 @@
 // Manages the events that Chrome has selected on X windows which were not
 // created by Chrome. This class allows several clients to select events
 // on the same X window.
-class UI_BASE_EXPORT XForeignWindowManager {
+class UI_BASE_X_EXPORT XForeignWindowManager {
  public:
   static XForeignWindowManager* GetInstance();
 
diff --git a/ui/base/x/x11_menu_list.h b/ui/base/x/x11_menu_list.h
index 6986f1c..87d412d 100644
--- a/ui/base/x/x11_menu_list.h
+++ b/ui/base/x/x11_menu_list.h
@@ -8,7 +8,7 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "ui/base/ui_base_export.h"
+#include "ui/base/x/ui_base_x_export.h"
 #include "ui/gfx/x/x11_types.h"
 
 // A process wide singleton cache for X menus.
@@ -19,7 +19,7 @@
 namespace ui {
 
 // Keeps track of created and destroyed top level menu windows.
-class UI_BASE_EXPORT XMenuList {
+class UI_BASE_X_EXPORT XMenuList {
  public:
   static XMenuList* GetInstance();
 
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h
index c3c9c2b..0709114 100644
--- a/ui/base/x/x11_util.h
+++ b/ui/base/x/x11_util.h
@@ -19,7 +19,7 @@
 #include "base/event_types.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted_memory.h"
-#include "ui/base/ui_base_export.h"
+#include "ui/base/x/ui_base_x_export.h"
 #include "ui/events/event_constants.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/x/x11_types.h"
@@ -45,94 +45,95 @@
 // These functions cache their results ---------------------------------
 
 // Returns true if the system supports XINPUT2.
-UI_BASE_EXPORT bool IsXInput2Available();
+UI_BASE_X_EXPORT bool IsXInput2Available();
 
 // Return true iff the display supports Xrender
-UI_BASE_EXPORT bool QueryRenderSupport(XDisplay* dpy);
+UI_BASE_X_EXPORT bool QueryRenderSupport(XDisplay* dpy);
 
 // Returns an X11 Cursor, sharable across the process.
 // |cursor_shape| is an X font cursor shape, see XCreateFontCursor().
-UI_BASE_EXPORT ::Cursor GetXCursor(int cursor_shape);
+UI_BASE_X_EXPORT::Cursor GetXCursor(int cursor_shape);
 
 // Creates a custom X cursor from the image. This takes ownership of image. The
 // caller must not free/modify the image. The refcount of the newly created
 // cursor is set to 1.
-UI_BASE_EXPORT ::Cursor CreateReffedCustomXCursor(XcursorImage* image);
+UI_BASE_X_EXPORT::Cursor CreateReffedCustomXCursor(XcursorImage* image);
 
 // Increases the refcount of the custom cursor.
-UI_BASE_EXPORT void RefCustomXCursor(::Cursor cursor);
+UI_BASE_X_EXPORT void RefCustomXCursor(::Cursor cursor);
 
 // Decreases the refcount of the custom cursor, and destroys it if it reaches 0.
-UI_BASE_EXPORT void UnrefCustomXCursor(::Cursor cursor);
+UI_BASE_X_EXPORT void UnrefCustomXCursor(::Cursor cursor);
 
 // Creates a XcursorImage and copies the SkBitmap |bitmap| on it. |bitmap|
 // should be non-null. Caller owns the returned object.
-UI_BASE_EXPORT XcursorImage* SkBitmapToXcursorImage(const SkBitmap* bitmap,
-                                                    const gfx::Point& hotspot);
+UI_BASE_X_EXPORT XcursorImage* SkBitmapToXcursorImage(
+    const SkBitmap* bitmap,
+    const gfx::Point& hotspot);
 
 // Coalesce all pending motion events (touch or mouse) that are at the top of
 // the queue, and return the number eliminated, storing the last one in
 // |last_event|.
-UI_BASE_EXPORT int CoalescePendingMotionEvents(const XEvent* xev,
-                                               XEvent* last_event);
+UI_BASE_X_EXPORT int CoalescePendingMotionEvents(const XEvent* xev,
+                                                 XEvent* last_event);
 
 // Hides the host cursor.
-UI_BASE_EXPORT void HideHostCursor();
+UI_BASE_X_EXPORT void HideHostCursor();
 
 // Returns an invisible cursor.
-UI_BASE_EXPORT ::Cursor CreateInvisibleCursor();
+UI_BASE_X_EXPORT::Cursor CreateInvisibleCursor();
 
 // Sets whether |window| should use the OS window frame.
-UI_BASE_EXPORT void SetUseOSWindowFrame(XID window, bool use_os_window_frame);
+UI_BASE_X_EXPORT void SetUseOSWindowFrame(XID window, bool use_os_window_frame);
 
 // These functions do not cache their results --------------------------
 
 // Returns true if the shape extension is supported.
-UI_BASE_EXPORT bool IsShapeExtensionAvailable();
+UI_BASE_X_EXPORT bool IsShapeExtensionAvailable();
 
 // Get the X window id for the default root window
-UI_BASE_EXPORT XID GetX11RootWindow();
+UI_BASE_X_EXPORT XID GetX11RootWindow();
 
 // Returns the user's current desktop.
-UI_BASE_EXPORT bool GetCurrentDesktop(int* desktop);
+UI_BASE_X_EXPORT bool GetCurrentDesktop(int* desktop);
 
 enum HideTitlebarWhenMaximized {
   SHOW_TITLEBAR_WHEN_MAXIMIZED = 0,
   HIDE_TITLEBAR_WHEN_MAXIMIZED = 1,
 };
 // Sets _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED on |window|.
-UI_BASE_EXPORT void SetHideTitlebarWhenMaximizedProperty(
+UI_BASE_X_EXPORT void SetHideTitlebarWhenMaximizedProperty(
     XID window,
     HideTitlebarWhenMaximized property);
 
 // Clears all regions of X11's default root window by filling black pixels.
-UI_BASE_EXPORT void ClearX11DefaultRootWindow();
+UI_BASE_X_EXPORT void ClearX11DefaultRootWindow();
 
 // Returns true if |window| is visible.
-UI_BASE_EXPORT bool IsWindowVisible(XID window);
+UI_BASE_X_EXPORT bool IsWindowVisible(XID window);
 
 // Returns the inner bounds of |window| (excluding the non-client area).
-UI_BASE_EXPORT bool GetInnerWindowBounds(XID window, gfx::Rect* rect);
+UI_BASE_X_EXPORT bool GetInnerWindowBounds(XID window, gfx::Rect* rect);
 
 // Returns the non-client area extents of |window|. This is a negative inset; it
 // represents the negative size of the window border on all sides.
 // InnerWindowBounds.Inset(WindowExtents) = OuterWindowBounds.
 // Returns false if the window manager does not provide extents information.
-UI_BASE_EXPORT bool GetWindowExtents(XID window, gfx::Insets* extents);
+UI_BASE_X_EXPORT bool GetWindowExtents(XID window, gfx::Insets* extents);
 
 // Returns the outer bounds of |window| (including the non-client area).
-UI_BASE_EXPORT bool GetOuterWindowBounds(XID window, gfx::Rect* rect);
+UI_BASE_X_EXPORT bool GetOuterWindowBounds(XID window, gfx::Rect* rect);
 
 // Returns true if |window| contains the point |screen_loc|.
-UI_BASE_EXPORT bool WindowContainsPoint(XID window, gfx::Point screen_loc);
+UI_BASE_X_EXPORT bool WindowContainsPoint(XID window, gfx::Point screen_loc);
 
 // Return true if |window| has any property with |property_name|.
-UI_BASE_EXPORT bool PropertyExists(XID window,
-                                   const std::string& property_name);
+UI_BASE_X_EXPORT bool PropertyExists(XID window,
+                                     const std::string& property_name);
 
 // Returns the raw bytes from a property with minimal
 // interpretation. |out_data| should be freed by XFree() after use.
-UI_BASE_EXPORT bool GetRawBytesOfProperty(
+UI_BASE_X_EXPORT bool GetRawBytesOfProperty(
     XID window,
     XAtom property,
     scoped_refptr<base::RefCountedMemory>* out_data,
@@ -144,61 +145,61 @@
 //
 // TODO(erg): Once we remove the gtk port and are 100% aura, all of these
 // should accept an XAtom instead of a string.
-UI_BASE_EXPORT bool GetIntProperty(XID window,
-                                   const std::string& property_name,
-                                   int* value);
-UI_BASE_EXPORT bool GetXIDProperty(XID window,
-                                   const std::string& property_name,
-                                   XID* value);
-UI_BASE_EXPORT bool GetIntArrayProperty(XID window,
+UI_BASE_X_EXPORT bool GetIntProperty(XID window,
+                                     const std::string& property_name,
+                                     int* value);
+UI_BASE_X_EXPORT bool GetXIDProperty(XID window,
+                                     const std::string& property_name,
+                                     XID* value);
+UI_BASE_X_EXPORT bool GetIntArrayProperty(XID window,
+                                          const std::string& property_name,
+                                          std::vector<int>* value);
+UI_BASE_X_EXPORT bool GetAtomArrayProperty(XID window,
+                                           const std::string& property_name,
+                                           std::vector<XAtom>* value);
+UI_BASE_X_EXPORT bool GetStringProperty(XID window,
                                         const std::string& property_name,
-                                        std::vector<int>* value);
-UI_BASE_EXPORT bool GetAtomArrayProperty(XID window,
-                                         const std::string& property_name,
-                                         std::vector<XAtom>* value);
-UI_BASE_EXPORT bool GetStringProperty(XID window,
-                                      const std::string& property_name,
-                                      std::string* value);
+                                        std::string* value);
 
 // These setters all make round trips.
-UI_BASE_EXPORT bool SetIntProperty(XID window,
-                                   const std::string& name,
-                                   const std::string& type,
-                                   int value);
-UI_BASE_EXPORT bool SetIntArrayProperty(XID window,
-                                        const std::string& name,
-                                        const std::string& type,
-                                        const std::vector<int>& value);
-UI_BASE_EXPORT bool SetAtomProperty(XID window,
-                                    const std::string& name,
-                                    const std::string& type,
-                                    XAtom value);
-UI_BASE_EXPORT bool SetAtomArrayProperty(XID window,
-                                         const std::string& name,
-                                         const std::string& type,
-                                         const std::vector<XAtom>& value);
-UI_BASE_EXPORT bool SetStringProperty(XID window,
-                                      XAtom property,
-                                      XAtom type,
-                                      const std::string& value);
+UI_BASE_X_EXPORT bool SetIntProperty(XID window,
+                                     const std::string& name,
+                                     const std::string& type,
+                                     int value);
+UI_BASE_X_EXPORT bool SetIntArrayProperty(XID window,
+                                          const std::string& name,
+                                          const std::string& type,
+                                          const std::vector<int>& value);
+UI_BASE_X_EXPORT bool SetAtomProperty(XID window,
+                                      const std::string& name,
+                                      const std::string& type,
+                                      XAtom value);
+UI_BASE_X_EXPORT bool SetAtomArrayProperty(XID window,
+                                           const std::string& name,
+                                           const std::string& type,
+                                           const std::vector<XAtom>& value);
+UI_BASE_X_EXPORT bool SetStringProperty(XID window,
+                                        XAtom property,
+                                        XAtom type,
+                                        const std::string& value);
 
 // Gets the X atom for default display corresponding to atom_name.
-UI_BASE_EXPORT XAtom GetAtom(const char* atom_name);
+UI_BASE_X_EXPORT XAtom GetAtom(const char* atom_name);
 
 // Sets the WM_CLASS attribute for a given X11 window.
-UI_BASE_EXPORT void SetWindowClassHint(XDisplay* display,
-                                       XID window,
-                                       const std::string& res_name,
-                                       const std::string& res_class);
+UI_BASE_X_EXPORT void SetWindowClassHint(XDisplay* display,
+                                         XID window,
+                                         const std::string& res_name,
+                                         const std::string& res_class);
 
 // Sets the WM_WINDOW_ROLE attribute for a given X11 window.
-UI_BASE_EXPORT void SetWindowRole(XDisplay* display,
-                                  XID window,
-                                  const std::string& role);
+UI_BASE_X_EXPORT void SetWindowRole(XDisplay* display,
+                                    XID window,
+                                    const std::string& role);
 
 // Determine whether we should default to native decorations or the custom
 // frame based on the currently-running window manager.
-UI_BASE_EXPORT bool GetCustomFramePrefDefault();
+UI_BASE_X_EXPORT bool GetCustomFramePrefDefault();
 
 static const int kAllDesktops = -1;
 // Queries the desktop |window| is on, kAllDesktops if sticky. Returns false if
@@ -206,7 +207,7 @@
 bool GetWindowDesktop(XID window, int* desktop);
 
 // Translates an X11 error code into a printable string.
-UI_BASE_EXPORT std::string GetX11ErrorString(XDisplay* display, int err);
+UI_BASE_X_EXPORT std::string GetX11ErrorString(XDisplay* display, int err);
 
 // Implementers of this interface receive a notification for every X window of
 // the main display.
@@ -222,26 +223,26 @@
 
 // Enumerates all windows in the current display.  Will recurse into child
 // windows up to a depth of |max_depth|.
-UI_BASE_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate,
-                                        int max_depth);
+UI_BASE_X_EXPORT bool EnumerateAllWindows(EnumerateWindowsDelegate* delegate,
+                                          int max_depth);
 
 // Enumerates the top-level windows of the current display.
-UI_BASE_EXPORT void EnumerateTopLevelWindows(
+UI_BASE_X_EXPORT void EnumerateTopLevelWindows(
     ui::EnumerateWindowsDelegate* delegate);
 
 // Returns all children windows of a given window in top-to-bottom stacking
 // order.
-UI_BASE_EXPORT bool GetXWindowStack(XID window, std::vector<XID>* windows);
+UI_BASE_X_EXPORT bool GetXWindowStack(XID window, std::vector<XID>* windows);
 
 // Copies |source_bounds| from |drawable| to |canvas| at offset |dest_offset|.
 // |source_bounds| is in physical pixels, while |dest_offset| is relative to
 // the canvas's scale. Note that this function is slow since it uses
 // XGetImage() to copy the data from the X server to this process before
 // copying it to |canvas|.
-UI_BASE_EXPORT bool CopyAreaToCanvas(XID drawable,
-                                     gfx::Rect source_bounds,
-                                     gfx::Point dest_offset,
-                                     gfx::Canvas* canvas);
+UI_BASE_X_EXPORT bool CopyAreaToCanvas(XID drawable,
+                                       gfx::Rect source_bounds,
+                                       gfx::Point dest_offset,
+                                       gfx::Canvas* canvas);
 
 enum WindowManagerName {
   WM_UNKNOWN,
@@ -269,27 +270,27 @@
 };
 // Attempts to guess the window maager. Returns WM_UNKNOWN if we can't
 // determine it for one reason or another.
-UI_BASE_EXPORT WindowManagerName GuessWindowManager();
+UI_BASE_X_EXPORT WindowManagerName GuessWindowManager();
 
 // The same as GuessWindowManager(), but returns the raw string.  If we
 // can't determine it, return "Unknown".
-UI_BASE_EXPORT std::string GuessWindowManagerName();
+UI_BASE_X_EXPORT std::string GuessWindowManagerName();
 
 // Enable the default X error handlers. These will log the error and abort
 // the process if called. Use SetX11ErrorHandlers() from x11_util_internal.h
 // to set your own error handlers.
-UI_BASE_EXPORT void SetDefaultX11ErrorHandlers();
+UI_BASE_X_EXPORT void SetDefaultX11ErrorHandlers();
 
 // Returns true if a given window is in full-screen mode.
-UI_BASE_EXPORT bool IsX11WindowFullScreen(XID window);
+UI_BASE_X_EXPORT bool IsX11WindowFullScreen(XID window);
 
 // Returns true if the window manager supports the given hint.
-UI_BASE_EXPORT bool WmSupportsHint(XAtom atom);
+UI_BASE_X_EXPORT bool WmSupportsHint(XAtom atom);
 
 // Manages a piece of X11 allocated memory as a RefCountedMemory segment. This
 // object takes ownership over the passed in memory and will free it with the
 // X11 allocator when done.
-class UI_BASE_EXPORT XRefcountedMemory : public base::RefCountedMemory {
+class UI_BASE_X_EXPORT XRefcountedMemory : public base::RefCountedMemory {
  public:
   XRefcountedMemory(unsigned char* x11_data, size_t length);
 
@@ -308,7 +309,7 @@
 
 // Keeps track of a cursor returned by an X function and makes sure it's
 // XFreeCursor'd.
-class UI_BASE_EXPORT XScopedCursor {
+class UI_BASE_X_EXPORT XScopedCursor {
  public:
   // Keeps track of |cursor| created with |display|.
   XScopedCursor(::Cursor cursor, XDisplay* display);
@@ -327,10 +328,10 @@
 namespace test {
 // Resets the cache used by GetXCursor(). Only useful for tests that may delete
 // the display.
-UI_BASE_EXPORT void ResetXCursorCache();
+UI_BASE_X_EXPORT void ResetXCursorCache();
 
 // Returns the cached XcursorImage for |cursor|.
-UI_BASE_EXPORT const XcursorImage* GetCachedXcursorImage(::Cursor cursor);
+UI_BASE_X_EXPORT const XcursorImage* GetCachedXcursorImage(::Cursor cursor);
 
 }  // namespace test
 
diff --git a/ui/base/x/x11_util_internal.h b/ui/base/x/x11_util_internal.h
index d58eccf..3b7419d 100644
--- a/ui/base/x/x11_util_internal.h
+++ b/ui/base/x/x11_util_internal.h
@@ -19,7 +19,7 @@
 }
 
 #include "build/build_config.h"
-#include "ui/base/ui_base_export.h"
+#include "ui/base/x/ui_base_x_export.h"
 
 namespace ui {
 
@@ -29,21 +29,21 @@
 // Get the XRENDER format id for ARGB32 (Skia's format).
 //
 // NOTE:Currently this don't support multiple screens/displays.
-UI_BASE_EXPORT XRenderPictFormat* GetRenderARGB32Format(Display* dpy);
+UI_BASE_X_EXPORT XRenderPictFormat* GetRenderARGB32Format(Display* dpy);
 
 // --------------------------------------------------------------------------
 // X11 error handling.
 // Sets the X Error Handlers. Passing NULL for either will enable the default
 // error handler, which if called will log the error and abort the process.
-UI_BASE_EXPORT void SetX11ErrorHandlers(XErrorHandler error_handler,
-                                        XIOErrorHandler io_error_handler);
+UI_BASE_X_EXPORT void SetX11ErrorHandlers(XErrorHandler error_handler,
+                                          XIOErrorHandler io_error_handler);
 
 // NOTE: This function should not be called directly from the
 // X11 Error handler because it queries the server to decode the
 // error message, which may trigger other errors. A suitable workaround
 // is to post a task in the error handler to call this function.
-UI_BASE_EXPORT void LogErrorEventDescription(Display* dpy,
-                                             const XErrorEvent& error_event);
+UI_BASE_X_EXPORT void LogErrorEventDescription(Display* dpy,
+                                               const XErrorEvent& error_event);
 
 // --------------------------------------------------------------------------
 // Selects a visual with a preference for alpha support on compositing window
@@ -51,7 +51,7 @@
 // supports transparency. NULL parameters are allowed to install or query the
 // cached visual and depth.
 #if !defined(OS_CHROMEOS)
-UI_BASE_EXPORT void ChooseVisualForWindow(Visual** visual, int* depth);
+UI_BASE_X_EXPORT void ChooseVisualForWindow(Visual** visual, int* depth);
 #endif
 
 }  // namespace ui
diff --git a/ui/display/manager/display_layout.cc b/ui/display/manager/display_layout.cc
index bcf821d..e8bb51b 100644
--- a/ui/display/manager/display_layout.cc
+++ b/ui/display/manager/display_layout.cc
@@ -36,10 +36,10 @@
   return iter != list.end();
 }
 
-gfx::Display* FindDisplayById(DisplayList* display_list, int64_t id) {
+display::Display* FindDisplayById(DisplayList* display_list, int64_t id) {
   auto iter = std::find_if(
       display_list->begin(), display_list->end(),
-      [id](const gfx::Display& display) { return display.id() == id; });
+      [id](const display::Display& display) { return display.id() == id; });
   return &(*iter);
 }
 
@@ -289,10 +289,10 @@
 bool DisplayLayout::ApplyDisplayPlacement(const DisplayPlacement& placement,
                                           DisplayList* display_list,
                                           int minimum_offset_overlap) {
-  const gfx::Display& parent_display =
+  const display::Display& parent_display =
       *FindDisplayById(display_list, placement.parent_display_id);
   DCHECK(parent_display.is_valid());
-  gfx::Display* target_display =
+  display::Display* target_display =
       FindDisplayById(display_list, placement.display_id);
   gfx::Rect old_bounds(target_display->bounds());
   DCHECK(target_display);
diff --git a/ui/display/manager/display_layout.h b/ui/display/manager/display_layout.h
index 154a51b..55a98191 100644
--- a/ui/display/manager/display_layout.h
+++ b/ui/display/manager/display_layout.h
@@ -31,7 +31,7 @@
 // DisplayLayoutStore.
 using DisplayIdList = std::vector<int64_t>;
 
-using DisplayList = std::vector<gfx::Display>;
+using DisplayList = std::vector<display::Display>;
 
 // DisplayPlacement specifies where the display (D) is placed relative
 // to parent (P) display.  In the following example, the display (D)
diff --git a/ui/display/win/dpi.cc b/ui/display/win/dpi.cc
index e6c3d68..4e8f43c 100644
--- a/ui/display/win/dpi.cc
+++ b/ui/display/win/dpi.cc
@@ -7,7 +7,7 @@
 #include <windows.h>
 
 #include "base/win/scoped_hdc.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
 
 namespace display {
 namespace win {
@@ -49,8 +49,8 @@
 }
 
 float GetDPIScale() {
-  if (gfx::Display::HasForceDeviceScaleFactor())
-    return gfx::Display::GetForcedDeviceScaleFactor();
+  if (display::Display::HasForceDeviceScaleFactor())
+    return display::Display::GetForcedDeviceScaleFactor();
   float dpi_scale = GetUnforcedDeviceScaleFactor();
   return (dpi_scale <= 1.25f) ? 1.f : dpi_scale;
 }
diff --git a/ui/display/win/screen_win_unittest.cc b/ui/display/win/screen_win_unittest.cc
index 88904cf..a0491aa 100644
--- a/ui/display/win/screen_win_unittest.cc
+++ b/ui/display/win/screen_win_unittest.cc
@@ -1568,7 +1568,7 @@
   }
 
   void TearDown() override {
-    gfx::Display::ResetForceDeviceScaleFactorForTesting();
+    display::Display::ResetForceDeviceScaleFactorForTesting();
     testing::Test::TearDown();
   }
 
@@ -1666,7 +1666,7 @@
   }
 
   void TearDown() override {
-    gfx::Display::ResetForceDeviceScaleFactorForTesting();
+    display::Display::ResetForceDeviceScaleFactorForTesting();
     testing::Test::TearDown();
   }
 
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 8373005b..4c7fd20 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -532,6 +532,7 @@
     "vector_icons/tab_close_normal.icon",
     "vector_icons/tab_media_capturing.icon",
     "vector_icons/tab_media_recording.icon",
+    "vector_icons/tab_usb_connected.1x.icon",
     "vector_icons/tab_usb_connected.icon",
     "vector_icons/tablet.icon",
     "vector_icons/translate.icon",
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 39f0040..5c2d378 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -577,21 +577,21 @@
 }
 #endif
 
-TextRunHarfBuzz::TextRunHarfBuzz()
+TextRunHarfBuzz::TextRunHarfBuzz(const gfx::Font& template_font)
     : width(0.0f),
       preceding_run_widths(0.0f),
       is_rtl(false),
       level(0),
       script(USCRIPT_INVALID_CODE),
       glyph_count(static_cast<size_t>(-1)),
+      font(template_font),
       font_size(0),
       baseline_offset(0),
       baseline_type(0),
       font_style(0),
       strike(false),
       diagonal_strike(false),
-      underline(false) {
-}
+      underline(false) {}
 
 TextRunHarfBuzz::~TextRunHarfBuzz() {}
 
@@ -1255,7 +1255,8 @@
   // to misbehave since they expect non-zero text metrics from a non-empty text.
   base::i18n::BiDiLineIterator bidi_iterator;
   if (!bidi_iterator.Open(text, GetTextDirection(text))) {
-    internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
+    internal::TextRunHarfBuzz* run =
+        new internal::TextRunHarfBuzz(font_list().GetPrimaryFont());
     run->range = Range(0, text.length());
     run_list_out->add(run);
     run_list_out->InitIndexMap();
@@ -1275,7 +1276,8 @@
   internal::StyleIterator style(empty_colors, baselines(), styles());
 
   for (size_t run_break = 0; run_break < text.length();) {
-    internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
+    internal::TextRunHarfBuzz* run =
+        new internal::TextRunHarfBuzz(font_list().GetPrimaryFont());
     run->range.set_start(run_break);
     run->font_style = (style.style(BOLD) ? Font::BOLD : 0) |
                       (style.style(ITALIC) ? Font::ITALIC : 0);
@@ -1378,7 +1380,7 @@
     }
   }
 
-  Font best_font;
+  Font best_font(primary_font);
   FontRenderParams best_render_params;
   size_t best_missing_glyphs = std::numeric_limits<size_t>::max();
 
@@ -1389,7 +1391,7 @@
   }
 
 #if defined(OS_WIN)
-  Font uniscribe_font;
+  Font uniscribe_font(primary_font);
   std::string uniscribe_family;
   const base::char16* run_text = &(text[run->range.start()]);
   if (GetUniscribeFallbackFont(primary_font, run_text, run->range.length(),
diff --git a/ui/gfx/render_text_harfbuzz.h b/ui/gfx/render_text_harfbuzz.h
index 38ee2b4..f164dc1 100644
--- a/ui/gfx/render_text_harfbuzz.h
+++ b/ui/gfx/render_text_harfbuzz.h
@@ -32,7 +32,9 @@
 namespace internal {
 
 struct GFX_EXPORT TextRunHarfBuzz {
-  TextRunHarfBuzz();
+  // Construct the run with |template_font| since determining the details of a
+  // default-constructed gfx::Font is expensive, but it will always be replaced.
+  explicit TextRunHarfBuzz(const gfx::Font& template_font);
   ~TextRunHarfBuzz();
 
   // Returns the index of the first glyph that corresponds to the character at
diff --git a/ui/gfx/render_text_mac.h b/ui/gfx/render_text_mac.h
index e1dbb6f..a437ac57 100644
--- a/ui/gfx/render_text_mac.h
+++ b/ui/gfx/render_text_mac.h
@@ -68,7 +68,7 @@
     std::vector<uint16_t> glyphs;
     std::vector<SkPoint> glyph_positions;
     SkScalar width;
-    Font font;
+    base::ScopedCFTypeRef<CTFontRef> ct_font;
     sk_sp<SkTypeface> typeface;
     SkColor foreground;
     bool underline;
@@ -76,7 +76,8 @@
     bool diagonal_strike;
 
     TextRun();
-    TextRun(const TextRun& other);
+    TextRun(const TextRun& other) = delete;
+    TextRun(TextRun&& other);
     ~TextRun();
   };
 
diff --git a/ui/gfx/render_text_mac.mm b/ui/gfx/render_text_mac.mm
index 915f51f9..5a4e5b11 100644
--- a/ui/gfx/render_text_mac.mm
+++ b/ui/gfx/render_text_mac.mm
@@ -118,7 +118,8 @@
   for (size_t i = 0; i < runs_.size(); ++i) {
     const CFRange cf_range = CTRunGetStringRange(runs_[i].ct_run);
     const Range range(cf_range.location, cf_range.location + cf_range.length);
-    spans.push_back(RenderText::FontSpan(runs_[i].font, range));
+    spans.push_back(RenderText::FontSpan(
+        gfx::Font(base::mac::CFToNSCast(runs_[i].ct_font.get())), range));
   }
 
   return spans;
@@ -210,9 +211,7 @@
   for (size_t i = 0; i < runs_.size(); ++i) {
     const TextRun& run = runs_[i];
     renderer->SetForegroundColor(run.foreground);
-
-    CTFontRef ct_font = static_cast<CTFontRef>(run.font.GetNativeFont());
-    renderer->SetTextSize(CTFontGetSize(ct_font));
+    renderer->SetTextSize(CTFontGetSize(run.ct_font));
 
     // The painter adds its own ref. So don't |release()| it from the ref ptr in
     // TextRun.
@@ -236,7 +235,7 @@
       strike(false),
       diagonal_strike(false) {}
 
-RenderTextMac::TextRun::TextRun(const TextRun& other) = default;
+RenderTextMac::TextRun::TextRun(TextRun&& other) = default;
 
 RenderTextMac::TextRun::~TextRun() {}
 
@@ -379,7 +378,7 @@
       continue;
     }
 
-    runs_.push_back(TextRun());
+    runs_.emplace_back();
     TextRun* run = &runs_.back();
     run->ct_run = ct_run;
     run->origin = run_origin;
@@ -414,7 +413,7 @@
     CFDictionaryRef attributes = CTRunGetAttributes(ct_run);
     CTFontRef ct_font = base::mac::GetValueFromDictionary<CTFontRef>(
         attributes, kCTFontAttributeName);
-    run->font = Font(static_cast<NSFont*>(ct_font));
+    run->ct_font.reset(ct_font, base::scoped_policy::RETAIN);
     run->typeface.reset(SkCreateTypefaceFromCTFont(ct_font));
 
     const CGColorRef foreground = base::mac::GetValueFromDictionary<CGColorRef>(
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 90d1604..598240c 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -2707,7 +2707,7 @@
     },
   };
 
-  internal::TextRunHarfBuzz run;
+  internal::TextRunHarfBuzz run((Font()));
   run.range = Range(0, 4);
   run.glyph_count = 4;
   run.glyph_to_char.resize(4);
@@ -2790,7 +2790,7 @@
     },
   };
 
-  internal::TextRunHarfBuzz run;
+  internal::TextRunHarfBuzz run((Font()));
   run.range = Range(0, 4);
   run.glyph_count = 2;
   run.glyph_to_char.resize(2);
@@ -2941,7 +2941,7 @@
 
 // Ensure an empty run returns sane values to queries.
 TEST_F(RenderTextTest, HarfBuzz_EmptyRun) {
-  internal::TextRunHarfBuzz run;
+  internal::TextRunHarfBuzz run((Font()));
   const base::string16 kString = ASCIIToUTF16("abcdefgh");
   std::unique_ptr<base::i18n::BreakIterator> iter(new base::i18n::BreakIterator(
       kString, base::i18n::BreakIterator::BREAK_CHARACTER));
diff --git a/ui/gfx/vector_icons/tab_usb_connected.1x.icon b/ui/gfx/vector_icons/tab_usb_connected.1x.icon
new file mode 100644
index 0000000..00cc795
--- /dev/null
+++ b/ui/gfx/vector_icons/tab_usb_connected.1x.icon
@@ -0,0 +1,38 @@
+// 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.
+
+CANVAS_DIMENSIONS, 16,
+MOVE_TO, 10, 8,
+R_H_LINE_TO, 1,
+R_V_LINE_TO, 1,
+H_LINE_TO, 9,
+V_LINE_TO, 5,
+R_H_LINE_TO, 1,
+LINE_TO, 8.5f, 3,
+LINE_TO, 7, 5,
+R_H_LINE_TO, 1,
+R_V_LINE_TO, 4,
+H_LINE_TO, 7,
+V_LINE_TO, 8,
+R_CUBIC_TO, -0.08f, -0.04f, 0, -0.5f, 0, -1,
+R_CUBIC_TO, 0, -0.5f, -0.5f, -1, -1, -1,
+R_CUBIC_TO, -0.5f, 0, -1, 0.5f, -1, 1,
+R_CUBIC_TO, 0, 0.5f, 0.25f, 0.96f, 1, 1,
+R_V_LINE_TO, 1,
+R_CUBIC_TO, 0, 0.5f, 0.5f, 1, 1, 1,
+R_H_LINE_TO, 1,
+R_V_LINE_TO, 2,
+R_LINE_TO, -1, 1,
+R_LINE_TO, 1, 1,
+R_H_LINE_TO, 1,
+R_LINE_TO, 1, -1,
+R_LINE_TO, -1, -1,
+R_V_LINE_TO, -2,
+R_H_LINE_TO, 2,
+R_CUBIC_TO, 0.5f, 0, 1, -0.5f, 1, -1,
+V_LINE_TO, 6,
+R_H_LINE_TO, -2,
+R_V_LINE_TO, 2,
+CLOSE,
+END
diff --git a/ui/gfx/vector_icons/tab_usb_connected.icon b/ui/gfx/vector_icons/tab_usb_connected.icon
index c383dca1..2884fdf 100644
--- a/ui/gfx/vector_icons/tab_usb_connected.icon
+++ b/ui/gfx/vector_icons/tab_usb_connected.icon
@@ -2,38 +2,38 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-CANVAS_DIMENSIONS, 24,
-MOVE_TO, 15, 7,
-R_V_LINE_TO, 4,
+CANVAS_DIMENSIONS, 32,
+MOVE_TO, 19, 16,
 R_H_LINE_TO, 1,
 R_V_LINE_TO, 2,
 R_H_LINE_TO, -3,
-V_LINE_TO, 5,
+R_V_LINE_TO, -8,
 R_H_LINE_TO, 2,
 R_LINE_TO, -3, -4,
 R_LINE_TO, -3, 4,
 R_H_LINE_TO, 2,
 R_V_LINE_TO, 8,
-H_LINE_TO, 8,
-R_V_LINE_TO, -2.07f,
-R_CUBIC_TO, 0.7f, -0.37f, 1.2f, -1.08f, 1.2f, -1.93f,
-R_CUBIC_TO, 0, -1.21f, -0.99f, -2.2f, -2.2f, -2.2f,
-R_CUBIC_TO, -1.21f, 0, -2.2f, 0.99f, -2.2f, 2.2f,
-R_CUBIC_TO, 0, 0.85f, 0.5f, 1.56f, 1.2f, 1.93f,
-V_LINE_TO, 13,
-R_CUBIC_TO, 0, 1.11f, 0.89f, 2, 2, 2,
+R_H_LINE_TO, -3,
+R_V_LINE_TO, -2,
+R_CUBIC_TO, 0.85f, -0.53f, 1.34f, -1.23f, 1, -2,
+R_CUBIC_TO, 0.34f, -1.27f, -0.64f, -2.25f, -2, -2,
+R_CUBIC_TO, -1.02f, -0.25f, -2, 0.73f, -2, 2,
+R_CUBIC_TO, 0, 0.77f, 0.49f, 1.47f, 1, 2,
+R_V_LINE_TO, 2,
+R_CUBIC_TO, 0.18f, 0.99f, 1.06f, 1.87f, 2, 2,
 R_H_LINE_TO, 3,
-R_V_LINE_TO, 3.05f,
-R_CUBIC_TO, -0.71f, 0.37f, -1.2f, 1.1f, -1.2f, 1.95f,
-R_CUBIC_TO, 0, 1.22f, 0.99f, 2.2f, 2.2f, 2.2f,
-R_CUBIC_TO, 1.21f, 0, 2.2f, -0.98f, 2.2f, -2.2f,
-R_CUBIC_TO, 0, -0.85f, -0.49f, -1.58f, -1.2f, -1.95f,
-V_LINE_TO, 15,
+R_V_LINE_TO, 3,
+R_CUBIC_TO, -0.59f, 0.26f, -1.07f, 0.98f, -1, 2,
+R_CUBIC_TO, -0.07f, 1.03f, 0.91f, 2, 2, 2,
+R_CUBIC_TO, 1.29f, 0, 2.27f, -0.97f, 2, -2,
+R_CUBIC_TO, 0.27f, -1.02f, -0.21f, -1.74f, -1, -2,
+R_V_LINE_TO, -3,
 R_H_LINE_TO, 3,
-R_CUBIC_TO, 1.11f, 0, 2, -0.89f, 2, -2,
+R_CUBIC_TO, 1.14f, -0.13f, 2.01f, -1.01f, 2, -2,
 R_V_LINE_TO, -2,
 R_H_LINE_TO, 1,
-V_LINE_TO, 7,
+R_V_LINE_TO, -4,
 R_H_LINE_TO, -4,
+R_V_LINE_TO, 4,
 CLOSE,
 END
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index df645846..2b84ea2 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -196,6 +196,7 @@
             '<(DEPTH)/build/linux/system.gyp:x11',
             '<(DEPTH)/build/linux/system.gyp:xcomposite',
             '<(DEPTH)/build/linux/system.gyp:xext',
+            '<(DEPTH)/ui/base/x/ui_base_x.gyp:ui_base_x',
             '<(DEPTH)/ui/events/platform/events_platform.gyp:events_platform',
             '<(DEPTH)/ui/gfx/x/gfx_x11.gyp:gfx_x11',
           ],
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index 43befdd..c7053b23 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -39,7 +39,7 @@
 #include <X11/Xlib.h>
 #define Status int
 }
-#include "ui/base/x/x11_util_internal.h"
+#include "ui/base/x/x11_util_internal.h"  // nogncheck
 #include "ui/gfx/x/x11_switches.h"  // nogncheck
 #endif
 
diff --git a/ui/ozone/platform/drm/BUILD.gn b/ui/ozone/platform/drm/BUILD.gn
index ff90fab2b..af0da57 100644
--- a/ui/ozone/platform/drm/BUILD.gn
+++ b/ui/ozone/platform/drm/BUILD.gn
@@ -126,6 +126,7 @@
     "//skia",
     "//third_party/minigbm",
     "//ui/base",
+    "//ui/display",
     "//ui/display/types",
     "//ui/display/util",
     "//ui/events",
diff --git a/ui/ozone/platform/drm/host/DEPS b/ui/ozone/platform/drm/host/DEPS
index 61d208f..f7f2d71 100644
--- a/ui/ozone/platform/drm/host/DEPS
+++ b/ui/ozone/platform/drm/host/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+ui/display",
   "-ui/ozone/platform/drm",
   "+ui/ozone/platform/drm/common",
   "+ui/ozone/platform/drm/host",
diff --git a/ui/ozone/platform/drm/host/drm_window_host.cc b/ui/ozone/platform/drm/host/drm_window_host.cc
index 56b59bb..647756053 100644
--- a/ui/ozone/platform/drm/host/drm_window_host.cc
+++ b/ui/ozone/platform/drm/host/drm_window_host.cc
@@ -5,12 +5,12 @@
 #include "ui/ozone/platform/drm/host/drm_window_host.h"
 
 #include "base/bind.h"
+#include "ui/display/display.h"
 #include "ui/events/devices/device_data_manager.h"
 #include "ui/events/event.h"
 #include "ui/events/ozone/evdev/event_factory_evdev.h"
 #include "ui/events/ozone/events_ozone.h"
 #include "ui/events/platform/platform_event_source.h"
-#include "ui/gfx/display.h"
 #include "ui/ozone/platform/drm/host/drm_cursor.h"
 #include "ui/ozone/platform/drm/host/drm_display_host.h"
 #include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
@@ -145,7 +145,7 @@
         DeviceDataManager::GetInstance()->GetTargetDisplayForTouchDevice(
             event->source_device_id());
 
-    if (display_id == gfx::Display::kInvalidDisplayID)
+    if (display_id == display::Display::kInvalidDisplayID)
       return false;
 
     DrmDisplayHost* display = display_manager_->GetDisplay(display_id);
diff --git a/ui/platform_window/x11/BUILD.gn b/ui/platform_window/x11/BUILD.gn
index d3edc9a..0ce1f80 100644
--- a/ui/platform_window/x11/BUILD.gn
+++ b/ui/platform_window/x11/BUILD.gn
@@ -41,7 +41,10 @@
       "x11_window_ozone.cc",
       "x11_window_ozone.h",
     ]
-    deps += [ "//ui/base" ]
+    deps += [
+      "//ui/base",
+      "//ui/base/x",
+    ]
   } else if (use_x11) {
     sources += [
       "x11_window.cc",
diff --git a/ui/views/bubble/bubble_dialog_delegate.cc b/ui/views/bubble/bubble_dialog_delegate.cc
index 0dfb629e7..683a7946 100644
--- a/ui/views/bubble/bubble_dialog_delegate.cc
+++ b/ui/views/bubble/bubble_dialog_delegate.cc
@@ -115,10 +115,6 @@
   return frame;
 }
 
-void BubbleDialogDelegateView::GetAccessibleState(ui::AXViewState* state) {
-  state->role = ui::AX_ROLE_DIALOG;
-}
-
 const char* BubbleDialogDelegateView::GetClassName() const {
   return kViewClassName;
 }
diff --git a/ui/views/bubble/bubble_dialog_delegate.h b/ui/views/bubble/bubble_dialog_delegate.h
index 13c576e..04a5eeb 100644
--- a/ui/views/bubble/bubble_dialog_delegate.h
+++ b/ui/views/bubble/bubble_dialog_delegate.h
@@ -44,7 +44,6 @@
   bool ShouldShowCloseButton() const override;
   ClientView* CreateClientView(Widget* widget) override;
   NonClientFrameView* CreateNonClientFrameView(Widget* widget) override;
-  void GetAccessibleState(ui::AXViewState* state) override;
   const char* GetClassName() const override;
 
   // WidgetObserver overrides:
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc
index 8d46029..bf26f1e8 100644
--- a/ui/views/controls/label.cc
+++ b/ui/views/controls/label.cc
@@ -213,7 +213,7 @@
 
 gfx::Insets Label::GetInsets() const {
   gfx::Insets insets = View::GetInsets();
-  if (focusable()) {
+  if (focus_behavior() == FocusBehavior::ALWAYS) {
     insets += gfx::Insets(kFocusBorderPadding, kFocusBorderPadding,
                           kFocusBorderPadding, kFocusBorderPadding);
   }
@@ -435,7 +435,7 @@
     return;
 
   gfx::Rect rect = GetContentsBounds();
-  if (focusable())
+  if (focus_behavior() == FocusBehavior::ALWAYS)
     rect.Inset(kFocusBorderPadding, kFocusBorderPadding);
   if (rect.IsEmpty())
     return;
diff --git a/ui/views/mus/screen_mus.cc b/ui/views/mus/screen_mus.cc
index 67aa2b7..44a6df7 100644
--- a/ui/views/mus/screen_mus.cc
+++ b/ui/views/mus/screen_mus.cc
@@ -80,7 +80,8 @@
 ScreenMus::ScreenMus(ScreenMusDelegate* delegate)
     : delegate_(delegate),
       primary_display_index_(0),
-      display_manager_observer_binding_(this) {}
+      display_manager_observer_binding_(this) {
+}
 
 ScreenMus::~ScreenMus() {}
 
@@ -161,8 +162,14 @@
 }
 
 gfx::Point ScreenMus::GetCursorScreenPoint() {
-  NOTIMPLEMENTED();
-  return gfx::Point();
+  if (!delegate_) {
+    // TODO(erg): If we need the cursor point in the window manager, we'll need
+    // to make |delegate_| required. It only recently changed to be optional.
+    NOTIMPLEMENTED();
+    return gfx::Point();
+  }
+
+  return delegate_->GetCursorScreenPoint();
 }
 
 gfx::NativeWindow ScreenMus::GetWindowUnderCursor() {
diff --git a/ui/views/mus/screen_mus_delegate.h b/ui/views/mus/screen_mus_delegate.h
index 4c79400..1db1b67 100644
--- a/ui/views/mus/screen_mus_delegate.h
+++ b/ui/views/mus/screen_mus_delegate.h
@@ -7,6 +7,10 @@
 
 #include "ui/views/mus/mus_export.h"
 
+namespace gfx {
+class Point;
+}
+
 namespace views {
 
 // Screen implementation backed by mus::mojom::DisplayManager.
@@ -14,7 +18,9 @@
  public:
   virtual void OnWindowManagerFrameValuesChanged() = 0;
 
- protected:
+  virtual gfx::Point GetCursorScreenPoint() = 0;
+
+protected:
   virtual ~ScreenMusDelegate() {}
 };
 
diff --git a/ui/views/mus/window_manager_connection.cc b/ui/views/mus/window_manager_connection.cc
index 0ddaead..eff9a443 100644
--- a/ui/views/mus/window_manager_connection.cc
+++ b/ui/views/mus/window_manager_connection.cc
@@ -12,7 +12,7 @@
 #include "components/mus/public/cpp/window.h"
 #include "components/mus/public/cpp/window_property.h"
 #include "components/mus/public/cpp/window_tree_connection.h"
-#include "components/mus/public/interfaces/input_event_matcher.mojom.h"
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "mojo/converters/geometry/geometry_type_converters.h"
 #include "services/shell/public/cpp/connection.h"
@@ -157,4 +157,8 @@
     NativeWidgetMus::NotifyFrameChanged(window_tree_connection_.get());
 }
 
+gfx::Point WindowManagerConnection::GetCursorScreenPoint() {
+  return window_tree_connection_->GetCursorScreenPoint();
+}
+
 }  // namespace views
diff --git a/ui/views/mus/window_manager_connection.h b/ui/views/mus/window_manager_connection.h
index b1d9196..03d07fe 100644
--- a/ui/views/mus/window_manager_connection.h
+++ b/ui/views/mus/window_manager_connection.h
@@ -79,6 +79,7 @@
 
   // ScreenMusDelegate:
   void OnWindowManagerFrameValuesChanged() override;
+  gfx::Point GetCursorScreenPoint() override;
 
   shell::Connector* connector_;
   shell::Identity identity_;
diff --git a/ui/views/pointer_watcher.h b/ui/views/pointer_watcher.h
index 6273e13..dc7fa8d 100644
--- a/ui/views/pointer_watcher.h
+++ b/ui/views/pointer_watcher.h
@@ -16,6 +16,8 @@
 
 // An interface for read-only observation of pointer events (in particular, the
 // events cannot be marked as handled). Only certain event types are supported.
+// NOTE: The event.target is always null, because on mus the target window may
+// be owned by another process.
 class VIEWS_EXPORT PointerWatcher {
  public:
   virtual ~PointerWatcher() {}
diff --git a/ui/views/view.h b/ui/views/view.h
index ec3f72b7..6ef5836 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -1144,9 +1144,8 @@
 
   // Focus ---------------------------------------------------------------------
 
-  // Returns true if ALWAYS is the last set focus behavior. Use IsFocusable() to
-  // determine if a view can take focus right now.
-  bool focusable() const { return focus_behavior_ == FocusBehavior::ALWAYS; }
+  // Returns last set focus behavior.
+  FocusBehavior focus_behavior() const { return focus_behavior_; }
 
   // Override to be notified when focus has changed either to or from this View.
   virtual void OnFocus();
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index 7ffd862..89e3c1b 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -239,7 +239,7 @@
     views::View::Blur();
   }
 
-  bool focusable() const { return View::focusable(); }
+  FocusBehavior focus_behavior() const { return View::focus_behavior(); }
 
   void set_can_process_events_within_subtree(bool can_process) {
     can_process_events_within_subtree_ = can_process;
@@ -4366,15 +4366,17 @@
   // which effects the preferred size. To avoid preferred size changing around
   // these Views need to key off the last value set to SetFocusBehavior(), not
   // whether the View is focusable right now. For this reason it's important
-  // that the return value of focusable() depends on the last value passed to
-  // SetFocusBehavior and not whether the View is focusable right now.
+  // that the return value of focus_behavior() depends on the last value passed
+  // to SetFocusBehavior and not whether the View is focusable right now.
   TestView view;
   view.SetFocusBehavior(View::FocusBehavior::ALWAYS);
-  EXPECT_TRUE(view.focusable());
+  EXPECT_EQ(View::FocusBehavior::ALWAYS, view.focus_behavior());
   view.SetEnabled(false);
-  EXPECT_TRUE(view.focusable());
+  EXPECT_EQ(View::FocusBehavior::ALWAYS, view.focus_behavior());
   view.SetFocusBehavior(View::FocusBehavior::NEVER);
-  EXPECT_FALSE(view.focusable());
+  EXPECT_EQ(View::FocusBehavior::NEVER, view.focus_behavior());
+  view.SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY);
+  EXPECT_EQ(View::FocusBehavior::ACCESSIBLE_ONLY, view.focus_behavior());
 }
 
 // Verifies when a view is deleted it is removed from ViewStorage.
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index d158ba5..eca6e61 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -796,6 +796,7 @@
               'sources': [ '<@(views_desktop_aura_x11_sources)' ],
               'dependencies': [
                 '../../build/linux/system.gyp:xext',
+                '../../ui/base/x/ui_base_x.gyp:ui_base_x',
               ],
             }],
             ['OS == "win"', {