diff --git a/BUILD.gn b/BUILD.gn
index 933f4ed..579eb72 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -180,7 +180,6 @@
       "//mojo/edk/system:mojo_system_unittests",
       "//mojo/edk/test:mojo_public_bindings_unittests",
       "//mojo/edk/test:mojo_public_system_unittests",
-      "//mojo/edk/test:mojo_public_utility_unittests",
       "//mojo/shell/public/cpp",
       "//net:net_perftests",
       "//third_party/WebKit/Source/platform:blink_heap_unittests",
diff --git a/DEPS b/DEPS
index ccf11aa..5a46e34 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': '4984c3c95f18eda44492a2126c9958e447f2cca8',
+  'skia_revision': 'e683c56115a210b5993df9294260bb147b408bfa',
   # 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': '3c3b9fbb1ffa2c7d3f48cadc2f66568d3e125e0e',
+  'v8_revision': 'a7ac1c416b81b5b55cd451aa5f840eda2085613c',
   # 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.
@@ -51,11 +51,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'bd382711c33bf4e419f0ad011feaff603907d2ae',
+  'angle_revision': 'fc4712b5ed270436f2993bfda9e916d4f92684a4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
-  'buildtools_revision': '14288a03a92856fe1fc296d39e6a25c2d83cd6cf',
+  'buildtools_revision': '7274f1c726640bce4cd4c4198e1ee62a0b29bb89',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # 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': 'ba70118d8ea7bb0232554bbd70606703bde5bde3',
+  'boringssl_revision': 'a857159dd61204bfe93bd8e2f00448434e8b0b99',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nss
   # and whatever else without interference from each other.
@@ -267,7 +267,7 @@
 
   'src/third_party/catapult':
     Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' +
-    '14c08ceb0eb454ac75638ca56a914801917a7b1d',
+    'ed08f0f1f07a6d16e3626c3a197499763f9b76c4',
 
   'src/third_party/openh264/src':
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'b37cda248234162033e3e11b0335f3131cdfe488',
@@ -338,7 +338,7 @@
      Var('chromium_git') + '/external/github.com/swisspol/GCDWebServer.git' + '@' + '3d5fd0b8281a7224c057deb2d17709b5bea64836',
 
     'src/ios/third_party/ochamcrest/src':
-     Var('chromium_git') + '/external/github.com/hamcrest/OCHamcrest.git' + '@' + '5b50930c66d1e537918a87eef0943d6750729dc5',
+     Var('chromium_git') + '/external/github.com/hamcrest/OCHamcrest.git' + '@' + 'd7ee4ecfb6bd13c3c8d364682b6228ccd86e1e1a',
 
     'src/third_party/google_toolbox_for_mac/src':
       Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
diff --git a/WATCHLISTS b/WATCHLISTS
index 2e21455..0932de7 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1296,8 +1296,7 @@
     'certificate_transparency': ['eranm@chromium.org', 'certificate-transparency-chrome@googlegroups.com'],
     'chrome_elf': ['caitkp+watch@chromium.org',],
     'chrome_views': ['tfarina@chromium.org'],
-    'chromecast': ['gunsch+watch@chromium.org',
-                   'halliwell+watch@chromium.org',
+    'chromecast': ['halliwell+watch@chromium.org',
                    'lcwu+watch@chromium.org'],
     'chromecast_public': ['gfhuang+watch@chromium.org'],
     'chromedriver': ['samuong+watch@chromium.org'],
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
index 473acd4..ca277ba 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidScrollIntegrationTest.java
@@ -15,6 +15,7 @@
 import org.chromium.android_webview.test.util.JavascriptEventObserver;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.content.browser.test.util.CallbackHelper;
 import org.chromium.content_public.browser.GestureStateListener;
@@ -23,7 +24,6 @@
 
 import java.util.Locale;
 import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
@@ -472,8 +472,7 @@
         AwTestTouchUtils.dragCompleteView(testContainerView,
                 0, -targetScrollXPix, // these need to be negative as we're scrolling down.
                 0, -targetScrollYPix,
-                dragSteps,
-                null /* completionLatch */);
+                dragSteps);
 
         for (int i = 1; i <= dragSteps; ++i) {
             onScrollToCallbackHelper.waitForCallback(scrollToCallCount, i);
@@ -487,38 +486,6 @@
 
     @SmallTest
     @Feature({"AndroidWebView"})
-    public void testNoSpuriousOverScrolls() throws Throwable {
-        final TestAwContentsClient contentsClient = new TestAwContentsClient();
-        final ScrollTestContainerView testContainerView =
-                (ScrollTestContainerView) createAwTestContainerViewOnMainSync(contentsClient);
-        enableJavaScriptOnUiThread(testContainerView.getAwContents());
-
-        final int dragSteps = 1;
-        final int targetScrollYPix = 40;
-
-        setMaxScrollOnMainSync(testContainerView, 0, 0);
-
-        loadTestPageAndWaitForFirstFrame(testContainerView, contentsClient, null, "");
-
-        final CallbackHelper onScrollToCallbackHelper =
-                testContainerView.getOnScrollToCallbackHelper();
-        final int scrollToCallCount = onScrollToCallbackHelper.getCallCount();
-        CountDownLatch scrollingCompleteLatch = new CountDownLatch(1);
-        AwTestTouchUtils.dragCompleteView(testContainerView,
-                0, 0, // these need to be negative as we're scrolling down.
-                0, -targetScrollYPix,
-                dragSteps,
-                scrollingCompleteLatch);
-        try {
-            scrollingCompleteLatch.await();
-        } catch (InterruptedException ex) {
-            // ignore
-        }
-        assertEquals(scrollToCallCount + 1, onScrollToCallbackHelper.getCallCount());
-    }
-
-    @SmallTest
-    @Feature({"AndroidWebView"})
     public void testOverScrollX() throws Throwable {
         final TestAwContentsClient contentsClient = new TestAwContentsClient();
         final ScrollTestContainerView testContainerView =
@@ -538,8 +505,7 @@
         AwTestTouchUtils.dragCompleteView(testContainerView,
                 0, overScrollDeltaX,
                 0, 0,
-                oneStep,
-                null /* completionLatch */);
+                oneStep);
         overScrollByCallbackHelper.waitForCallback(overScrollCallCount);
         // Unfortunately the gesture detector seems to 'eat' some number of pixels. For now
         // checking that the value is < 0 (overscroll is reported as negative values) will have to
@@ -569,8 +535,7 @@
         AwTestTouchUtils.dragCompleteView(testContainerView,
                 0, 0,
                 0, overScrollDeltaY,
-                oneStep,
-                null /* completionLatch */);
+                oneStep);
         overScrollByCallbackHelper.waitForCallback(overScrollCallCount);
         assertEquals(0, overScrollByCallbackHelper.getDeltaX());
         assertTrue(0 > overScrollByCallbackHelper.getDeltaY());
@@ -802,13 +767,17 @@
         AwTestTouchUtils.dragCompleteView(testContainerView,
                 0, -targetScrollXPix, // these need to be negative as we're scrolling down.
                 0, -targetScrollYPix,
-                dragSteps,
-                null /* completionLatch */);
+                dragSteps);
         onScrollUpdateGestureConsumedHelper.waitForCallback(callCount);
     }
 
+    /*
     @SmallTest
     @Feature({"AndroidWebView"})
+    Disabled because zoomIn is no longer synchronous. Fix if it's a compatibility problem.
+    See crbug.com/545628.
+    */
+    @DisabledTest
     public void testPinchZoomUpdatesScrollRangeSynchronously() throws Throwable {
         final TestAwContentsClient contentsClient = new TestAwContentsClient();
         final ScrollTestContainerView testContainerView =
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/AwTestTouchUtils.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/AwTestTouchUtils.java
index bdae4ec..c733076 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/util/AwTestTouchUtils.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/AwTestTouchUtils.java
@@ -8,8 +8,6 @@
 import android.view.MotionEvent;
 import android.view.View;
 
-import java.util.concurrent.CountDownLatch;
-
 /**
  * A touch utility class that injects the events directly into the view.
  * TODO(mkosiba): Merge with TestTouchUtils.
@@ -59,20 +57,15 @@
      * @param fromY The relative y-coordinate of the start point of the drag.
      * @param toY The relative y-coordinate of the end point of the drag.
      * @param stepCount The total number of motion events that should be generated during the drag.
-     * @param completionLatch The .countDown method is called on this latch once the drag finishes.
      */
     public static void dragCompleteView(final View view, final int fromX, final int toX,
-            final int fromY, final int toY, final int stepCount,
-            final CountDownLatch completionLatch) {
+            final int fromY, final int toY, final int stepCount) {
         view.post(new Runnable() {
             @Override
             public void run() {
                 long downTime = dragStart(view, fromX, fromY);
                 dragTo(view, fromX, toX, fromY, toY, stepCount, downTime);
                 dragEnd(view, toX, toY, downTime);
-                if (completionLatch != null) {
-                    completionLatch.countDown();
-                }
             }
         });
     }
diff --git a/android_webview/native/aw_dev_tools_server.cc b/android_webview/native/aw_dev_tools_server.cc
index 7e6cb59..9d1a83f7 100644
--- a/android_webview/native/aw_dev_tools_server.cc
+++ b/android_webview/native/aw_dev_tools_server.cc
@@ -156,7 +156,7 @@
 }
 
 bool AwDevToolsServer::IsStarted() const {
-  return devtools_http_handler_;
+  return !!devtools_http_handler_;
 }
 
 bool RegisterAwDevToolsServer(JNIEnv* env) {
diff --git a/android_webview/renderer/aw_render_frame_ext.cc b/android_webview/renderer/aw_render_frame_ext.cc
index 69b06f054..61c8025 100644
--- a/android_webview/renderer/aw_render_frame_ext.cc
+++ b/android_webview/renderer/aw_render_frame_ext.cc
@@ -17,6 +17,7 @@
 #include "third_party/WebKit/public/web/WebElementCollection.h"
 #include "third_party/WebKit/public/web/WebFrameWidget.h"
 #include "third_party/WebKit/public/web/WebHitTestResult.h"
+#include "third_party/WebKit/public/web/WebImageCache.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebMeaningfulLayout.h"
 #include "third_party/WebKit/public/web/WebNode.h"
@@ -146,6 +147,21 @@
     blink::WebSecurityOrigin origin = frame->document().getSecurityOrigin();
     origin.grantLoadLocalResources();
   }
+
+  // Clear the cache when we cross site boundaries in the main frame.
+  //
+  // We're trying to approximate what happens with a multi-process Chromium,
+  // where navigation across origins would cause a new render process to spin
+  // up, and thus start with a clear cache. Wiring up a signal from browser to
+  // renderer code to say "this navigation would have switched processes" would
+  // be disruptive, so this clearing of the cache is the compromise.
+  if (!frame->parent()) {
+    url::Origin new_origin(frame->document().url());
+    if (!new_origin.IsSameOriginWith(last_origin_)) {
+      last_origin_ = new_origin;
+      blink::WebImageCache::clear();
+    }
+  }
 }
 
 bool AwRenderFrameExt::OnMessageReceived(const IPC::Message& message) {
diff --git a/android_webview/renderer/aw_render_frame_ext.h b/android_webview/renderer/aw_render_frame_ext.h
index 09c9853..cb85969 100644
--- a/android_webview/renderer/aw_render_frame_ext.h
+++ b/android_webview/renderer/aw_render_frame_ext.h
@@ -10,6 +10,7 @@
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/size_f.h"
+#include "url/origin.h"
 
 namespace blink {
 enum WebMeaningfulLayout;
@@ -53,6 +54,8 @@
   blink::WebView* GetWebView();
   blink::WebFrameWidget* GetWebFrameWidget();
 
+  url::Origin last_origin_;
+
   DISALLOW_COPY_AND_ASSIGN(AwRenderFrameExt);
 };
 
diff --git a/android_webview/renderer/aw_render_view_ext.cc b/android_webview/renderer/aw_render_view_ext.cc
index eaec178..c14f14e 100644
--- a/android_webview/renderer/aw_render_view_ext.cc
+++ b/android_webview/renderer/aw_render_view_ext.cc
@@ -7,7 +7,6 @@
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_view.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebImageCache.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
 namespace android_webview {
@@ -66,15 +65,4 @@
         contents_size));
 }
 
-void AwRenderViewExt::Navigate(const GURL& url) {
-  // Navigate is called only on NEW navigations, so WebImageCache won't be
-  // freed when the user just clicks on links, but only when a navigation is
-  // started, for instance via loadUrl. A better approach would be clearing the
-  // cache on cross-site boundaries, however this would require too many
-  // changes both on the browser side (in RenderViewHostManger), to the
-  // IPCmessages and to the RenderViewObserver. Thus, clearing decoding image
-  // cache on Navigate, seems a more acceptable compromise.
-  blink::WebImageCache::clear();
-}
-
 }  // namespace android_webview
diff --git a/android_webview/renderer/aw_render_view_ext.h b/android_webview/renderer/aw_render_view_ext.h
index f14c1da7..25a264b 100644
--- a/android_webview/renderer/aw_render_view_ext.h
+++ b/android_webview/renderer/aw_render_view_ext.h
@@ -26,7 +26,6 @@
   // RenderViewObserver:
   void DidCommitCompositorFrame() override;
   void DidUpdateLayout() override;
-  void Navigate(const GURL& url) override;
 
   void CheckContentsSize();
   void PostCheckContentsSize();
diff --git a/base/BUILD.gn b/base/BUILD.gn
index f19c8f4..0b41b0e 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -36,6 +36,10 @@
   import("//build/config/android/rules.gni")
 }
 
+if (is_win) {
+  import("//build/config/win/visual_studio_version.gni")
+}
+
 config("base_flags") {
   if (is_clang) {
     cflags = [
@@ -1162,10 +1166,61 @@
 
       # These runtime files are copied to the output directory by the
       # vs_toolchain script that runs as part of toolchain configuration.
-      data += [
-        "$root_out_dir/msvcp120${vcrt_suffix}.dll",
-        "$root_out_dir/msvcr120${vcrt_suffix}.dll",
-      ]
+      if (visual_studio_version == "2015") {
+        data += [
+          "$root_out_dir/msvcp140${vcrt_suffix}.dll",
+          "$root_out_dir/vccorlib140${vcrt_suffix}.dll",
+          "$root_out_dir/vcruntime140${vcrt_suffix}.dll",
+
+          # Universal Windows 10 CRT files
+          "$root_out_dir/api-ms-win-core-console-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-datetime-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-debug-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-errorhandling-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-file-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-file-l1-2-0.dll",
+          "$root_out_dir/api-ms-win-core-file-l2-1-0.dll",
+          "$root_out_dir/api-ms-win-core-handle-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-heap-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-interlocked-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-libraryloader-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-localization-l1-2-0.dll",
+          "$root_out_dir/api-ms-win-core-memory-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-namedpipe-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-processenvironment-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-processthreads-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-processthreads-l1-1-1.dll",
+          "$root_out_dir/api-ms-win-core-profile-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-rtlsupport-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-string-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-synch-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-synch-l1-2-0.dll",
+          "$root_out_dir/api-ms-win-core-sysinfo-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-timezone-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-core-util-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-conio-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-convert-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-environment-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-filesystem-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-heap-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-locale-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-math-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-multibyte-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-private-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-process-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-runtime-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-stdio-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-string-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-time-l1-1-0.dll",
+          "$root_out_dir/api-ms-win-crt-utility-l1-1-0.dll",
+          "$root_out_dir/ucrtbase${vcrt_suffix}.dll",
+        ]
+      } else {
+        data += [
+          "$root_out_dir/msvcp120${vcrt_suffix}.dll",
+          "$root_out_dir/msvcr120${vcrt_suffix}.dll",
+        ]
+      }
       if (is_asan) {
         data += [ "//third_party/llvm-build/Release+Asserts/lib/clang/3.9.0/lib/windows/clang_rt.asan_dynamic-i386.dll" ]
       }
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc
index 08dbeb3..199f147 100644
--- a/base/i18n/icu_util.cc
+++ b/base/i18n/icu_util.cc
@@ -60,6 +60,10 @@
 bool g_called_once = false;
 #endif  // !defined(NDEBUG)
 
+// To debug http://crbug.com/445616.
+int g_debug_icu_last_error;
+int g_debug_icu_load;
+
 #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
 // Use an unversioned file name to simplify a icu version update down the road.
 // No need to change the filename in multiple places (gyp files, windows
@@ -151,15 +155,18 @@
     const MemoryMappedFile::Region& data_region) {
   // This can be called multiple times in tests.
   if (g_icudtl_mapped_file) {
+    g_debug_icu_load = 0;  // To debug http://crbug.com/445616.
     return true;
   }
   if (data_fd == kInvalidPlatformFile) {
+    g_debug_icu_load = 1;  // To debug http://crbug.com/445616.
     LOG(ERROR) << "Invalid file descriptor to ICU data received.";
     return false;
   }
 
   scoped_ptr<MemoryMappedFile> icudtl_mapped_file(new MemoryMappedFile());
   if (!icudtl_mapped_file->Initialize(File(data_fd), data_region)) {
+    g_debug_icu_load = 2;  // To debug http://crbug.com/445616.
     LOG(ERROR) << "Couldn't mmap icu data file";
     return false;
   }
@@ -167,6 +174,10 @@
 
   UErrorCode err = U_ZERO_ERROR;
   udata_setCommonData(const_cast<uint8_t*>(g_icudtl_mapped_file->data()), &err);
+  if (err != U_ZERO_ERROR) {
+    g_debug_icu_load = 3;  // To debug http://crbug.com/445616.
+    g_debug_icu_last_error = err;
+  }
   return err == U_ZERO_ERROR;
 }
 #endif  // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
@@ -257,6 +268,10 @@
   result =
       InitializeICUWithFileDescriptorInternal(g_icudtl_pf, g_icudtl_region);
 #if defined(OS_WIN)
+  int debug_icu_load = g_debug_icu_load;
+  debug::Alias(&debug_icu_load);
+  int debug_icu_last_error = g_debug_icu_last_error;
+  debug::Alias(&debug_icu_last_error);
   CHECK(result);  // TODO(scottmg): http://crbug.com/445616
 #endif
 #endif
diff --git a/base/mac/mach_port_broker.mm b/base/mac/mach_port_broker.mm
index 3d563ba..bd47017 100644
--- a/base/mac/mach_port_broker.mm
+++ b/base/mac/mach_port_broker.mm
@@ -163,8 +163,11 @@
   mach_port_t child_task_port = msg.child_task_port.name;
 
   // Take the lock and update the broker information.
-  base::AutoLock lock(lock_);
-  FinalizePid(child_pid, child_task_port);
+  {
+    base::AutoLock lock(lock_);
+    FinalizePid(child_pid, child_task_port);
+  }
+  NotifyObservers(child_pid);
 }
 
 void MachPortBroker::FinalizePid(base::ProcessHandle pid,
diff --git a/base/mac/mach_port_broker_unittest.cc b/base/mac/mach_port_broker_unittest.cc
index 2188ea3..c15afb6 100644
--- a/base/mac/mach_port_broker_unittest.cc
+++ b/base/mac/mach_port_broker_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
 #include "base/test/multiprocess_test.h"
 #include "base/test/test_timeouts.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -17,9 +18,18 @@
 const char kBootstrapPortName[] = "thisisatest";
 }
 
-class MachPortBrokerTest : public testing::Test {
+class MachPortBrokerTest : public testing::Test,
+                           public base::PortProvider::Observer {
  public:
-  MachPortBrokerTest() : broker_(kBootstrapPortName) {}
+  MachPortBrokerTest()
+      : broker_(kBootstrapPortName),
+        event_(true, false),
+        received_process_(kNullProcessHandle) {
+    broker_.AddObserver(this);
+  }
+  ~MachPortBrokerTest() override {
+    broker_.RemoveObserver(this);
+  }
 
   // Helper function to acquire/release locks and call |PlaceholderForPid()|.
   void AddPlaceholderForPid(base::ProcessHandle pid) {
@@ -34,8 +44,20 @@
     broker_.FinalizePid(pid, task_port);
   }
 
+  void WaitForTaskPort() {
+    event_.Wait();
+  }
+
+  // base::PortProvider::Observer:
+  void OnReceivedTaskPort(ProcessHandle process) override {
+    received_process_ = process;
+    event_.Signal();
+  }
+
  protected:
   MachPortBroker broker_;
+  WaitableEvent event_;
+  ProcessHandle received_process_;
 };
 
 TEST_F(MachPortBrokerTest, Locks) {
@@ -77,6 +99,9 @@
   broker_.AddPlaceholderForPid(test_child_process.Handle());
   broker_.GetLock().Release();
 
+  WaitForTaskPort();
+  EXPECT_EQ(test_child_process.Handle(), received_process_);
+
   int rv = -1;
   ASSERT_TRUE(test_child_process.WaitForExitWithTimeout(
       TestTimeouts::action_timeout(), &rv));
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h
index db0d04b..9ff0776b 100644
--- a/base/memory/scoped_ptr.h
+++ b/base/memory/scoped_ptr.h
@@ -122,7 +122,7 @@
 // Now that scoped_ptr is almost 100% compatible with std::unique_ptr, we're
 // incrementally migrating scoped_ptr to just be a type alias for
 // std::unique_ptr. The eventual goal is to delete scoped_ptr altogether.
-#if defined(OS_LINUX) || defined(OS_WIN)
+#if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_ANDROID)
 template <typename T, typename D = std::default_delete<T>>
 using scoped_ptr = std::unique_ptr<T, D>;
 
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
index ea4f816..7feacdb 100644
--- a/base/metrics/histogram.cc
+++ b/base/metrics/histogram.cc
@@ -154,10 +154,22 @@
   ImportPersistentHistograms();
 
   HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_);
+
+  // crbug.com/588946 debugging. See comment at end of function.
+  const BucketRanges* created_ranges =
+      reinterpret_cast<const BucketRanges*>(0xDEADBEEF);
+  const BucketRanges* registered_ranges =
+      reinterpret_cast<const BucketRanges*>(0xDEADBEEF);
+  HistogramBase* tentative_histogram =
+      reinterpret_cast<HistogramBase*>(0xDEADBEEF);
+  PersistentMemoryAllocator* allocator =
+      reinterpret_cast<PersistentMemoryAllocator*>(0xDEADBEEF);
+  PersistentMemoryAllocator::Reference histogram_ref = 0xDEADBEEF;
+
   if (!histogram) {
     // To avoid racy destruction at shutdown, the following will be leaked.
-    const BucketRanges* created_ranges = CreateRanges();
-    const BucketRanges* registered_ranges =
+    created_ranges = CreateRanges();
+    registered_ranges =
         StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges);
 
     // In most cases, the bucket-count, minimum, and maximum values are known
@@ -170,15 +182,17 @@
       minimum_ = registered_ranges->range(1);
       maximum_ = registered_ranges->range(bucket_count_ - 1);
     }
+    CHECK_LT(0, minimum_);
+    CHECK_LT(0, maximum_);
 
     // Try to create the histogram using a "persistent" allocator. As of
     // 2015-01-14, the availability of such is controlled by a base::Feature
     // that is off by default. If the allocator doesn't exist or if
     // allocating from it fails, code below will allocate the histogram from
     // the process heap.
-    PersistentMemoryAllocator::Reference histogram_ref = 0;
-    HistogramBase* tentative_histogram = nullptr;
-    PersistentMemoryAllocator* allocator =
+    histogram_ref = 0;
+    tentative_histogram = nullptr;
+    allocator =
         GetPersistentHistogramMemoryAllocator();
     if (allocator) {
       flags_ |= HistogramBase::kIsPersistent;
@@ -191,6 +205,12 @@
           registered_ranges,
           flags_,
           &histogram_ref);
+      CHECK_LT(0, minimum_);
+      CHECK_LT(0, maximum_);
+      CHECK_EQ(minimum_,
+               static_cast<Histogram*>(tentative_histogram)->declared_min_);
+      CHECK_EQ(maximum_,
+               static_cast<Histogram*>(tentative_histogram)->declared_max_);
     }
 
     // Handle the case where no persistent allocator is present or the
@@ -200,6 +220,12 @@
       DCHECK(!allocator);  // Shouldn't have failed.
       flags_ &= ~HistogramBase::kIsPersistent;
       tentative_histogram = HeapAlloc(registered_ranges);
+      CHECK_LT(0, minimum_);
+      CHECK_LT(0, maximum_);
+      CHECK_EQ(minimum_,
+               static_cast<Histogram*>(tentative_histogram)->declared_min_);
+      CHECK_EQ(maximum_,
+               static_cast<Histogram*>(tentative_histogram)->declared_max_);
     }
 
     FillHistogram(tentative_histogram);
@@ -214,6 +240,15 @@
   }
 
   DCHECK_EQ(histogram_type_, histogram->GetHistogramType());
+  bool bad_args = false;
+  HistogramBase* existing_histogram = histogram;
+  HistogramType existing_type = histogram->GetHistogramType();
+  const char* existing_name = histogram->histogram_name().c_str();
+  Sample existing_minimum = static_cast<Histogram*>(histogram)->declared_min_;
+  Sample existing_maximum = static_cast<Histogram*>(histogram)->declared_max_;
+  uint32_t existing_bucket_count =
+    static_cast<Histogram*>(histogram)->bucket_count();
+
   if (bucket_count_ != 0 &&
       !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) {
     // The construction arguments do not match the existing histogram.  This can
@@ -223,8 +258,45 @@
     // on dereference, but extension/Pepper APIs will guard against NULL and not
     // crash.
     DLOG(ERROR) << "Histogram " << name_ << " has bad construction arguments";
-    return nullptr;
+    bad_args = true;
+    histogram = nullptr;
   }
+
+#if !DCHECK_IS_ON()  // Don't affect tests, only release builds.
+  // For the moment, crash here so that collected crash reports have access
+  // to the construction values in order to figure out why this is failing.
+  // TODO(bcwhite): Remove this once crbug.com/588946 is resolved. Also remove
+  // from beta-branch because we don't want crashes due to misbehaving
+  // extensions (see comment above).
+  if (!histogram) {
+    HistogramType histogram_type = histogram_type_;
+    HistogramBase::Sample minimum = minimum_;
+    HistogramBase::Sample maximum = maximum_;
+    uint32_t bucket_count = bucket_count_;
+    int32_t flags = flags_;
+    CHECK(histogram) << name_ << ": bad-args=" << bad_args;
+    base::debug::Alias(&histogram_type);
+    base::debug::Alias(&minimum);
+    base::debug::Alias(&maximum);
+    base::debug::Alias(&bucket_count);
+    base::debug::Alias(&flags);
+    base::debug::Alias(&created_ranges);
+    base::debug::Alias(&registered_ranges);
+    base::debug::Alias(&histogram_ref);
+    base::debug::Alias(&tentative_histogram);
+    base::debug::Alias(&allocator);
+    base::debug::Alias(&tentative_histogram);
+  }
+#endif
+
+  // Down here so vars are always "used".
+  base::debug::Alias(&bad_args);
+  base::debug::Alias(&existing_histogram);
+  base::debug::Alias(&existing_type);
+  base::debug::Alias(&existing_name);
+  base::debug::Alias(&existing_minimum);
+  base::debug::Alias(&existing_maximum);
+  base::debug::Alias(&existing_bucket_count);
   return histogram;
 }
 
@@ -486,8 +558,12 @@
     bucket_ranges_(ranges),
     declared_min_(minimum),
     declared_max_(maximum) {
+  CHECK_LT(0, minimum);
+  CHECK_LT(0, maximum);
   if (ranges)
     samples_.reset(new SampleVector(HashMetricName(name), ranges));
+  CHECK_EQ(minimum, declared_min_);
+  CHECK_EQ(maximum, declared_max_);
 }
 
 Histogram::Histogram(const std::string& name,
@@ -503,12 +579,16 @@
     bucket_ranges_(ranges),
     declared_min_(minimum),
     declared_max_(maximum) {
+  CHECK_LT(0, minimum);
+  CHECK_LT(0, maximum);
   if (ranges) {
     samples_.reset(new SampleVector(HashMetricName(name),
                                     counts, counts_size, meta, ranges));
     logged_samples_.reset(new SampleVector(samples_->id(), logged_counts,
                                            counts_size, logged_meta, ranges));
   }
+  CHECK_EQ(minimum, declared_min_);
+  CHECK_EQ(maximum, declared_max_);
 }
 
 Histogram::~Histogram() {
diff --git a/base/metrics/histogram_persistence.cc b/base/metrics/histogram_persistence.cc
index f18d175..34b3100b 100644
--- a/base/metrics/histogram_persistence.cc
+++ b/base/metrics/histogram_persistence.cc
@@ -244,6 +244,12 @@
   // validated below; the local copy is to ensure that the contents cannot
   // be externally changed between validation and use.
   PersistentHistogramData histogram_data = *histogram_data_ptr;
+  CHECK_EQ(histogram_data.histogram_type, histogram_data_ptr->histogram_type);
+  CHECK_EQ(histogram_data.flags, histogram_data_ptr->flags);
+  CHECK_EQ(histogram_data.minimum, histogram_data_ptr->minimum);
+  CHECK_EQ(histogram_data.maximum, histogram_data_ptr->maximum);
+  CHECK_EQ(histogram_data.bucket_count, histogram_data_ptr->bucket_count);
+  CHECK_EQ(histogram_data.ranges_checksum, histogram_data_ptr->ranges_checksum);
 
   HistogramBase::Sample* ranges_data =
       allocator->GetAsObject<HistogramBase::Sample>(histogram_data.ranges_ref,
@@ -288,6 +294,8 @@
   HistogramBase::AtomicCount* logged_data =
       counts_data + histogram_data.bucket_count;
 
+  CHECK_LT(0, histogram_data.minimum);
+  CHECK_LT(0, histogram_data.maximum);
   std::string name(histogram_data_ptr->name);
   HistogramBase* histogram = nullptr;
   switch (histogram_data.histogram_type) {
diff --git a/base/metrics/histogram_unittest.cc b/base/metrics/histogram_unittest.cc
index beb6a71..e6aefd3 100644
--- a/base/metrics/histogram_unittest.cc
+++ b/base/metrics/histogram_unittest.cc
@@ -668,7 +668,7 @@
   EXPECT_FALSE(iter.SkipBytes(1));
 }
 
-TEST_P(HistogramTest, BadConstruction) {
+TEST_P(HistogramTest, DISABLED_BadConstruction) {
   HistogramBase* histogram = Histogram::FactoryGet(
       "BadConstruction", 0, 100, 8, HistogramBase::kNoFlags);
   EXPECT_TRUE(histogram->HasConstructionArguments(1, 100, 8));
diff --git a/base/metrics/metrics_hashes.cc b/base/metrics/metrics_hashes.cc
index 5672b06d..54c117b 100644
--- a/base/metrics/metrics_hashes.cc
+++ b/base/metrics/metrics_hashes.cc
@@ -4,6 +4,7 @@
 
 #include "base/metrics/metrics_hashes.h"
 
+#include "base/debug/alias.h"
 #include "base/logging.h"
 #include "base/md5.h"
 #include "base/sys_byteorder.h"
@@ -15,9 +16,14 @@
 // Converts the 8-byte prefix of an MD5 hash into a uint64_t value.
 inline uint64_t DigestToUInt64(const base::MD5Digest& digest) {
   uint64_t value;
-  DCHECK_GE(sizeof(digest.a), sizeof(value));
+  CHECK_GE(sizeof(digest.a), sizeof(value));
   memcpy(&value, digest.a, sizeof(value));
-  return base::NetToHost64(value);
+  uint64_t hash = base::NetToHost64(value);
+  CHECK_NE(0U, hash);
+  base::debug::Alias(&hash);
+  base::debug::Alias(&value);
+  base::debug::Alias(&digest);
+  return hash;
 }
 
 }  // namespace
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index d0fa2ad..90d64bb 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -5,6 +5,7 @@
 #include "base/metrics/statistics_recorder.h"
 
 #include "base/at_exit.h"
+#include "base/debug/alias.h"
 #include "base/debug/leak_annotations.h"
 #include "base/json/string_escape.h"
 #include "base/logging.h"
@@ -123,13 +124,17 @@
         histogram_to_return = histogram;
       } else {
         // We already have one histogram with this name.
-        DCHECK_EQ(histogram->histogram_name(),
-                  it->second->histogram_name()) << "hash collision";
+        CHECK_EQ(histogram->histogram_name(),
+                 it->second->histogram_name()) << "hash collision";
         histogram_to_return = it->second;
         histogram_to_delete = histogram;
       }
+      base::debug::Alias(&it);
+      base::debug::Alias(&name);
+      base::debug::Alias(&name_hash);
     }
   }
+  base::debug::Alias(&histogram);
   delete histogram_to_delete;
   return histogram_to_return;
 }
@@ -279,10 +284,22 @@
   if (histograms_ == NULL)
     return NULL;
 
-  HistogramMap::iterator it = histograms_->find(HashMetricName(name));
+  const uint64_t lookup_hash = HashMetricName(name);
+  HistogramMap::iterator it = histograms_->find(lookup_hash);
   if (histograms_->end() == it)
     return NULL;
-  DCHECK_EQ(name, it->second->histogram_name()) << "hash collision";
+
+  const uint64_t existing_hash = it->first;
+  const char* existing_name = it->second->histogram_name().c_str();
+  HistogramMap* histograms = histograms_;
+  CHECK_EQ(name, it->second->histogram_name()) << "hash collision";
+  base::debug::Alias(&lookup_hash);
+  base::debug::Alias(&existing_hash);
+  base::debug::Alias(&name);
+  base::debug::Alias(&existing_name);
+  base::debug::Alias(&it);
+  base::debug::Alias(&histograms);
+
   return it->second;
 }
 
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
index c429375..99dae66 100644
--- a/base/win/scoped_handle.cc
+++ b/base/win/scoped_handle.cc
@@ -41,16 +41,11 @@
 };
 typedef std::unordered_map<HANDLE, Info, HandleHash> HandleMap;
 
-// g_lock protects the handle map and setting g_active_verifier.
+// g_lock protects the handle map and setting g_active_verifier within this
+// module.
 typedef base::internal::LockImpl NativeLock;
 base::LazyInstance<NativeLock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER;
 
-bool CloseHandleWrapper(HANDLE handle) {
-  if (!::CloseHandle(handle))
-    CHECK(false);  // CloseHandle failed.
-  return true;
-}
-
 // Simple automatic locking using a native critical section so it supports
 // recursive locking.
 class AutoNativeLock {
@@ -113,11 +108,30 @@
   return g_active_verifier;
 }
 
+bool CloseHandleWrapper(HANDLE handle) {
+  if (!::CloseHandle(handle))
+    CHECK(false);  // CloseHandle failed.
+  return true;
+}
+
+// Assigns the g_active_verifier global within the g_lock lock.
+// If |existing_verifier| is non-null then |enabled| is ignored.
+void ThreadSafeAssignOrCreateActiveVerifier(ActiveVerifier* existing_verifier,
+                                            bool enabled) {
+  AutoNativeLock lock(g_lock.Get());
+  // Another thread in this module might be trying to assign the global
+  // verifier, so check that within the lock here.
+  if (g_active_verifier)
+    return;
+  g_active_verifier =
+      existing_verifier ? existing_verifier : new ActiveVerifier(enabled);
+}
+
 // static
 void ActiveVerifier::InstallVerifier() {
 #if defined(COMPONENT_BUILD)
-  AutoNativeLock lock(g_lock.Get());
-  g_active_verifier = new ActiveVerifier(true);
+  // Component build has one Active Verifier per module.
+  ThreadSafeAssignOrCreateActiveVerifier(nullptr, true);
 #else
   // If you are reading this, wondering why your process seems deadlocked, take
   // a look at your DllMain code and remove things that should not be done
@@ -128,17 +142,27 @@
       reinterpret_cast<GetHandleVerifierFn>(::GetProcAddress(
           main_module, "GetHandleVerifier"));
 
+  // This should only happen if running in a DLL is linked with base but the
+  // hosting EXE is not. In this case, create an ActiveVerifier for the current
+  // module but leave it disabled.
   if (!get_handle_verifier) {
-    g_active_verifier = new ActiveVerifier(false);
+    ThreadSafeAssignOrCreateActiveVerifier(nullptr, false);
     return;
   }
 
-  ActiveVerifier* verifier =
+  // Check if in the main module.
+  if (get_handle_verifier == GetHandleVerifier) {
+    ThreadSafeAssignOrCreateActiveVerifier(nullptr, true);
+    return;
+  }
+
+  ActiveVerifier* main_module_verifier =
       reinterpret_cast<ActiveVerifier*>(get_handle_verifier());
 
-  // This lock only protects against races in this module, which is fine.
-  AutoNativeLock lock(g_lock.Get());
-  g_active_verifier = verifier ? verifier : new ActiveVerifier(true);
+  // Main module should always on-demand create a verifier.
+  DCHECK(main_module_verifier);
+
+  ThreadSafeAssignOrCreateActiveVerifier(main_module_verifier, false);
 #endif
 }
 
@@ -221,7 +245,7 @@
 }  // namespace
 
 void* GetHandleVerifier() {
-  return g_active_verifier;
+  return ActiveVerifier::Get();
 }
 
 namespace base {
diff --git a/build/all.gyp b/build/all.gyp
index 280dcdda..8f5e701 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -57,7 +57,6 @@
             '../mojo/mojo_edk.gyp:mojo_system_impl',
             '../mojo/mojo_edk_tests.gyp:mojo_public_bindings_unittests',
             '../mojo/mojo_edk_tests.gyp:mojo_public_system_unittests',
-            '../mojo/mojo_edk_tests.gyp:mojo_public_utility_unittests',
             '../mojo/mojo_edk_tests.gyp:mojo_system_unittests',
             '../mojo/mojo_public.gyp:mojo_cpp_bindings',
             '../mojo/mojo_public.gyp:mojo_public_test_utils',
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn
index f998edba..9766c87 100644
--- a/build/android/BUILD.gn
+++ b/build/android/BUILD.gn
@@ -80,9 +80,14 @@
   data = [
     "devil_chromium.json",
     "devil_chromium.py",
-    "//third_party/catapult/catapult_base/",
-    "//third_party/catapult/dependency_manager/",
-    "//third_party/catapult/devil/",
+    "//third_party/android_tools/sdk/build-tools/23.0.0/aapt",
+    "//third_party/android_tools/sdk/build-tools/23.0.0/dexdump",
+    "//third_party/android_tools/sdk/build-tools/23.0.0/split-select",
+    "//third_party/android_tools/sdk/platform-tools/adb",
+    "//third_party/catapult/catapult_base/catapult_base/",
+    "//third_party/catapult/dependency_manager/dependency_manager/",
+    "//third_party/catapult/third_party/gsutil/",
+    "//third_party/catapult/devil/devil/",
   ]
 }
 
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
index 5d0f7db..3a4e4b5 100644
--- a/build/gn_migration.gypi
+++ b/build/gn_migration.gypi
@@ -285,7 +285,6 @@
             '../mojo/mojo_edk_tests.gyp:mojo_public_bindings_unittests',
             '../mojo/mojo_edk_tests.gyp:mojo_public_system_perftests',
             '../mojo/mojo_edk_tests.gyp:mojo_public_system_unittests',
-            '../mojo/mojo_edk_tests.gyp:mojo_public_utility_unittests',
             '../net/net.gyp:crash_cache',
             '../net/net.gyp:crl_set_dump',
             '../net/net.gyp:dns_fuzz_stub',
@@ -567,7 +566,6 @@
             '../media/midi/midi.gyp:midi_unittests_run',
             '../mojo/mojo_edk_tests.gyp:mojo_public_bindings_unittests_run',
             '../mojo/mojo_edk_tests.gyp:mojo_public_system_unittests_run',
-            '../mojo/mojo_edk_tests.gyp:mojo_public_utility_unittests_run',
             '../net/net.gyp:net_unittests_run',
             '../ppapi/ppapi_internal.gyp:ppapi_unittests_run',
             '../printing/printing.gyp:printing_unittests_run',
diff --git a/build/secondary/third_party/android_tools/BUILD.gn b/build/secondary/third_party/android_tools/BUILD.gn
index ba4f498..ce73c640 100644
--- a/build/secondary/third_party/android_tools/BUILD.gn
+++ b/build/secondary/third_party/android_tools/BUILD.gn
@@ -122,6 +122,21 @@
   jar_path = "$android_sdk_root/extras/google/google_play_services/libproject/google-play-services_lib/libs/google-play-services.jar"
 }
 
+android_resources("android_support_v17_leanback_resources") {
+  v14_skip = true
+  resource_dirs =
+      [ "$android_sdk_root/extras/android/support/v17/leanback/res" ]
+  custom_package = "android.support.v17.leanback"
+}
+
+android_java_prebuilt("android_support_v17_leanback_java") {
+  deps = [
+    ":android_support_v17_leanback_resources",
+    ":android_support_v7_recyclerview_java",
+  ]
+  jar_path = "$android_sdk_root/extras/android/support/v17/leanback/libs/android-support-v17-leanback.jar"
+}
+
 # TODO(jbudorick): Remove this once net_java_test_support no longer needs it.
 android_java_prebuilt("legacy_http_javalib") {
   jar_path = "$android_sdk/optional/org.apache.http.legacy.jar"
diff --git a/cc/animation/layer_animation_controller.h b/cc/animation/layer_animation_controller.h
index 28a4523c..c6cc506 100644
--- a/cc/animation/layer_animation_controller.h
+++ b/cc/animation/layer_animation_controller.h
@@ -52,9 +52,8 @@
 
   // Ensures that the list of active animations on the main thread and the impl
   // thread are kept in sync. This function does not take ownership of the impl
-  // thread controller. This method is virtual for testing.
-  virtual void PushAnimationUpdatesTo(
-      LayerAnimationController* controller_impl);
+  // thread controller.
+  void PushAnimationUpdatesTo(LayerAnimationController* controller_impl);
 
   void Animate(base::TimeTicks monotonic_time);
   void AccumulatePropertyUpdates(base::TimeTicks monotonic_time,
@@ -170,13 +169,12 @@
     return needs_to_start_animations_;
   }
 
- protected:
+ private:
   friend class base::RefCounted<LayerAnimationController>;
 
   explicit LayerAnimationController(int id);
-  virtual ~LayerAnimationController();
+  ~LayerAnimationController();
 
- private:
   using TargetProperties = std::unordered_set<int>;
 
   void PushNewAnimationsToImplThread(
diff --git a/cc/blink/web_layer_impl.cc b/cc/blink/web_layer_impl.cc
index 0512cf5..2d578fc2 100644
--- a/cc/blink/web_layer_impl.cc
+++ b/cc/blink/web_layer_impl.cc
@@ -30,7 +30,6 @@
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/vector2d_conversions.h"
 
-using cc::Animation;
 using cc::Layer;
 using blink::WebLayer;
 using blink::WebFloatPoint;
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 7f51dc0e..854effe 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -15,10 +15,6 @@
 #include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
-#include "cc/animation/animation.h"
-#include "cc/animation/animation_registrar.h"
-#include "cc/animation/keyframed_animation_curve.h"
-#include "cc/animation/layer_animation_controller.h"
 #include "cc/animation/mutable_properties.h"
 #include "cc/base/simple_enclosed_region.h"
 #include "cc/debug/frame_viewer_instrumentation.h"
@@ -102,11 +98,6 @@
       client_(nullptr),
       num_unclipped_descendants_(0),
       frame_timing_requests_dirty_(false) {
-  if (!settings.use_compositor_animation_timelines) {
-    layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
-    layer_animation_controller_->AddValueObserver(this);
-    layer_animation_controller_->set_value_provider(this);
-  }
 }
 
 Layer::~Layer() {
@@ -117,11 +108,6 @@
   // reference to us.
   DCHECK(!layer_tree_host());
 
-  if (layer_animation_controller_) {
-    layer_animation_controller_->RemoveValueObserver(this);
-    layer_animation_controller_->remove_value_provider(this);
-  }
-
   RemoveFromScrollTree();
   RemoveFromClipTree();
 
@@ -166,14 +152,8 @@
   if (replica_layer_.get())
     replica_layer_->SetLayerTreeHost(host);
 
-  if (host)
-    RegisterForAnimations(host->animation_registrar());
-
-  bool has_any_animation = false;
-  if (layer_animation_controller_)
-    has_any_animation = layer_animation_controller_->has_any_animation();
-  else if (layer_tree_host_)
-    has_any_animation = layer_tree_host_->HasAnyAnimation(this);
+  const bool has_any_animation =
+      layer_tree_host_ ? layer_tree_host_->HasAnyAnimation(this) : false;
 
   if (host && has_any_animation)
     host->SetNeedsCommit();
@@ -505,18 +485,10 @@
 
 bool Layer::FilterIsAnimating() const {
   DCHECK(layer_tree_host_);
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsCurrentlyAnimatingProperty(
-                   TargetProperty::FILTER,
-                   LayerAnimationController::ObserverType::ACTIVE)
-             : layer_tree_host_->IsAnimatingFilterProperty(this);
+  return layer_tree_host_->IsAnimatingFilterProperty(this);
 }
 
 bool Layer::HasPotentiallyRunningFilterAnimation() const {
-  if (layer_animation_controller_) {
-    return layer_animation_controller_->IsPotentiallyAnimatingProperty(
-        TargetProperty::FILTER, LayerAnimationController::ObserverType::ACTIVE);
-  }
   return layer_tree_host_->HasPotentiallyRunningFilterAnimation(this);
 }
 
@@ -543,19 +515,10 @@
 
 bool Layer::OpacityIsAnimating() const {
   DCHECK(layer_tree_host_);
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsCurrentlyAnimatingProperty(
-                   TargetProperty::OPACITY,
-                   LayerAnimationController::ObserverType::ACTIVE)
-             : layer_tree_host_->IsAnimatingOpacityProperty(this);
+  return layer_tree_host_->IsAnimatingOpacityProperty(this);
 }
 
 bool Layer::HasPotentiallyRunningOpacityAnimation() const {
-  if (layer_animation_controller_) {
-    return layer_animation_controller_->IsPotentiallyAnimatingProperty(
-        TargetProperty::OPACITY,
-        LayerAnimationController::ObserverType::ACTIVE);
-  }
   return layer_tree_host_->HasPotentiallyRunningOpacityAnimation(this);
 }
 
@@ -749,67 +712,38 @@
 
 bool Layer::AnimationsPreserveAxisAlignment() const {
   DCHECK(layer_tree_host_);
-  return layer_animation_controller_
-             ? layer_animation_controller_->AnimationsPreserveAxisAlignment()
-             : layer_tree_host_->AnimationsPreserveAxisAlignment(this);
+  return layer_tree_host_->AnimationsPreserveAxisAlignment(this);
 }
 
 bool Layer::TransformIsAnimating() const {
   DCHECK(layer_tree_host_);
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsCurrentlyAnimatingProperty(
-                   TargetProperty::TRANSFORM,
-                   LayerAnimationController::ObserverType::ACTIVE)
-             : layer_tree_host_->IsAnimatingTransformProperty(this);
+  return layer_tree_host_->IsAnimatingTransformProperty(this);
 }
 
 bool Layer::HasPotentiallyRunningTransformAnimation() const {
-  if (layer_animation_controller_) {
-    return layer_animation_controller_->IsPotentiallyAnimatingProperty(
-        TargetProperty::TRANSFORM,
-        LayerAnimationController::ObserverType::ACTIVE);
-  }
   return layer_tree_host_->HasPotentiallyRunningTransformAnimation(this);
 }
 
 bool Layer::HasOnlyTranslationTransforms() const {
-  if (layer_animation_controller_) {
-    return layer_animation_controller_->HasOnlyTranslationTransforms(
-        LayerAnimationController::ObserverType::ACTIVE);
-  }
   return layer_tree_host_->HasOnlyTranslationTransforms(this);
 }
 
 bool Layer::MaximumTargetScale(float* max_scale) const {
-  if (layer_animation_controller_) {
-    return layer_animation_controller_->MaximumTargetScale(
-        LayerAnimationController::ObserverType::ACTIVE, max_scale);
-  }
   return layer_tree_host_->MaximumTargetScale(this, max_scale);
 }
 
 bool Layer::AnimationStartScale(float* start_scale) const {
-  if (layer_animation_controller_) {
-    return layer_animation_controller_->AnimationStartScale(
-        LayerAnimationController::ObserverType::ACTIVE, start_scale);
-  }
   return layer_tree_host_->AnimationStartScale(this, start_scale);
 }
 
 bool Layer::HasAnyAnimationTargetingProperty(
     TargetProperty::Type property) const {
-  if (layer_animation_controller_)
-    return !!layer_animation_controller_->GetAnimation(property);
-
   return layer_tree_host_->HasAnyAnimationTargetingProperty(this, property);
 }
 
 bool Layer::ScrollOffsetAnimationWasInterrupted() const {
   DCHECK(layer_tree_host_);
-  return layer_animation_controller_
-             ? layer_animation_controller_
-                   ->scroll_offset_animation_was_interrupted()
-             : layer_tree_host_->ScrollOffsetAnimationWasInterrupted(this);
+  return layer_tree_host_->ScrollOffsetAnimationWasInterrupted(this);
 }
 
 void Layer::SetScrollParent(Layer* parent) {
@@ -1383,10 +1317,6 @@
   update_rect_.Union(layer->update_rect());
   layer->SetUpdateRect(update_rect_);
 
-  if (layer->layer_animation_controller() && layer_animation_controller_)
-    layer_animation_controller_->PushAnimationUpdatesTo(
-        layer->layer_animation_controller());
-
   if (frame_timing_requests_dirty_) {
     layer->SetFrameTimingRequests(frame_timing_requests_);
     frame_timing_requests_dirty_ = false;
@@ -1845,11 +1775,6 @@
   // compositor-driven scrolling.
 }
 
-void Layer::OnAnimationWaitingForDeletion() {
-  // Animations are only deleted during PushProperties.
-  SetNeedsPushProperties();
-}
-
 void Layer::OnTransformIsPotentiallyAnimatingChanged(bool is_animating) {
   if (!layer_tree_host_)
     return;
@@ -1888,73 +1813,9 @@
   return true;
 }
 
-bool Layer::AddAnimation(scoped_ptr <Animation> animation) {
-  DCHECK(layer_animation_controller_);
-  if (!layer_animation_controller_->animation_registrar())
-    return false;
-
-  if (animation->target_property() == TargetProperty::SCROLL_OFFSET &&
-      !layer_animation_controller_->animation_registrar()
-           ->supports_scroll_animations())
-    return false;
-
-  UMA_HISTOGRAM_BOOLEAN("Renderer.AnimationAddedToOrphanLayer",
-                        !layer_tree_host_);
-  layer_animation_controller_->AddAnimation(std::move(animation));
-  SetNeedsCommit();
-  return true;
-}
-
-void Layer::PauseAnimation(int animation_id, double time_offset) {
-  DCHECK(layer_animation_controller_);
-  layer_animation_controller_->PauseAnimation(
-      animation_id, base::TimeDelta::FromSecondsD(time_offset));
-  SetNeedsCommit();
-}
-
-void Layer::RemoveAnimation(int animation_id) {
-  DCHECK(layer_animation_controller_);
-  layer_animation_controller_->RemoveAnimation(animation_id);
-  SetNeedsCommit();
-}
-
-void Layer::AbortAnimation(int animation_id) {
-  DCHECK(layer_animation_controller_);
-  layer_animation_controller_->AbortAnimation(animation_id);
-  SetNeedsCommit();
-}
-
-void Layer::SetLayerAnimationControllerForTest(
-    scoped_refptr<LayerAnimationController> controller) {
-  DCHECK(layer_animation_controller_);
-  layer_animation_controller_->RemoveValueObserver(this);
-  layer_animation_controller_ = controller;
-  layer_animation_controller_->AddValueObserver(this);
-  SetNeedsCommit();
-}
-
 bool Layer::HasActiveAnimation() const {
   DCHECK(layer_tree_host_);
-  return layer_animation_controller_
-             ? layer_animation_controller_->HasActiveAnimation()
-             : layer_tree_host_->HasActiveAnimation(this);
-}
-
-void Layer::RegisterForAnimations(AnimationRegistrar* registrar) {
-  if (layer_animation_controller_)
-    layer_animation_controller_->SetAnimationRegistrar(registrar);
-}
-
-void Layer::AddLayerAnimationEventObserver(
-    LayerAnimationEventObserver* animation_observer) {
-  DCHECK(layer_animation_controller_);
-  layer_animation_controller_->AddEventObserver(animation_observer);
-}
-
-void Layer::RemoveLayerAnimationEventObserver(
-    LayerAnimationEventObserver* animation_observer) {
-  DCHECK(layer_animation_controller_);
-  layer_animation_controller_->RemoveEventObserver(animation_observer);
+  return layer_tree_host_->HasActiveAnimation(this);
 }
 
 ScrollbarLayerInterface* Layer::ToScrollbarLayer() {
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index edd0eaaae9..c14f14d 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -17,9 +17,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/observer_list.h"
-#include "cc/animation/layer_animation_controller.h"
-#include "cc/animation/layer_animation_value_observer.h"
-#include "cc/animation/layer_animation_value_provider.h"
+#include "cc/animation/target_property.h"
 #include "cc/base/cc_export.h"
 #include "cc/base/region.h"
 #include "cc/debug/frame_timing_request.h"
@@ -53,9 +51,6 @@
 
 namespace cc {
 
-class Animation;
-class AnimationDelegate;
-struct AnimationEvent;
 class CopyOutputRequest;
 class LayerAnimationEventObserver;
 class LayerClient;
@@ -69,7 +64,6 @@
 class ResourceUpdateQueue;
 class ScrollbarLayerInterface;
 class SimpleEnclosedRegion;
-struct AnimationEvent;
 
 namespace proto {
 class LayerNode;
@@ -79,9 +73,7 @@
 
 // Base class for composited layers. Special layer types are derived from
 // this class.
-class CC_EXPORT Layer : public base::RefCounted<Layer>,
-                        public LayerAnimationValueObserver,
-                        public LayerAnimationValueProvider {
+class CC_EXPORT Layer : public base::RefCounted<Layer> {
  public:
   using LayerListType = LayerList;
   using LayerIdMap = std::unordered_map<int, scoped_refptr<Layer>>;
@@ -414,28 +406,7 @@
   LayerTreeHost* layer_tree_host() { return layer_tree_host_; }
   const LayerTreeHost* layer_tree_host() const { return layer_tree_host_; }
 
-  bool AddAnimation(scoped_ptr<Animation> animation);
-  void PauseAnimation(int animation_id, double time_offset);
-  void RemoveAnimation(int animation_id);
-  void AbortAnimation(int animation_id);
-  LayerAnimationController* layer_animation_controller() const {
-    return layer_animation_controller_.get();
-  }
-  void SetLayerAnimationControllerForTest(
-      scoped_refptr<LayerAnimationController> controller);
-
-  void set_layer_animation_delegate(AnimationDelegate* delegate) {
-    DCHECK(layer_animation_controller_);
-    layer_animation_controller_->set_layer_animation_delegate(delegate);
-  }
-
   bool HasActiveAnimation() const;
-  void RegisterForAnimations(AnimationRegistrar* registrar);
-
-  void AddLayerAnimationEventObserver(
-      LayerAnimationEventObserver* animation_observer);
-  void RemoveLayerAnimationEventObserver(
-      LayerAnimationEventObserver* animation_observer);
 
   virtual ScrollbarLayerInterface* ToScrollbarLayer();
 
@@ -550,22 +521,19 @@
   void set_sorted_for_recursion(bool sorted_for_recursion);
   bool sorted_for_recursion();
 
-  // LayerAnimationValueProvider implementation.
-  gfx::ScrollOffset ScrollOffsetForAnimation() const override;
-
-  // LayerAnimationValueObserver implementation.
-  void OnFilterAnimated(const FilterOperations& filters) override;
-  void OnOpacityAnimated(float opacity) override;
-  void OnTransformAnimated(const gfx::Transform& transform) override;
-  void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) override;
-  void OnAnimationWaitingForDeletion() override;
-  void OnTransformIsPotentiallyAnimatingChanged(bool is_animating) override;
-  bool IsActive() const override;
+  // Interactions with attached animations.
+  gfx::ScrollOffset ScrollOffsetForAnimation() const;
+  void OnFilterAnimated(const FilterOperations& filters);
+  void OnOpacityAnimated(float opacity);
+  void OnTransformAnimated(const gfx::Transform& transform);
+  void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset);
+  void OnTransformIsPotentiallyAnimatingChanged(bool is_animating);
+  bool IsActive() const;
 
  protected:
   friend class LayerImpl;
   friend class TreeSynchronizer;
-  ~Layer() override;
+  virtual ~Layer();
 
   explicit Layer(const LayerSettings& settings);
 
@@ -685,8 +653,6 @@
   // updated via SetLayerTreeHost() if a layer moves between trees.
   LayerTreeHost* layer_tree_host_;
 
-  scoped_refptr<LayerAnimationController> layer_animation_controller_;
-
   // Layer properties.
   gfx::Size bounds_;
 
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index b10ab7e..08167ef 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -15,7 +15,6 @@
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_argument.h"
 #include "cc/animation/animation_host.h"
-#include "cc/animation/animation_registrar.h"
 #include "cc/animation/mutable_properties.h"
 #include "cc/base/math_util.h"
 #include "cc/base/simple_enclosed_region.h"
@@ -95,20 +94,9 @@
       layer_or_descendant_has_touch_handler_(false),
       sorted_for_recursion_(false) {
   DCHECK_GT(layer_id_, 0);
+
   DCHECK(layer_tree_impl_);
   layer_tree_impl_->RegisterLayer(this);
-
-  if (!layer_tree_impl_->settings().use_compositor_animation_timelines) {
-    AnimationRegistrar* registrar = layer_tree_impl_->GetAnimationRegistrar();
-    layer_animation_controller_ =
-        registrar->GetAnimationControllerForId(layer_id_);
-    layer_animation_controller_->AddValueObserver(this);
-    if (IsActive()) {
-      layer_animation_controller_->set_value_provider(this);
-      layer_animation_controller_->set_layer_animation_delegate(this);
-    }
-  }
-
   layer_tree_impl_->AddToElementMap(this);
 
   SetNeedsPushProperties();
@@ -117,12 +105,6 @@
 LayerImpl::~LayerImpl() {
   DCHECK_EQ(DRAW_MODE_NONE, current_draw_mode_);
 
-  if (layer_animation_controller_) {
-    layer_animation_controller_->RemoveValueObserver(this);
-    layer_animation_controller_->remove_value_provider(this);
-    layer_animation_controller_->remove_layer_animation_delegate(this);
-  }
-
   if (!copy_requests_.empty() && layer_tree_impl_->IsActiveTree())
     layer_tree_impl()->RemoveLayerWithCopyOutputRequest(this);
   layer_tree_impl_->UnregisterScrollLayer(this);
@@ -503,9 +485,6 @@
     if (layer_tree_impl()->ScrollOffsetIsAnimatingOnImplOnly(this)) {
       layer_tree_impl()->animation_host()->ScrollAnimationAbort(
           true /* needs_completion */);
-    } else if (layer_animation_controller()) {
-      layer_animation_controller()->AbortAnimations(
-          TargetProperty::SCROLL_OFFSET);
     }
   }
 
@@ -960,8 +939,6 @@
   layer_tree_impl_->DidAnimateScrollOffset();
 }
 
-void LayerImpl::OnAnimationWaitingForDeletion() {}
-
 void LayerImpl::OnTransformIsPotentiallyAnimatingChanged(bool is_animating) {
   UpdatePropertyTreeTransformIsAnimated(is_animating);
   was_ever_ready_since_last_transform_animation_ = false;
@@ -1126,32 +1103,15 @@
 }
 
 bool LayerImpl::FilterIsAnimating() const {
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsCurrentlyAnimatingProperty(
-                   TargetProperty::FILTER, observer_type)
-             : layer_tree_impl_->IsAnimatingFilterProperty(this);
+  return layer_tree_impl_->IsAnimatingFilterProperty(this);
 }
 
 bool LayerImpl::HasPotentiallyRunningFilterAnimation() const {
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsPotentiallyAnimatingProperty(
-                   TargetProperty::FILTER, observer_type)
-             : layer_tree_impl_->HasPotentiallyRunningFilterAnimation(this);
+  return layer_tree_impl_->HasPotentiallyRunningFilterAnimation(this);
 }
 
 bool LayerImpl::FilterIsAnimatingOnImplOnly() const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->FilterIsAnimatingOnImplOnly(this);
-
-  Animation* filter_animation =
-      layer_animation_controller_->GetAnimation(TargetProperty::FILTER);
-  return filter_animation && filter_animation->is_impl_only();
+  return layer_tree_impl_->FilterIsAnimatingOnImplOnly(this);
 }
 
 void LayerImpl::SetBackgroundFilters(
@@ -1189,32 +1149,15 @@
 }
 
 bool LayerImpl::OpacityIsAnimating() const {
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsCurrentlyAnimatingProperty(
-                   TargetProperty::OPACITY, observer_type)
-             : layer_tree_impl_->IsAnimatingOpacityProperty(this);
+  return layer_tree_impl_->IsAnimatingOpacityProperty(this);
 }
 
 bool LayerImpl::HasPotentiallyRunningOpacityAnimation() const {
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsPotentiallyAnimatingProperty(
-                   TargetProperty::OPACITY, observer_type)
-             : layer_tree_impl_->HasPotentiallyRunningOpacityAnimation(this);
+  return layer_tree_impl_->HasPotentiallyRunningOpacityAnimation(this);
 }
 
 bool LayerImpl::OpacityIsAnimatingOnImplOnly() const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->OpacityIsAnimatingOnImplOnly(this);
-
-  Animation* opacity_animation =
-      layer_animation_controller_->GetAnimation(TargetProperty::OPACITY);
-  return opacity_animation && opacity_animation->is_impl_only();
+  return layer_tree_impl_->OpacityIsAnimatingOnImplOnly(this);
 }
 
 void LayerImpl::SetElementId(uint64_t element_id) {
@@ -1320,117 +1263,58 @@
 }
 
 bool LayerImpl::TransformIsAnimating() const {
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsCurrentlyAnimatingProperty(
-                   TargetProperty::TRANSFORM, observer_type)
-             : layer_tree_impl_->IsAnimatingTransformProperty(this);
+  return layer_tree_impl_->IsAnimatingTransformProperty(this);
 }
 
 bool LayerImpl::HasPotentiallyRunningTransformAnimation() const {
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_
-             ? layer_animation_controller_->IsPotentiallyAnimatingProperty(
-                   TargetProperty::TRANSFORM, observer_type)
-             : layer_tree_impl_->HasPotentiallyRunningTransformAnimation(this);
+  return layer_tree_impl_->HasPotentiallyRunningTransformAnimation(this);
 }
 
 bool LayerImpl::TransformIsAnimatingOnImplOnly() const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->TransformIsAnimatingOnImplOnly(this);
-
-  Animation* transform_animation =
-      layer_animation_controller_->GetAnimation(TargetProperty::TRANSFORM);
-  return transform_animation && transform_animation->is_impl_only();
+  return layer_tree_impl_->TransformIsAnimatingOnImplOnly(this);
 }
 
 bool LayerImpl::HasOnlyTranslationTransforms() const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->HasOnlyTranslationTransforms(this);
-
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_->HasOnlyTranslationTransforms(
-      observer_type);
+  return layer_tree_impl_->HasOnlyTranslationTransforms(this);
 }
 
 bool LayerImpl::AnimationsPreserveAxisAlignment() const {
-  return layer_animation_controller_
-             ? layer_animation_controller_->AnimationsPreserveAxisAlignment()
-             : layer_tree_impl_->AnimationsPreserveAxisAlignment(this);
+  return layer_tree_impl_->AnimationsPreserveAxisAlignment(this);
 }
 
 bool LayerImpl::MaximumTargetScale(float* max_scale) const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->MaximumTargetScale(this, max_scale);
-
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_->MaximumTargetScale(observer_type,
-                                                         max_scale);
+  return layer_tree_impl_->MaximumTargetScale(this, max_scale);
 }
 
 bool LayerImpl::AnimationStartScale(float* start_scale) const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->AnimationStartScale(this, start_scale);
-
-  LayerAnimationController::ObserverType observer_type =
-      IsActive() ? LayerAnimationController::ObserverType::ACTIVE
-                 : LayerAnimationController::ObserverType::PENDING;
-  return layer_animation_controller_->AnimationStartScale(observer_type,
-                                                          start_scale);
+  return layer_tree_impl_->AnimationStartScale(this, start_scale);
 }
 
 bool LayerImpl::HasAnyAnimationTargetingProperty(
     TargetProperty::Type property) const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->HasAnyAnimationTargetingProperty(this, property);
-
-  return !!layer_animation_controller_->GetAnimation(property);
+  return layer_tree_impl_->HasAnyAnimationTargetingProperty(this, property);
 }
 
 bool LayerImpl::HasFilterAnimationThatInflatesBounds() const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->HasFilterAnimationThatInflatesBounds(this);
-
-  return layer_animation_controller_->HasFilterAnimationThatInflatesBounds();
+  return layer_tree_impl_->HasFilterAnimationThatInflatesBounds(this);
 }
 
 bool LayerImpl::HasTransformAnimationThatInflatesBounds() const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->HasTransformAnimationThatInflatesBounds(this);
-
-  return layer_animation_controller_->HasTransformAnimationThatInflatesBounds();
+  return layer_tree_impl_->HasTransformAnimationThatInflatesBounds(this);
 }
 
 bool LayerImpl::HasAnimationThatInflatesBounds() const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->HasAnimationThatInflatesBounds(this);
-
-  return layer_animation_controller_->HasAnimationThatInflatesBounds();
+  return layer_tree_impl_->HasAnimationThatInflatesBounds(this);
 }
 
 bool LayerImpl::FilterAnimationBoundsForBox(const gfx::BoxF& box,
                                             gfx::BoxF* bounds) const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->FilterAnimationBoundsForBox(this, box, bounds);
-
-  return layer_animation_controller_->FilterAnimationBoundsForBox(box, bounds);
+  return layer_tree_impl_->FilterAnimationBoundsForBox(this, box, bounds);
 }
 
 bool LayerImpl::TransformAnimationBoundsForBox(const gfx::BoxF& box,
                                                gfx::BoxF* bounds) const {
-  if (!layer_animation_controller_)
-    return layer_tree_impl_->TransformAnimationBoundsForBox(this, box, bounds);
-
-  return layer_animation_controller_->TransformAnimationBoundsForBox(box,
-                                                                     bounds);
+  return layer_tree_impl_->TransformAnimationBoundsForBox(this, box, bounds);
 }
 
 void LayerImpl::SetUpdateRect(const gfx::Rect& update_rect) {
@@ -1614,11 +1498,8 @@
   state->SetBoolean("can_use_lcd_text", can_use_lcd_text());
   state->SetBoolean("contents_opaque", contents_opaque());
 
-  state->SetBoolean(
-      "has_animation_bounds",
-      layer_animation_controller_
-          ? layer_animation_controller_->HasAnimationThatInflatesBounds()
-          : layer_tree_impl_->HasAnimationThatInflatesBounds(this));
+  state->SetBoolean("has_animation_bounds",
+                    layer_tree_impl_->HasAnimationThatInflatesBounds(this));
 
   gfx::BoxF box;
   if (LayerUtils::GetAnimationBounds(*this, &box))
@@ -1671,13 +1552,6 @@
   return num_descendants_that_draw_content_;
 }
 
-void LayerImpl::NotifyAnimationFinished(base::TimeTicks monotonic_time,
-                                        TargetProperty::Type target_property,
-                                        int group) {
-  if (target_property == TargetProperty::SCROLL_OFFSET)
-    layer_tree_impl_->InputScrollAnimationFinished();
-}
-
 void LayerImpl::SetHasRenderSurface(bool should_have_render_surface) {
   if (!!render_surface() == should_have_render_surface)
     return;
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 7cb5a41..5accffa 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -17,10 +17,7 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/values.h"
-#include "cc/animation/animation_delegate.h"
-#include "cc/animation/layer_animation_controller.h"
-#include "cc/animation/layer_animation_value_observer.h"
-#include "cc/animation/layer_animation_value_provider.h"
+#include "cc/animation/target_property.h"
 #include "cc/base/cc_export.h"
 #include "cc/base/region.h"
 #include "cc/base/synced_property.h"
@@ -79,9 +76,7 @@
   DRAW_MODE_RESOURCELESS_SOFTWARE
 };
 
-class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
-                            public LayerAnimationValueProvider,
-                            public AnimationDelegate {
+class CC_EXPORT LayerImpl {
  public:
   typedef LayerImplList RenderSurfaceListType;
   typedef LayerImplList LayerListType;
@@ -93,36 +88,18 @@
     return make_scoped_ptr(new LayerImpl(tree_impl, id));
   }
 
-  ~LayerImpl() override;
+  virtual ~LayerImpl();
 
   int id() const { return layer_id_; }
 
-  // LayerAnimationValueProvider implementation.
-  gfx::ScrollOffset ScrollOffsetForAnimation() const override;
-
-  // LayerAnimationValueObserver implementation.
-  void OnFilterAnimated(const FilterOperations& filters) override;
-  void OnOpacityAnimated(float opacity) override;
-  void OnTransformAnimated(const gfx::Transform& transform) override;
-  void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) override;
-  void OnAnimationWaitingForDeletion() override;
-  void OnTransformIsPotentiallyAnimatingChanged(bool is_animating) override;
-  bool IsActive() const override;
-
-  // AnimationDelegate implementation.
-  void NotifyAnimationStarted(base::TimeTicks monotonic_time,
-                              TargetProperty::Type target_property,
-                              int group) override{};
-  void NotifyAnimationFinished(base::TimeTicks monotonic_time,
-                               TargetProperty::Type target_property,
-                               int group) override;
-  void NotifyAnimationAborted(base::TimeTicks monotonic_time,
-                              TargetProperty::Type target_property,
-                              int group) override{};
-  void NotifyAnimationTakeover(base::TimeTicks monotonic_time,
-                               TargetProperty::Type target_property,
-                               double animation_start_time,
-                               scoped_ptr<AnimationCurve> curve) override {}
+  // Interactions with attached animations.
+  gfx::ScrollOffset ScrollOffsetForAnimation() const;
+  void OnFilterAnimated(const FilterOperations& filters);
+  void OnOpacityAnimated(float opacity);
+  void OnTransformAnimated(const gfx::Transform& transform);
+  void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset);
+  void OnTransformIsPotentiallyAnimatingChanged(bool is_animating);
+  bool IsActive() const;
 
   // Tree structure.
   LayerImpl* parent() { return parent_; }
@@ -549,14 +526,6 @@
 
   void ResetAllChangeTrackingForSubtree();
 
-  LayerAnimationController* layer_animation_controller() {
-    return layer_animation_controller_.get();
-  }
-
-  const LayerAnimationController* layer_animation_controller() const {
-    return layer_animation_controller_.get();
-  }
-
   virtual SimpleEnclosedRegion VisibleOpaqueRegion() const;
 
   virtual void DidBecomeActive() {}
@@ -806,9 +775,6 @@
   // space.
   gfx::Rect damage_rect_;
 
-  // Manages animations for this layer.
-  scoped_refptr<LayerAnimationController> layer_animation_controller_;
-
   std::vector<scoped_ptr<CopyOutputRequest>> copy_requests_;
 
   // Group of properties that need to be computed based on the layer tree
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index a09295e..b9fe4a8 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -2049,49 +2049,6 @@
   layer_tree_host->SetRootLayer(root);
 }
 
-static bool AddTestAnimation(Layer* layer) {
-  scoped_ptr<KeyframedFloatAnimationCurve> curve =
-      KeyframedFloatAnimationCurve::Create();
-  curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.3f, nullptr));
-  curve->AddKeyframe(
-      FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 0.7f, nullptr));
-  scoped_ptr<Animation> animation =
-      Animation::Create(std::move(curve), 0, 0, TargetProperty::OPACITY);
-
-  return layer->AddAnimation(std::move(animation));
-}
-
-TEST_F(LayerLayerTreeHostTest, ShouldNotAddAnimationWithoutAnimationRegistrar) {
-  // This tests isn't needed in new use_compositor_animation_timelines mode.
-  if (layer_settings_.use_compositor_animation_timelines)
-    return;
-
-  scoped_refptr<Layer> layer = Layer::Create(layer_settings_);
-
-  // Case 1: without a LayerTreeHost and without an AnimationRegistrar, the
-  // animation should not be accepted.
-  EXPECT_FALSE(AddTestAnimation(layer.get()));
-
-  scoped_ptr<AnimationRegistrar> registrar = AnimationRegistrar::Create();
-  layer->RegisterForAnimations(registrar.get());
-
-  // Case 2: with an AnimationRegistrar, the animation should be accepted.
-  EXPECT_TRUE(AddTestAnimation(layer.get()));
-
-  LayerTreeSettings settings;
-  settings.accelerated_animation_enabled = false;
-  settings.use_compositor_animation_timelines =
-      layer_settings_.use_compositor_animation_timelines;
-  LayerTreeHostFactory factory;
-  scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create(settings);
-  layer_tree_host->SetRootLayer(layer);
-  AssertLayerTreeHostMatchesForSubtree(layer.get(), layer_tree_host.get());
-
-  // Case 3: with a LayerTreeHost where accelerated animation is disabled, the
-  // animation should be rejected.
-  EXPECT_FALSE(AddTestAnimation(layer.get()));
-}
-
 TEST_F(LayerTest, SafeOpaqueBackgroundColor) {
   LayerTreeHostFactory factory;
   scoped_ptr<LayerTreeHost> layer_tree_host = factory.Create();
diff --git a/cc/layers/layer_utils_unittest.cc b/cc/layers/layer_utils_unittest.cc
index 396d02a..6d16c5c 100644
--- a/cc/layers/layer_utils_unittest.cc
+++ b/cc/layers/layer_utils_unittest.cc
@@ -46,11 +46,9 @@
         child2_(parent2_->children()[0].get()),
         grand_child_(child2_->children()[0].get()),
         great_grand_child_(grand_child_->children()[0].get()) {
-    if (host_impl_.settings().use_compositor_animation_timelines) {
-      timeline_ =
-          AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
-      host_impl_.animation_host()->AddAnimationTimeline(timeline_);
-    }
+    timeline_ =
+        AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
+    host_impl_.animation_host()->AddAnimationTimeline(timeline_);
   }
 
   LayerImpl* root() { return root_; }
@@ -103,12 +101,8 @@
   start.AppendScale(1.f, 1.f, 1.f);
   TransformOperations end;
   end.AppendScale(2.f, 2.f, 1.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(root()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(root(), duration, start, end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(root()->id(), timeline(), duration,
+                                        start, end);
 
   root()->SetPosition(gfx::PointF());
   parent1()->SetPosition(gfx::PointF());
@@ -134,12 +128,8 @@
   start.AppendTranslate(0.f, 0.f, 0.f);
   TransformOperations end;
   end.AppendTranslate(50.f, 50.f, 0.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(parent1()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(parent1(), duration, start, end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(parent1()->id(), timeline(), duration,
+                                        start, end);
 
   parent1()->SetBounds(gfx::Size(350, 200));
 
@@ -163,13 +153,8 @@
   start.AppendTranslate(0.f, 0.f, 0.f);
   TransformOperations end;
   end.AppendTranslate(50.f, 50.f, 0.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(child1(), duration, start, end);
-  }
-
+  AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
+                                        start, end);
   parent1()->SetBounds(gfx::Size(350, 200));
 
   child1()->SetDrawsContent(true);
@@ -192,21 +177,13 @@
   start.AppendTranslate(0.f, 0.f, 0.f);
   TransformOperations child_end;
   child_end.AppendTranslate(50.f, 0.f, 0.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(parent1()->id(), timeline(), duration,
-                                          start, child_end);
-  } else {
-    AddAnimatedTransformToLayer(parent1(), duration, start, child_end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(parent1()->id(), timeline(), duration,
+                                        start, child_end);
 
   TransformOperations grand_child_end;
   grand_child_end.AppendTranslate(0.f, 50.f, 0.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
-                                          start, grand_child_end);
-  } else {
-    AddAnimatedTransformToLayer(child1(), duration, start, grand_child_end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
+                                        start, grand_child_end);
 
   parent1()->SetBounds(gfx::Size(350, 200));
 
@@ -230,12 +207,9 @@
   start.AppendRotate(1.f, 0.f, 0.f, 0.f);
   TransformOperations end;
   end.AppendRotate(1.f, 0.f, 0.f, 90.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(child1(), duration, start, end);
-  }
+
+  AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
+                                        start, end);
 
   parent1()->SetBounds(gfx::Size(350, 200));
 
@@ -263,12 +237,8 @@
   TransformOperations end;
   end.AppendRotate(1.f, 0.f, 0.f, 90.f);
 
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(child1(), duration, start, end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
+                                        start, end);
 
   // Make the anchor point not the default 0.5 value and line up with the
   // child center to make the math easier.
@@ -308,12 +278,8 @@
   TransformOperations end;
   end.AppendRotate(1.f, 0.f, 0.f, 90.f);
 
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(parent1()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(parent1(), duration, start, end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(parent1()->id(), timeline(), duration,
+                                        start, end);
 
   // Make the anchor point not the default 0.5 value and line up
   // with the child center to make the math easier.
@@ -348,12 +314,8 @@
   start.AppendRotate(0.f, 0.f, 1.f, 0.f);
   TransformOperations end;
   end.AppendRotate(0.f, 0.f, 1.f, 90.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(child1(), duration, start, end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
+                                        start, end);
 
   parent1()->SetBounds(gfx::Size(350, 200));
 
@@ -386,12 +348,8 @@
   start.AppendTranslate(5, 6, 7);
   TransformOperations end;
   end.AppendRotate(0.f, 0.f, 1.f, 90.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
-                                          start, end);
-  } else {
-    AddAnimatedTransformToLayer(child1(), duration, start, end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child1()->id(), timeline(), duration,
+                                        start, end);
 
   parent1()->SetBounds(gfx::Size(350, 200));
 
@@ -425,14 +383,8 @@
   start.AppendTranslate(0.f, 0.f, 0.f);
   TransformOperations great_grand_child_end;
   great_grand_child_end.AppendTranslate(50.f, 0.f, 0.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(grand_child()->id(), timeline(),
-                                          duration, start,
-                                          great_grand_child_end);
-  } else {
-    AddAnimatedTransformToLayer(grand_child(), duration, start,
-                                great_grand_child_end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(grand_child()->id(), timeline(),
+                                        duration, start, great_grand_child_end);
 
   gfx::Transform translate_2d_transform;
   translate_2d_transform.Translate(80.f, 60.f);
@@ -459,14 +411,8 @@
   start.AppendRotate(0.f, 0.f, 1.f, 0.f);
   TransformOperations great_grand_child_end;
   great_grand_child_end.AppendRotate(0.f, 0.f, 1.f, 90.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(grand_child()->id(), timeline(),
-                                          duration, start,
-                                          great_grand_child_end);
-  } else {
-    AddAnimatedTransformToLayer(grand_child(), duration, start,
-                                great_grand_child_end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(grand_child()->id(), timeline(),
+                                        duration, start, great_grand_child_end);
 
   gfx::Transform translate_2d_transform;
   translate_2d_transform.Translate(80.f, 60.f);
@@ -512,14 +458,8 @@
   start.AppendRotate(1.f, 0.f, 0.f, 0.f);
   TransformOperations great_grand_child_end;
   great_grand_child_end.AppendRotate(1.f, 0.f, 0.f, 90.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(great_grand_child()->id(), timeline(),
-                                          duration, start,
-                                          great_grand_child_end);
-  } else {
-    AddAnimatedTransformToLayer(great_grand_child(), duration, start,
-                                great_grand_child_end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(great_grand_child()->id(), timeline(),
+                                        duration, start, great_grand_child_end);
 
   gfx::Transform translate_2d_transform;
   translate_2d_transform.Translate(80.f, 60.f);
@@ -599,13 +539,8 @@
   start.AppendRotate(1.f, 0.f, 0.f, 0.f);
   TransformOperations rotate_x_end;
   rotate_x_end.AppendRotate(1.f, 0.f, 0.f, 90.f);
-  if (host_impl().settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(great_grand_child()->id(), timeline(),
-                                          duration, start, rotate_x_end);
-  } else {
-    AddAnimatedTransformToLayer(great_grand_child(), duration, start,
-                                rotate_x_end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(great_grand_child()->id(), timeline(),
+                                        duration, start, rotate_x_end);
 
   gfx::Transform translate_2d_transform;
   translate_2d_transform.Translate(80.f, 60.f);
diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc
index cc02e633..8bed0ee 100644
--- a/cc/test/animation_test_common.cc
+++ b/cc/test/animation_test_common.cc
@@ -292,81 +292,6 @@
       controller, duration, start_brightness, end_brightness);
 }
 
-int AddOpacityTransitionToLayer(Layer* layer,
-                                double duration,
-                                float start_opacity,
-                                float end_opacity,
-                                bool use_timing_function) {
-  return AddOpacityTransition(layer,
-                              duration,
-                              start_opacity,
-                              end_opacity,
-                              use_timing_function);
-}
-
-int AddOpacityTransitionToLayer(LayerImpl* layer,
-                                double duration,
-                                float start_opacity,
-                                float end_opacity,
-                                bool use_timing_function) {
-  return AddOpacityTransition(layer->layer_animation_controller(),
-                              duration,
-                              start_opacity,
-                              end_opacity,
-                              use_timing_function);
-}
-
-int AddAnimatedTransformToLayer(Layer* layer,
-                                double duration,
-                                int delta_x,
-                                int delta_y) {
-  return AddAnimatedTransform(layer, duration, delta_x, delta_y);
-}
-
-int AddAnimatedTransformToLayer(LayerImpl* layer,
-                                double duration,
-                                int delta_x,
-                                int delta_y) {
-  return AddAnimatedTransform(layer->layer_animation_controller(),
-                              duration,
-                              delta_x,
-                              delta_y);
-}
-
-int AddAnimatedTransformToLayer(Layer* layer,
-                                double duration,
-                                TransformOperations start_operations,
-                                TransformOperations operations) {
-  return AddAnimatedTransform(layer, duration, start_operations, operations);
-}
-
-int AddAnimatedTransformToLayer(LayerImpl* layer,
-                                double duration,
-                                TransformOperations start_operations,
-                                TransformOperations operations) {
-  return AddAnimatedTransform(layer->layer_animation_controller(),
-                              duration,
-                              start_operations,
-                              operations);
-}
-
-int AddAnimatedFilterToLayer(Layer* layer,
-                             double duration,
-                             float start_brightness,
-                             float end_brightness) {
-  return AddAnimatedFilter(layer, duration, start_brightness, end_brightness);
-}
-
-int AddAnimatedFilterToLayer(LayerImpl* layer,
-                             double duration,
-                             float start_brightness,
-                             float end_brightness) {
-  return AddAnimatedFilter(layer->layer_animation_controller(),
-                           duration,
-                           start_brightness,
-                           end_brightness);
-}
-
 int AddAnimatedTransformToPlayer(AnimationPlayer* player,
                                  double duration,
                                  int delta_x,
diff --git a/cc/test/animation_test_common.h b/cc/test/animation_test_common.h
index 7a6fe0d8..2d47e6d1 100644
--- a/cc/test/animation_test_common.h
+++ b/cc/test/animation_test_common.h
@@ -144,48 +144,6 @@
                                   float start_brightness,
                                   float end_brightness);
 
-int AddOpacityTransitionToLayer(Layer* layer,
-                                double duration,
-                                float start_opacity,
-                                float end_opacity,
-                                bool use_timing_function);
-
-int AddOpacityTransitionToLayer(LayerImpl* layer,
-                                double duration,
-                                float start_opacity,
-                                float end_opacity,
-                                bool use_timing_function);
-
-int AddAnimatedTransformToLayer(Layer* layer,
-                                double duration,
-                                int delta_x,
-                                int delta_y);
-
-int AddAnimatedTransformToLayer(LayerImpl* layer,
-                                double duration,
-                                int delta_x,
-                                int delta_y);
-
-int AddAnimatedTransformToLayer(Layer* layer,
-                                double duration,
-                                TransformOperations start_operations,
-                                TransformOperations operations);
-
-int AddAnimatedTransformToLayer(LayerImpl* layer,
-                                double duration,
-                                TransformOperations start_operations,
-                                TransformOperations operations);
-
-int AddAnimatedFilterToLayer(Layer* layer,
-                             double duration,
-                             float start_brightness,
-                             float end_brightness);
-
-int AddAnimatedFilterToLayer(LayerImpl* layer,
-                             double duration,
-                             float start_brightness,
-                             float end_brightness);
-
 int AddAnimatedTransformToPlayer(AnimationPlayer* player,
                                  double duration,
                                  int delta_x,
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 0887cc53..9503c42 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -320,9 +320,7 @@
   void UpdateAnimationState(bool start_ready_animations) override {
     LayerTreeHostImpl::UpdateAnimationState(start_ready_animations);
     bool has_unfinished_animation = false;
-    AnimationRegistrar* registrar =
-        animation_registrar() ? animation_registrar()
-                              : animation_host()->animation_registrar();
+    AnimationRegistrar* registrar = animation_host()->animation_registrar();
     for (const auto& it :
          registrar->active_animation_controllers_for_testing()) {
       if (it.second->HasActiveAnimation()) {
@@ -576,34 +574,6 @@
       base::TimeDelta::FromMilliseconds(delay_milliseconds));
 }
 
-void LayerTreeTest::PostAddAnimationToMainThread(
-    Layer* layer_to_receive_animation) {
-  main_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&LayerTreeTest::DispatchAddAnimation, main_thread_weak_ptr_,
-                 base::Unretained(layer_to_receive_animation), 0.000004));
-}
-
-void LayerTreeTest::PostAddInstantAnimationToMainThread(
-    Layer* layer_to_receive_animation) {
-  main_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&LayerTreeTest::DispatchAddAnimation,
-                 main_thread_weak_ptr_,
-                 base::Unretained(layer_to_receive_animation),
-                 0.0));
-}
-
-void LayerTreeTest::PostAddLongAnimationToMainThread(
-    Layer* layer_to_receive_animation) {
-  main_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&LayerTreeTest::DispatchAddAnimation,
-                 main_thread_weak_ptr_,
-                 base::Unretained(layer_to_receive_animation),
-                 1.0));
-}
-
 void LayerTreeTest::PostAddAnimationToMainThreadPlayer(
     AnimationPlayer* player_to_receive_animation) {
   main_task_runner_->PostTask(
@@ -816,16 +786,6 @@
   base::MessageLoop::current()->QuitWhenIdle();
 }
 
-void LayerTreeTest::DispatchAddAnimation(Layer* layer_to_receive_animation,
-                                         double animation_duration) {
-  DCHECK(!task_runner_provider() || task_runner_provider()->IsMainThread());
-
-  if (layer_to_receive_animation) {
-    AddOpacityTransitionToLayer(
-        layer_to_receive_animation, animation_duration, 0, 0.5, true);
-  }
-}
-
 void LayerTreeTest::DispatchAddAnimationToPlayer(
     AnimationPlayer* player_to_receive_animation,
     double animation_duration) {
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 2b9a91a..36a882c 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -77,9 +77,6 @@
   virtual void EndTest();
   void EndTestAfterDelayMs(int delay_milliseconds);
 
-  void PostAddAnimationToMainThread(Layer* layer_to_receive_animation);
-  void PostAddInstantAnimationToMainThread(Layer* layer_to_receive_animation);
-  void PostAddLongAnimationToMainThread(Layer* layer_to_receive_animation);
   void PostAddAnimationToMainThreadPlayer(
       AnimationPlayer* player_to_receive_animation);
   void PostAddInstantAnimationToMainThreadPlayer(
@@ -109,8 +106,6 @@
 
   void RealEndTest();
 
-  virtual void DispatchAddAnimation(Layer* layer_to_receive_animation,
-                                    double animation_duration);
   virtual void DispatchAddAnimationToPlayer(
       AnimationPlayer* player_to_receive_animation,
       double animation_duration);
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 6e9d689..5f21e91e 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -26,8 +26,6 @@
 #include "base/trace_event/trace_event_argument.h"
 #include "cc/animation/animation_events.h"
 #include "cc/animation/animation_host.h"
-#include "cc/animation/animation_registrar.h"
-#include "cc/animation/layer_animation_controller.h"
 #include "cc/base/math_util.h"
 #include "cc/debug/devtools_instrumentation.h"
 #include "cc/debug/frame_viewer_instrumentation.h"
@@ -201,12 +199,8 @@
   DCHECK(task_graph_runner_);
 
   if (settings_.accelerated_animation_enabled) {
-    if (settings_.use_compositor_animation_timelines) {
-      animation_host_ = AnimationHost::Create(ThreadInstance::MAIN);
-      animation_host_->SetMutatorHostClient(this);
-    } else {
-      animation_registrar_ = AnimationRegistrar::Create();
-    }
+    animation_host_ = AnimationHost::Create(ThreadInstance::MAIN);
+    animation_host_->SetMutatorHostClient(this);
   }
 
   rendering_stats_instrumentation_->set_record_rendering_stats(
@@ -293,12 +287,8 @@
   proxy_ = std::move(proxy);
   proxy_->Start(std::move(external_begin_frame_source));
   if (settings_.accelerated_animation_enabled) {
-    if (animation_host_)
-      animation_host_->SetSupportsScrollAnimations(
-          proxy_->SupportsImplScrolling());
-    else
-      animation_registrar_->set_supports_scroll_animations(
-          proxy_->SupportsImplScrolling());
+    animation_host_->SetSupportsScrollAnimations(
+        proxy_->SupportsImplScrolling());
   }
 }
 
@@ -698,10 +688,7 @@
 
 void LayerTreeHost::SetAnimationEvents(scoped_ptr<AnimationEvents> events) {
   DCHECK(task_runner_provider_->IsMainThread());
-  if (animation_host_)
-    animation_host_->SetAnimationEvents(std::move(events));
-  else
-    animation_registrar_->SetAnimationEvents(std::move(events));
+  animation_host_->SetAnimationEvents(std::move(events));
 }
 
 void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
@@ -1069,15 +1056,9 @@
     return;
 
   scoped_ptr<AnimationEvents> events;
-  if (animation_host_) {
-    events = animation_host_->CreateEvents();
-    if (animation_host_->AnimateLayers(monotonic_time))
-      animation_host_->UpdateAnimationState(true, events.get());
-  } else {
-    events = animation_registrar_->CreateEvents();
-    if (animation_registrar_->AnimateLayers(monotonic_time))
-      animation_registrar_->UpdateAnimationState(true, events.get());
-  }
+  events = animation_host_->CreateEvents();
+  if (animation_host_->AnimateLayers(monotonic_time))
+    animation_host_->UpdateAnimationState(true, events.get());
 
   if (!events->events_.empty())
     property_trees_.needs_rebuild = true;
@@ -1286,7 +1267,7 @@
 void LayerTreeHost::SetLayerFilterMutated(int layer_id,
                                           LayerTreeType tree_type,
                                           const FilterOperations& filters) {
-  LayerAnimationValueObserver* layer = LayerById(layer_id);
+  Layer* layer = LayerById(layer_id);
   DCHECK(layer);
   layer->OnFilterAnimated(filters);
 }
@@ -1294,7 +1275,7 @@
 void LayerTreeHost::SetLayerOpacityMutated(int layer_id,
                                            LayerTreeType tree_type,
                                            float opacity) {
-  LayerAnimationValueObserver* layer = LayerById(layer_id);
+  Layer* layer = LayerById(layer_id);
   DCHECK(layer);
   layer->OnOpacityAnimated(opacity);
 }
@@ -1302,7 +1283,7 @@
 void LayerTreeHost::SetLayerTransformMutated(int layer_id,
                                              LayerTreeType tree_type,
                                              const gfx::Transform& transform) {
-  LayerAnimationValueObserver* layer = LayerById(layer_id);
+  Layer* layer = LayerById(layer_id);
   DCHECK(layer);
   layer->OnTransformAnimated(transform);
 }
@@ -1311,7 +1292,7 @@
     int layer_id,
     LayerTreeType tree_type,
     const gfx::ScrollOffset& scroll_offset) {
-  LayerAnimationValueObserver* layer = LayerById(layer_id);
+  Layer* layer = LayerById(layer_id);
   DCHECK(layer);
   layer->OnScrollOffsetAnimated(scroll_offset);
 }
@@ -1320,14 +1301,14 @@
     int layer_id,
     LayerTreeType tree_type,
     bool is_animating) {
-  LayerAnimationValueObserver* layer = LayerById(layer_id);
+  Layer* layer = LayerById(layer_id);
   DCHECK(layer);
   layer->OnTransformIsPotentiallyAnimatingChanged(is_animating);
 }
 
 gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
     int layer_id) const {
-  LayerAnimationValueProvider* layer = LayerById(layer_id);
+  Layer* layer = LayerById(layer_id);
   DCHECK(layer);
   return layer->ScrollOffsetForAnimation();
 }
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 056326b..b13be32 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -20,7 +20,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
-#include "cc/animation/animation.h"
+#include "cc/animation/target_property.h"
 #include "cc/base/cc_export.h"
 #include "cc/debug/frame_timing_tracker.h"
 #include "cc/debug/micro_benchmark.h"
@@ -295,9 +295,6 @@
   TaskRunnerProvider* task_runner_provider() const {
     return task_runner_provider_.get();
   }
-  AnimationRegistrar* animation_registrar() const {
-    return animation_registrar_.get();
-  }
   AnimationHost* animation_host() const { return animation_host_.get(); }
 
   bool in_paint_layer_contents() const { return in_paint_layer_contents_; }
@@ -550,7 +547,6 @@
   EventListenerProperties event_listener_properties_[static_cast<size_t>(
       EventListenerClass::kNumClasses)];
 
-  scoped_ptr<AnimationRegistrar> animation_registrar_;
   scoped_ptr<AnimationHost> animation_host_;
 
   scoped_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index c0786df..4377c2f 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -2514,46 +2514,24 @@
       grand_child_of_rs2, layer_transform, gfx::Point3F(0.25f, 0.f, 0.f),
       gfx::PointF(2.5f, 0.f), gfx::Size(10, 10), true, false, false);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    // Put an animated opacity on the render surface.
-    AddOpacityTransitionToLayerWithPlayer(
-        render_surface1->id(), timeline_impl(), 10.0, 1.f, 0.f, false);
+  // Put an animated opacity on the render surface.
+  AddOpacityTransitionToLayerWithPlayer(render_surface1->id(), timeline_impl(),
+                                        10.0, 1.f, 0.f, false);
 
-    // Also put an animated opacity on a layer without descendants.
-    AddOpacityTransitionToLayerWithPlayer(
-        grand_child_of_root->id(), timeline_impl(), 10.0, 1.f, 0.f, false);
+  // Also put an animated opacity on a layer without descendants.
+  AddOpacityTransitionToLayerWithPlayer(grand_child_of_root->id(),
+                                        timeline_impl(), 10.0, 1.f, 0.f, false);
 
-    // Put a transform animation on the render surface.
-    AddAnimatedTransformToLayerWithPlayer(render_surface2->id(),
-                                          timeline_impl(), 10.0, 30, 0);
+  // Put a transform animation on the render surface.
+  AddAnimatedTransformToLayerWithPlayer(render_surface2->id(), timeline_impl(),
+                                        10.0, 30, 0);
 
-    // Also put transform animations on grand_child_of_root, and
-    // grand_child_of_rs2
-    AddAnimatedTransformToLayerWithPlayer(grand_child_of_root->id(),
-                                          timeline_impl(), 10.0, 30, 0);
-    AddAnimatedTransformToLayerWithPlayer(grand_child_of_rs2->id(),
-                                          timeline_impl(), 10.0, 30, 0);
-  } else {
-    // Put an animated opacity on the render surface.
-    AddOpacityTransitionToController(
-        render_surface1->layer_animation_controller(), 10.0, 1.f, 0.f, false);
-
-    // Also put an animated opacity on a layer without descendants.
-    AddOpacityTransitionToController(
-        grand_child_of_root->layer_animation_controller(), 10.0, 1.f, 0.f,
-        false);
-
-    // Put a transform animation on the render surface.
-    AddAnimatedTransformToController(
-        render_surface2->layer_animation_controller(), 10.0, 30, 0);
-
-    // Also put transform animations on grand_child_of_root, and
-    // grand_child_of_rs2
-    AddAnimatedTransformToController(
-        grand_child_of_root->layer_animation_controller(), 10.0, 30, 0);
-    AddAnimatedTransformToController(
-        grand_child_of_rs2->layer_animation_controller(), 10.0, 30, 0);
-  }
+  // Also put transform animations on grand_child_of_root, and
+  // grand_child_of_rs2
+  AddAnimatedTransformToLayerWithPlayer(grand_child_of_root->id(),
+                                        timeline_impl(), 10.0, 30, 0);
+  AddAnimatedTransformToLayerWithPlayer(grand_child_of_rs2->id(),
+                                        timeline_impl(), 10.0, 30, 0);
 
   ExecuteCalculateDrawProperties(parent);
 
@@ -2673,13 +2651,8 @@
       TargetProperty::TRANSFORM);
   animation->set_fill_mode(Animation::FILL_MODE_NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimationToLayerWithPlayer(grand_child->id(), timeline_impl(),
-                                  std::move(animation));
-  } else {
-    grand_child->layer_animation_controller()->AddAnimation(
-        std::move(animation));
-  }
+  AddAnimationToLayerWithPlayer(grand_child->id(), timeline_impl(),
+                                std::move(animation));
   ExecuteCalculateDrawProperties(parent);
 
   EXPECT_FALSE(parent->screen_space_transform_is_animating());
@@ -3621,14 +3594,9 @@
   TransformOperations end_transform_operations;
   end_transform_operations.AppendScale(1.f, 1.f, 0.f);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(root->id(), timeline(), 10.0,
-                                          start_transform_operations,
-                                          end_transform_operations);
-  } else {
-    AddAnimatedTransformToLayer(root.get(), 10.0, start_transform_operations,
-                                end_transform_operations);
-  }
+  AddAnimatedTransformToLayerWithPlayer(root->id(), timeline(), 10.0,
+                                        start_transform_operations,
+                                        end_transform_operations);
   EXPECT_TRUE(root->TransformIsAnimating());
 
   ExecuteCalculateDrawProperties(root.get());
@@ -4536,21 +4504,12 @@
   // Make our render surface.
   animating_surface->SetForceRenderSurface(true);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    // Animate the transform on the render surface.
-    AddAnimatedTransformToLayerWithPlayer(animating_surface->id(), timeline(),
-                                          10.0, 30, 0);
-    // This is just an animating layer, not a surface.
-    AddAnimatedTransformToLayerWithPlayer(animating_child->id(), timeline(),
-                                          10.0, 30, 0);
-  } else {
-    // Animate the transform on the render surface.
-    AddAnimatedTransformToController(
-        animating_surface->layer_animation_controller(), 10.0, 30, 0);
-    // This is just an animating layer, not a surface.
-    AddAnimatedTransformToController(
-        animating_child->layer_animation_controller(), 10.0, 30, 0);
-  }
+  // Animate the transform on the render surface.
+  AddAnimatedTransformToLayerWithPlayer(animating_surface->id(), timeline(),
+                                        10.0, 30, 0);
+  // This is just an animating layer, not a surface.
+  AddAnimatedTransformToLayerWithPlayer(animating_child->id(), timeline(), 10.0,
+                                        30, 0);
 
   SetLayerPropertiesForTesting(parent.get(),
                                identity_matrix,
@@ -5236,17 +5195,12 @@
   child->SetOpacity(0.0f);
 
   // Add opacity animation.
-  if (layer_settings().use_compositor_animation_timelines) {
-    scoped_refptr<AnimationTimeline> timeline =
-        AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
-    host_impl.animation_host()->AddAnimationTimeline(timeline);
+  scoped_refptr<AnimationTimeline> timeline =
+      AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
+  host_impl.animation_host()->AddAnimationTimeline(timeline);
 
-    AddOpacityTransitionToLayerWithPlayer(child->id(), timeline, 10.0, 0.0f,
-                                          1.0f, false);
-  } else {
-    AddOpacityTransitionToController(child->layer_animation_controller(), 10.0,
-                                     0.0f, 1.0f, false);
-  }
+  AddOpacityTransitionToLayerWithPlayer(child->id(), timeline, 10.0, 0.0f, 1.0f,
+                                        false);
 
   root->AddChild(std::move(child));
   root->SetHasRenderSurface(true);
@@ -5326,11 +5280,9 @@
 
  protected:
   void SetUp() override {
-    if (layer_settings().use_compositor_animation_timelines) {
-      timeline_ =
-          AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
-      host_impl_.animation_host()->AddAnimationTimeline(timeline_);
-    }
+    timeline_ =
+        AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
+    host_impl_.animation_host()->AddAnimationTimeline(timeline_);
 
     can_use_lcd_text_ = std::tr1::get<0>(GetParam());
     layers_always_allowed_lcd_text_ = std::tr1::get<1>(GetParam());
@@ -5503,13 +5455,8 @@
   // Add opacity animation.
   child_->SetOpacity(0.9f);
   child_->layer_tree_impl()->property_trees()->needs_rebuild = true;
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddOpacityTransitionToLayerWithPlayer(child_->id(), timeline(), 10.0, 0.9f,
-                                          0.1f, false);
-  } else {
-    AddOpacityTransitionToController(child_->layer_animation_controller(), 10.0,
-                                     0.9f, 0.1f, false);
-  }
+  AddOpacityTransitionToLayerWithPlayer(child_->id(), timeline(), 10.0, 0.9f,
+                                        0.1f, false);
   ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
                                  layers_always_allowed_lcd_text_);
   // Text LCD should be adjusted while animation is active.
@@ -5531,13 +5478,8 @@
 
   // Mark contents non-opaque within the first animation frame.
   child_->SetContentsOpaque(false);
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddOpacityTransitionToLayerWithPlayer(child_->id(), timeline(), 10.0, 0.9f,
-                                          0.1f, false);
-  } else {
-    AddOpacityTransitionToController(child_->layer_animation_controller(), 10.0,
-                                     0.9f, 0.1f, false);
-  }
+  AddOpacityTransitionToLayerWithPlayer(child_->id(), timeline(), 10.0, 0.9f,
+                                        0.1f, false);
   ExecuteCalculateDrawProperties(root_, 1.f, 1.f, NULL, can_use_lcd_text_,
                                  layers_always_allowed_lcd_text_);
   // LCD text should be disabled for non-opaque layers even during animations.
@@ -7393,14 +7335,8 @@
   start_operations.AppendMatrix(start_scale);
   TransformOperations end_operations;
   end_operations.AppendMatrix(end_scale);
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(animated_layer->id(), timeline_impl(),
-                                          1.0, start_operations,
-                                          end_operations);
-  } else {
-    AddAnimatedTransformToLayer(animated_layer, 1.0, start_operations,
-                                end_operations);
-  }
+  AddAnimatedTransformToLayerWithPlayer(animated_layer->id(), timeline_impl(),
+                                        1.0, start_operations, end_operations);
   gfx::Vector2dF scroll_delta(5.f, 9.f);
   SetScrollOffsetDelta(scroller, scroll_delta);
 
@@ -7495,16 +7431,11 @@
   translation.AppendTranslate(1.f, 2.f, 3.f);
 
   scoped_refptr<AnimationTimeline> timeline;
-  if (layer_settings().use_compositor_animation_timelines) {
-    timeline = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
-    host_impl.animation_host()->AddAnimationTimeline(timeline);
+  timeline = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
+  host_impl.animation_host()->AddAnimationTimeline(timeline);
 
-    AddAnimatedTransformToLayerWithPlayer(parent_raw->id(), timeline, 1.0,
-                                          TransformOperations(), translation);
-  } else {
-    AddAnimatedTransformToLayer(parent_raw, 1.0, TransformOperations(),
-                                translation);
-  }
+  AddAnimatedTransformToLayerWithPlayer(parent_raw->id(), timeline, 1.0,
+                                        TransformOperations(), translation);
 
   // No layers have scale-affecting animations.
   EXPECT_EQ(0.f,
@@ -7528,12 +7459,8 @@
   TransformOperations scale;
   scale.AppendScale(5.f, 4.f, 3.f);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child_raw->id(), timeline, 1.0,
-                                          TransformOperations(), scale);
-  } else {
-    AddAnimatedTransformToLayer(child_raw, 1.0, TransformOperations(), scale);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child_raw->id(), timeline, 1.0,
+                                        TransformOperations(), scale);
   child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true;
   ExecuteCalculateDrawProperties(grand_parent.get());
 
@@ -7556,13 +7483,8 @@
       1.f,
       grand_child_raw->draw_properties().starting_animation_contents_scale);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(grand_parent->id(), timeline, 1.0,
-                                          TransformOperations(), scale);
-  } else {
-    AddAnimatedTransformToLayer(grand_parent.get(), 1.0, TransformOperations(),
-                                scale);
-  }
+  AddAnimatedTransformToLayerWithPlayer(grand_parent->id(), timeline, 1.0,
+                                        TransformOperations(), scale);
   grand_parent->layer_tree_impl()->property_trees()->needs_rebuild = true;
   ExecuteCalculateDrawProperties(grand_parent.get());
 
@@ -7587,12 +7509,8 @@
       0.f,
       grand_child_raw->draw_properties().starting_animation_contents_scale);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(parent_raw->id(), timeline, 1.0,
-                                          TransformOperations(), scale);
-  } else {
-    AddAnimatedTransformToLayer(parent_raw, 1.0, TransformOperations(), scale);
-  }
+  AddAnimatedTransformToLayerWithPlayer(parent_raw->id(), timeline, 1.0,
+                                        TransformOperations(), scale);
   parent_raw->layer_tree_impl()->property_trees()->needs_rebuild = true;
   ExecuteCalculateDrawProperties(grand_parent.get());
 
@@ -7615,32 +7533,18 @@
       0.f,
       grand_child_raw->draw_properties().starting_animation_contents_scale);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AbortAnimationsOnLayerWithPlayer(grand_parent->id(), timeline,
-                                     TargetProperty::TRANSFORM);
-    AbortAnimationsOnLayerWithPlayer(parent_raw->id(), timeline,
-                                     TargetProperty::TRANSFORM);
-    AbortAnimationsOnLayerWithPlayer(child_raw->id(), timeline,
-                                     TargetProperty::TRANSFORM);
-  } else {
-    grand_parent->layer_animation_controller()->AbortAnimations(
-        TargetProperty::TRANSFORM);
-    parent_raw->layer_animation_controller()->AbortAnimations(
-        TargetProperty::TRANSFORM);
-    child_raw->layer_animation_controller()->AbortAnimations(
-        TargetProperty::TRANSFORM);
-  }
+  AbortAnimationsOnLayerWithPlayer(grand_parent->id(), timeline,
+                                   TargetProperty::TRANSFORM);
+  AbortAnimationsOnLayerWithPlayer(parent_raw->id(), timeline,
+                                   TargetProperty::TRANSFORM);
+  AbortAnimationsOnLayerWithPlayer(child_raw->id(), timeline,
+                                   TargetProperty::TRANSFORM);
 
   TransformOperations perspective;
   perspective.AppendPerspective(10.f);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child_raw->id(), timeline, 1.0,
-                                          TransformOperations(), perspective);
-  } else {
-    AddAnimatedTransformToLayer(child_raw, 1.0, TransformOperations(),
-                                perspective);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child_raw->id(), timeline, 1.0,
+                                        TransformOperations(), perspective);
   child_raw->layer_tree_impl()->property_trees()->needs_rebuild = true;
   ExecuteCalculateDrawProperties(grand_parent.get());
 
@@ -7664,25 +7568,16 @@
       0.f,
       grand_child_raw->draw_properties().starting_animation_contents_scale);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AbortAnimationsOnLayerWithPlayer(child_raw->id(), timeline,
-                                     TargetProperty::TRANSFORM);
-  } else {
-    child_raw->layer_animation_controller()->AbortAnimations(
-        TargetProperty::TRANSFORM);
-  }
+  AbortAnimationsOnLayerWithPlayer(child_raw->id(), timeline,
+                                   TargetProperty::TRANSFORM);
   gfx::Transform scale_matrix;
   scale_matrix.Scale(1.f, 2.f);
   grand_parent->SetTransform(scale_matrix);
   parent_raw->SetTransform(scale_matrix);
   grand_parent->layer_tree_impl()->property_trees()->needs_rebuild = true;
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(parent_raw->id(), timeline, 1.0,
-                                          TransformOperations(), scale);
-  } else {
-    AddAnimatedTransformToLayer(parent_raw, 1.0, TransformOperations(), scale);
-  }
+  AddAnimatedTransformToLayerWithPlayer(parent_raw->id(), timeline, 1.0,
+                                        TransformOperations(), scale);
   ExecuteCalculateDrawProperties(grand_parent.get());
 
   // |grand_parent| and |parent| each have scale 2.f. |parent| has a  scale
@@ -8103,17 +7998,12 @@
   TransformOperations scale;
   scale.AppendScale(5.f, 8.f, 3.f);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    scoped_refptr<AnimationTimeline> timeline =
-        AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
-    host_impl.animation_host()->AddAnimationTimeline(timeline);
+  scoped_refptr<AnimationTimeline> timeline =
+      AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
+  host_impl.animation_host()->AddAnimationTimeline(timeline);
 
-    AddAnimatedTransformToLayerWithPlayer(child2_layer->id(), timeline, 1.0,
-                                          TransformOperations(), scale);
-  } else {
-    AddAnimatedTransformToLayer(child2_layer, 1.0, TransformOperations(),
-                                scale);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child2_layer->id(), timeline, 1.0,
+                                        TransformOperations(), scale);
 
   SetLayerPropertiesForTesting(child2_layer, scale_transform_child2,
                                gfx::Point3F(), gfx::PointF(), gfx::Size(1, 1),
@@ -8420,13 +8310,8 @@
   root->SetForceRenderSurface(true);
   animated->SetOpacity(0.f);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddOpacityTransitionToLayerWithPlayer(animated->id(), timeline(), 10.0, 0.f,
-                                          1.f, false);
-  } else {
-    AddOpacityTransitionToController(animated->layer_animation_controller(),
-                                     10.0, 0.f, 1.f, false);
-  }
+  AddOpacityTransitionToLayerWithPlayer(animated->id(), timeline(), 10.0, 0.f,
+                                        1.f, false);
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
 
   EXPECT_FALSE(animated->visible_layer_rect().IsEmpty());
@@ -8474,15 +8359,9 @@
   start_transform_operations.AppendMatrix(uninvertible_matrix);
   TransformOperations end_transform_operations;
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(animated->id(), timeline(), 10.0,
-                                          start_transform_operations,
-                                          end_transform_operations);
-  } else {
-    AddAnimatedTransformToLayer(animated.get(), 10.0,
-                                start_transform_operations,
-                                end_transform_operations);
-  }
+  AddAnimatedTransformToLayerWithPlayer(animated->id(), timeline(), 10.0,
+                                        start_transform_operations,
+                                        end_transform_operations);
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
 
   // The animated layer has a singular transform and maps to a non-empty rect in
@@ -8531,12 +8410,7 @@
                                true, false);
   host()->SetRootLayer(root);
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimatedFilterToLayerWithPlayer(child->id(), timeline(), 10.0, 0.1f,
-                                       0.2f);
-  } else {
-    AddAnimatedFilterToLayer(child.get(), 10.0, 0.1f, 0.2f);
-  }
+  AddAnimatedFilterToLayerWithPlayer(child->id(), timeline(), 10.0, 0.1f, 0.2f);
   ExecuteCalculateDrawProperties(root.get());
 
   EXPECT_TRUE(root->has_render_surface());
@@ -8586,12 +8460,7 @@
   animation->set_fill_mode(Animation::FILL_MODE_NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimationToLayerWithPlayer(child->id(), timeline(),
-                                  std::move(animation));
-  } else {
-    child->layer_animation_controller()->AddAnimation(std::move(animation));
-  }
+  AddAnimationToLayerWithPlayer(child->id(), timeline(), std::move(animation));
   ExecuteCalculateDrawProperties(root.get());
 
   EXPECT_TRUE(root->has_render_surface());
@@ -9062,22 +8931,13 @@
       animation_id, 1, TargetProperty::TRANSFORM);
   animation->set_fill_mode(Animation::FILL_MODE_NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimationToLayerWithPlayer(child->id(), timeline(),
-                                  std::move(animation));
-  } else {
-    child->AddAnimation(std::move(animation));
-  }
+  AddAnimationToLayerWithPlayer(child->id(), timeline(), std::move(animation));
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
   EXPECT_EQ(gfx::Rect(10, 10), grandchild->visible_layer_rect());
   grandchild->set_visible_layer_rect(gfx::Rect());
 
-  if (layer_settings().use_compositor_animation_timelines) {
-    RemoveAnimationFromLayerWithExistingPlayer(child->id(), timeline(),
-                                               animation_id);
-  } else {
-    child->RemoveAnimation(animation_id);
-  }
+  RemoveAnimationFromLayerWithExistingPlayer(child->id(), timeline(),
+                                             animation_id);
   child->SetTransform(identity);
   child->SetOpacity(0.f);
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
@@ -9099,12 +8959,8 @@
       animation_id, 1, TargetProperty::OPACITY);
   animation->set_fill_mode(Animation::FILL_MODE_NONE);
   animation->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
-  if (layer_settings().use_compositor_animation_timelines) {
-    AddAnimationToLayerWithExistingPlayer(child->id(), timeline(),
-                                          std::move(animation));
-  } else {
-    child->AddAnimation(std::move(animation));
-  }
+  AddAnimationToLayerWithExistingPlayer(child->id(), timeline(),
+                                        std::move(animation));
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
   EXPECT_EQ(gfx::Rect(10, 10), grandchild->visible_layer_rect());
 }
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 19febba..7bda114 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -24,8 +24,6 @@
 #include "base/trace_event/trace_event_argument.h"
 #include "cc/animation/animation_events.h"
 #include "cc/animation/animation_host.h"
-#include "cc/animation/animation_id_provider.h"
-#include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/animation/timing_function.h"
 #include "cc/base/histograms.h"
 #include "cc/base/math_util.h"
@@ -224,7 +222,7 @@
       texture_mailbox_deleter_(new TextureMailboxDeleter(GetTaskRunner())),
       max_memory_needed_bytes_(0),
       resourceless_software_draw_(false),
-      animation_registrar_(),
+      animation_host_(),
       rendering_stats_instrumentation_(rendering_stats_instrumentation),
       micro_benchmark_controller_(this),
       shared_bitmap_manager_(shared_bitmap_manager),
@@ -234,16 +232,10 @@
       requires_high_res_to_draw_(false),
       is_likely_to_require_a_draw_(false),
       frame_timing_tracker_(FrameTimingTracker::Create(this)) {
-  if (settings.use_compositor_animation_timelines) {
-    if (settings.accelerated_animation_enabled) {
-      animation_host_ = AnimationHost::Create(ThreadInstance::IMPL);
-      animation_host_->SetMutatorHostClient(this);
-      animation_host_->SetSupportsScrollAnimations(SupportsImplScrolling());
-    }
-  } else {
-    animation_registrar_ = AnimationRegistrar::Create();
-    animation_registrar_->set_supports_scroll_animations(
-        SupportsImplScrolling());
+  if (settings.accelerated_animation_enabled) {
+    animation_host_ = AnimationHost::Create(ThreadInstance::IMPL);
+    animation_host_->SetMutatorHostClient(this);
+    animation_host_->SetSupportsScrollAnimations(SupportsImplScrolling());
   }
 
   DCHECK(task_runner_provider_->IsImplThread());
@@ -1661,9 +1653,7 @@
 
   if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) {
     bool disable_picture_quad_image_filtering =
-        IsActivelyScrolling() ||
-        (animation_host_ ? animation_host_->NeedsAnimateLayers()
-                         : animation_registrar_->needs_animate_layers());
+        IsActivelyScrolling() || animation_host_->NeedsAnimateLayers();
 
     scoped_ptr<SoftwareRenderer> temp_software_renderer =
         SoftwareRenderer::Create(this, &settings_.renderer_settings,
@@ -3363,13 +3353,8 @@
     return false;
 
   bool animated = false;
-  if (animation_host_) {
-    if (animation_host_->AnimateLayers(monotonic_time))
-      animated = true;
-  } else {
-    if (animation_registrar_->AnimateLayers(monotonic_time))
-      animated = true;
-  }
+  if (animation_host_->AnimateLayers(monotonic_time))
+    animated = true;
 
   // TODO(crbug.com/551134): Only do this if the animations are on the active
   // tree, or if they are on the pending tree waiting for some future time to
@@ -3392,15 +3377,9 @@
   bool has_active_animations = false;
   scoped_ptr<AnimationEvents> events;
 
-  if (animation_host_) {
-    events = animation_host_->CreateEvents();
-    has_active_animations = animation_host_->UpdateAnimationState(
-        start_ready_animations, events.get());
-  } else {
-    events = animation_registrar_->CreateEvents();
-    has_active_animations = animation_registrar_->UpdateAnimationState(
-        start_ready_animations, events.get());
-  }
+  events = animation_host_->CreateEvents();
+  has_active_animations = animation_host_->UpdateAnimationState(
+      start_ready_animations, events.get());
 
   if (!events->events_.empty())
     client_->PostAnimationEventsToMainThreadOnImplThread(std::move(events));
@@ -3413,15 +3392,7 @@
   if (!settings_.accelerated_animation_enabled)
     return;
 
-  bool activated = false;
-  if (animation_host_) {
-    if (animation_host_->ActivateAnimations())
-      activated = true;
-  } else {
-    if (animation_registrar_->ActivateAnimations())
-      activated = true;
-  }
-
+  const bool activated = animation_host_->ActivateAnimations();
   if (activated) {
     // Activating an animation changes layer draw properties, such as
     // screen_space_transform_is_animating. So when we see a new animation get
@@ -3737,71 +3708,25 @@
 }
 
 void LayerTreeHostImpl::ScrollAnimationAbort(LayerImpl* layer_impl) {
-  if (animation_host_)
-    return animation_host_->ScrollAnimationAbort(false /* needs_completion */);
-
-  layer_impl->layer_animation_controller()->AbortAnimations(
-      TargetProperty::SCROLL_OFFSET);
+  return animation_host_->ScrollAnimationAbort(false /* needs_completion */);
 }
 
 void LayerTreeHostImpl::ScrollAnimationCreate(
     ScrollNode* scroll_node,
     const gfx::ScrollOffset& target_offset,
     const gfx::ScrollOffset& current_offset) {
-  if (animation_host_)
-    return animation_host_->ImplOnlyScrollAnimationCreate(
-        scroll_node->owner_id, target_offset, current_offset);
-
-  LayerImpl* layer_impl = active_tree_->LayerById(scroll_node->owner_id);
-
-  scoped_ptr<ScrollOffsetAnimationCurve> curve =
-      ScrollOffsetAnimationCurve::Create(
-          target_offset, EaseInOutTimingFunction::Create(),
-          ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA);
-  curve->SetInitialValue(current_offset);
-
-  scoped_ptr<Animation> animation = Animation::Create(
-      std::move(curve), AnimationIdProvider::NextAnimationId(),
-      AnimationIdProvider::NextGroupId(), TargetProperty::SCROLL_OFFSET);
-  animation->set_is_impl_only(true);
-
-  layer_impl->layer_animation_controller()->AddAnimation(std::move(animation));
+  return animation_host_->ImplOnlyScrollAnimationCreate(
+      scroll_node->owner_id, target_offset, current_offset);
 }
 
 bool LayerTreeHostImpl::ScrollAnimationUpdateTarget(
     ScrollNode* scroll_node,
     const gfx::Vector2dF& scroll_delta) {
-  if (animation_host_)
-    return animation_host_->ImplOnlyScrollAnimationUpdateTarget(
-        scroll_node->owner_id, scroll_delta,
-        active_tree_->property_trees()->scroll_tree.MaxScrollOffset(
-            scroll_node->id),
-        CurrentBeginFrameArgs().frame_time);
-
-  LayerImpl* layer_impl = active_tree_->LayerById(scroll_node->owner_id);
-
-  Animation* animation =
-      layer_impl->layer_animation_controller()
-          ? layer_impl->layer_animation_controller()->GetAnimation(
-                TargetProperty::SCROLL_OFFSET)
-          : nullptr;
-  if (!animation)
-    return false;
-
-  ScrollOffsetAnimationCurve* curve =
-      animation->curve()->ToScrollOffsetAnimationCurve();
-
-  gfx::ScrollOffset new_target =
-      gfx::ScrollOffsetWithDelta(curve->target_value(), scroll_delta);
-  new_target.SetToMax(gfx::ScrollOffset());
-  new_target.SetToMin(layer_impl->MaxScrollOffset());
-
-  curve->UpdateTarget(
-      animation->TrimTimeToCurrentIteration(CurrentBeginFrameArgs().frame_time)
-          .InSecondsF(),
-      new_target);
-
-  return true;
+  return animation_host_->ImplOnlyScrollAnimationUpdateTarget(
+      scroll_node->owner_id, scroll_delta,
+      active_tree_->property_trees()->scroll_tree.MaxScrollOffset(
+          scroll_node->id),
+      CurrentBeginFrameArgs().frame_time);
 }
 
 bool LayerTreeHostImpl::IsLayerInTree(int layer_id,
@@ -3830,7 +3755,7 @@
   if (!tree)
     return;
 
-  LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+  LayerImpl* layer = tree->LayerById(layer_id);
   if (layer)
     layer->OnFilterAnimated(filters);
 }
@@ -3841,7 +3766,7 @@
   if (!tree)
     return;
 
-  LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+  LayerImpl* layer = tree->LayerById(layer_id);
   if (layer)
     layer->OnOpacityAnimated(opacity);
 }
@@ -3853,7 +3778,7 @@
   if (!tree)
     return;
 
-  LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+  LayerImpl* layer = tree->LayerById(layer_id);
   if (layer)
     layer->OnTransformAnimated(transform);
 }
@@ -3865,7 +3790,7 @@
   if (!tree)
     return;
 
-  LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+  LayerImpl* layer = tree->LayerById(layer_id);
   if (layer)
     layer->OnScrollOffsetAnimated(scroll_offset);
 }
@@ -3877,7 +3802,7 @@
   if (!tree)
     return;
 
-  LayerAnimationValueObserver* layer = tree->LayerById(layer_id);
+  LayerImpl* layer = tree->LayerById(layer_id);
   if (layer)
     layer->OnTransformIsPotentiallyAnimatingChanged(is_animating);
 }
@@ -3958,7 +3883,7 @@
 gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation(
     int layer_id) const {
   if (active_tree()) {
-    LayerAnimationValueProvider* layer = active_tree()->LayerById(layer_id);
+    LayerImpl* layer = active_tree()->LayerById(layer_id);
     if (layer)
       return layer->ScrollOffsetForAnimation();
   }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 6d1212f..359a436 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -15,7 +15,6 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/time/time.h"
-#include "cc/animation/animation_registrar.h"
 #include "cc/base/cc_export.h"
 #include "cc/base/synced_property.h"
 #include "cc/debug/frame_timing_tracker.h"
@@ -490,9 +489,6 @@
     return task_runner_provider_;
   }
 
-  AnimationRegistrar* animation_registrar() const {
-    return animation_registrar_.get();
-  }
   AnimationHost* animation_host() const { return animation_host_.get(); }
 
   void SetDebugState(const LayerTreeDebugState& new_debug_state);
@@ -812,7 +808,6 @@
 
   gfx::Rect viewport_damage_rect_;
 
-  scoped_ptr<AnimationRegistrar> animation_registrar_;
   scoped_ptr<AnimationHost> animation_host_;
   std::set<VideoFrameController*> video_frame_controllers_;
 
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 46b98cf..370c1b2 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -209,11 +209,9 @@
         base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
     host_impl_->DidFinishImplFrame();
 
-    if (host_impl_->settings().use_compositor_animation_timelines) {
-      timeline_ =
-          AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
-      host_impl_->animation_host()->AddAnimationTimeline(timeline_);
-    }
+    timeline_ =
+        AnimationTimeline::Create(AnimationIdProvider::NextTimelineId());
+    host_impl_->animation_host()->AddAnimationTimeline(timeline_);
 
     return init;
   }
@@ -1227,11 +1225,7 @@
   child->SetBounds(gfx::Size(10, 10));
   child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
   child->SetDrawsContent(true);
-  if (host_impl_->settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child->id(), timeline(), 10.0, 3, 0);
-  } else {
-    AddAnimatedTransformToLayer(child, 10.0, 3, 0);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child->id(), timeline(), 10.0, 3, 0);
 
   EXPECT_FALSE(did_request_next_frame_);
   EXPECT_FALSE(did_request_redraw_);
@@ -1287,12 +1281,8 @@
   start.AppendTranslate(6.f, 7.f, 0.f);
   TransformOperations end;
   end.AppendTranslate(8.f, 9.f, 0.f);
-  if (host_impl_->settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child->id(), timeline(), 4.0, start,
-                                          end);
-  } else {
-    AddAnimatedTransformToLayer(child, 4.0, start, end);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child->id(), timeline(), 4.0, start,
+                                        end);
 
   base::TimeTicks now = base::TimeTicks::Now();
   host_impl_->WillBeginImplFrame(
@@ -1349,11 +1339,7 @@
   child->SetBounds(gfx::Size(10, 10));
   child->draw_properties().visible_layer_rect = gfx::Rect(10, 10);
   child->SetDrawsContent(true);
-  if (host_impl_->settings().use_compositor_animation_timelines) {
-    AddAnimatedTransformToLayerWithPlayer(child->id(), timeline(), 10.0, 3, 0);
-  } else {
-    AddAnimatedTransformToLayer(child, 10.0, 3, 0);
-  }
+  AddAnimatedTransformToLayerWithPlayer(child->id(), timeline(), 10.0, 3, 0);
 
   // Set up the property trees so that UpdateDrawProperties will work in
   // CommitComplete below.
@@ -1420,13 +1406,8 @@
   start.AppendTranslate(6.f, 7.f, 0.f);
   TransformOperations end;
   end.AppendTranslate(8.f, 9.f, 0.f);
-  int animation_id;
-  if (host_impl_->settings().use_compositor_animation_timelines) {
-    animation_id = AddAnimatedTransformToLayerWithPlayer(
-        child->id(), timeline(), 4.0, start, end);
-  } else {
-    animation_id = AddAnimatedTransformToLayer(child, 4.0, start, end);
-  }
+  int animation_id = AddAnimatedTransformToLayerWithPlayer(
+      child->id(), timeline(), 4.0, start, end);
 
   base::TimeTicks now = base::TimeTicks::Now();
   host_impl_->WillBeginImplFrame(
@@ -1457,12 +1438,8 @@
 
   // Remove the animation.
   child->set_has_missing_tiles(true);
-  if (host_impl_->settings().use_compositor_animation_timelines) {
-    RemoveAnimationFromLayerWithExistingPlayer(child->id(), timeline(),
-                                               animation_id);
-  } else {
-    child->layer_animation_controller()->RemoveAnimation(animation_id);
-  }
+  RemoveAnimationFromLayerWithExistingPlayer(child->id(), timeline(),
+                                             animation_id);
   child->draw_properties().screen_space_transform_is_animating = false;
 
   // Child layer doesn't have an animation, but was never ready since the last
@@ -3458,13 +3435,8 @@
       : DidDrawCheckLayer(tree_impl, id),
         tile_missing_(tile_missing),
         had_incomplete_tile_(had_incomplete_tile) {
-    if (animating) {
-      if (tree_impl->settings().use_compositor_animation_timelines) {
-        AddAnimatedTransformToLayerWithPlayer(this->id(), timeline, 10.0, 3, 0);
-      } else {
-        AddAnimatedTransformToLayer(this, 10.0, 3, 0);
-      }
-    }
+    if (animating)
+      AddAnimatedTransformToLayerWithPlayer(this->id(), timeline, 10.0, 3, 0);
   }
 
   bool tile_missing_;
@@ -3580,8 +3552,7 @@
       to_remove.push_back(child.get());
     for (auto* child : to_remove)
       root->RemoveChild(child);
-    if (host_impl_->settings().use_compositor_animation_timelines)
-      timeline()->ClearPlayers();
+    timeline()->ClearPlayers();
 
     std::ostringstream scope;
     scope << "Test case: " << i;
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index cff38e5..54088ee 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -10,6 +10,7 @@
 #include "cc/animation/animation_host.h"
 #include "cc/animation/animation_id_provider.h"
 #include "cc/animation/animation_player.h"
+#include "cc/animation/animation_registrar.h"
 #include "cc/animation/animation_timeline.h"
 #include "cc/animation/element_animations.h"
 #include "cc/animation/layer_animation_controller.h"
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index e9f11da9..ec65108 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -1193,10 +1193,6 @@
   layer_tree_host_impl_->SetNeedsRedraw();
 }
 
-AnimationRegistrar* LayerTreeImpl::GetAnimationRegistrar() const {
-  return layer_tree_host_impl_->animation_registrar();
-}
-
 void LayerTreeImpl::GetAllPrioritizedTilesForTracing(
     std::vector<PrioritizedTile>* prioritized_tiles) const {
   LayerIterator end = LayerIterator::End(&render_surface_layer_list_);
@@ -1869,13 +1865,6 @@
   }
 }
 
-void LayerTreeImpl::InputScrollAnimationFinished() {
-  // TODO(majidvp): We should pass in the original starting scroll position here
-  ScrollStateData scroll_state_data;
-  ScrollState scroll_state(scroll_state_data);
-  layer_tree_host_impl_->ScrollEnd(&scroll_state);
-}
-
 bool LayerTreeImpl::SmoothnessTakesPriority() const {
   return layer_tree_host_impl_->GetTreePriority() == SMOOTHNESS_TAKES_PRIORITY;
 }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 57523f97..c6c1cae 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -108,7 +108,6 @@
   scoped_ptr<ScrollbarAnimationController> CreateScrollbarAnimationController(
       int scroll_layer_id);
   void DidAnimateScrollOffset();
-  void InputScrollAnimationFinished();
   bool use_gpu_rasterization() const;
   GpuRasterizationStatus GetGpuRasterizationStatus() const;
   bool create_low_res_tiling() const;
@@ -310,8 +309,6 @@
 
   size_t NumLayers();
 
-  AnimationRegistrar* GetAnimationRegistrar() const;
-
   void DidBecomeActive();
 
   // Set on the active tree when the viewport size recently changed
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc
index 417cda5..d35036d 100644
--- a/cc/trees/tree_synchronizer_unittest.cc
+++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -82,31 +82,6 @@
   std::vector<int>* layer_impl_destruction_list_;
 };
 
-class FakeLayerAnimationController : public LayerAnimationController {
- public:
-  static scoped_refptr<LayerAnimationController> Create() {
-    return static_cast<LayerAnimationController*>(
-        new FakeLayerAnimationController);
-  }
-
-  bool SynchronizedAnimations() const { return synchronized_animations_; }
-
- private:
-  FakeLayerAnimationController()
-      : LayerAnimationController(1),
-        synchronized_animations_(false) {}
-
-  ~FakeLayerAnimationController() override {}
-
-  void PushAnimationUpdatesTo(
-      LayerAnimationController* controller_impl) override {
-    LayerAnimationController::PushAnimationUpdatesTo(controller_impl);
-    synchronized_animations_ = true;
-  }
-
-  bool synchronized_animations_;
-};
-
 void ExpectTreesAreIdentical(Layer* layer,
                              LayerImpl* layer_impl,
                              LayerTreeImpl* tree_impl) {
@@ -590,43 +565,6 @@
                           host_->active_tree());
 }
 
-TEST_F(TreeSynchronizerTest, SynchronizeAnimations) {
-  LayerTreeSettingsForTreeSynchronizerTest settings;
-  // This test is meaningless in new use_compositor_animation_timelines mode.
-  // TODO(loyso): Delete FakeLayerAnimationController and related stuff.
-  if (settings.use_compositor_animation_timelines)
-    return;
-
-  FakeImplTaskRunnerProvider task_runner_provider;
-  FakeRenderingStatsInstrumentation stats_instrumentation;
-  TestSharedBitmapManager shared_bitmap_manager;
-  TestTaskGraphRunner task_graph_runner;
-  scoped_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
-      settings, nullptr, &task_runner_provider, &stats_instrumentation,
-      &shared_bitmap_manager, nullptr, &task_graph_runner, 0);
-
-  scoped_refptr<Layer> layer_tree_root = Layer::Create(layer_settings_);
-  host_->SetRootLayer(layer_tree_root);
-
-  layer_tree_root->SetLayerAnimationControllerForTest(
-      FakeLayerAnimationController::Create());
-
-  EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(
-      layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
-
-  scoped_ptr<LayerImpl> layer_impl_tree_root =
-      TreeSynchronizer::SynchronizeTrees(
-          layer_tree_root.get(), nullptr, host_->active_tree());
-  TreeSynchronizer::PushProperties(layer_tree_root.get(),
-                                   layer_impl_tree_root.get());
-  layer_impl_tree_root = TreeSynchronizer::SynchronizeTrees(
-      layer_tree_root.get(), std::move(layer_impl_tree_root),
-      host_->active_tree());
-
-  EXPECT_TRUE(static_cast<FakeLayerAnimationController*>(
-      layer_tree_root->layer_animation_controller())->SynchronizedAnimations());
-}
-
 TEST_F(TreeSynchronizerTest, SynchronizeScrollParent) {
   LayerTreeSettings settings;
   FakeImplTaskRunnerProvider task_runner_provider;
diff --git a/chrome/VERSION b/chrome/VERSION
index 5b5baa1f..f1c8402f 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=51
 MINOR=0
-BUILD=2674
+BUILD=2675
 PATCH=0
diff --git a/chrome/android/java/res/xml/clear_browsing_data_preferences.xml b/chrome/android/java/res/xml/clear_browsing_data_preferences.xml
index 1dacee6b..789c45d 100644
--- a/chrome/android/java/res/xml/clear_browsing_data_preferences.xml
+++ b/chrome/android/java/res/xml/clear_browsing_data_preferences.xml
@@ -38,11 +38,6 @@
         android:persistent="false"
         android:title="@string/clear_form_data_title" />
 
-    <org.chromium.chrome.browser.preferences.ClearBrowsingDataCheckBoxPreference
-        android:key="clear_bookmarks_checkbox"
-        android:persistent="false"
-        android:title="@string/clear_bookmarks_title" />
-
     <org.chromium.chrome.browser.preferences.ButtonPreference
         android:key="clear_button"
         android:title="@string/clear_data_delete" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index d2e4357c..8d3bc99f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -271,7 +271,6 @@
 
     private void refreshSignIn() {
         if (mIsOnFirstRun) return;
-        Log.i(TAG, "in refreshSignIn before starting the sign-in processor");
         FirstRunSignInProcessor.start(this);
     }
 
@@ -932,10 +931,8 @@
 
         final boolean isIntentActionMain = getIntent() != null
                 && TextUtils.equals(getIntent().getAction(), Intent.ACTION_MAIN);
-        Log.i(TAG, "begin FirstRunFlowSequencer.checkIfFirstRunIsNecessary");
         final Intent freIntent = FirstRunFlowSequencer.checkIfFirstRunIsNecessary(
                 this, isIntentActionMain);
-        Log.i(TAG, "end FirstRunFlowSequencer.checkIfFirstRunIsNecessary");
         if (freIntent == null) return;
 
         mIsOnFirstRun = true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
index d341cbc..1d098b5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
@@ -71,8 +71,8 @@
             if (mModel.doesBookmarkExist(mBookmarkId)) {
                 updateViewContent(true);
             } else {
-                Log.wtf(TAG, "A partner bookmark might be removed while the user is editing it.",
-                        new Exception(TAG));
+                // This happens either when the user clicks delete button or partner bookmark is
+                // removed in background.
                 finish();
             }
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java
index 166c4fb..badc4ef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/readermode/ReaderModePanel.java
@@ -172,7 +172,6 @@
         super.handleBarClick(time, x, y);
         if (isCoordinateInsideCloseButton(x)) {
             closePanel(StateChangeReason.CLOSE_BUTTON, true);
-            mManagerDelegate.onCloseButtonPressed();
         } else {
             maximizePanel(StateChangeReason.SEARCH_BAR_TAP);
         }
@@ -264,6 +263,13 @@
         }
     }
 
+    @Override
+    protected void onClosed(StateChangeReason reason) {
+        super.onClosed(reason);
+        if (mManagerDelegate == null) return;
+        mManagerDelegate.onClosed(reason);
+    }
+
     /**
      * Record the time spent in Reader Mode.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
index 48b1780..8cc347d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
@@ -314,11 +314,21 @@
     }
 
     @Override
-    public void onCloseButtonPressed() {
+    public void onClosed(StateChangeReason reason) {
         if (mReaderModePanel == null) return;
-        RecordHistogram.recordBooleanHistogram("DomDistiller.BarCloseButtonUsage",
-                mReaderModePanel.getPanelState() == PanelState.EXPANDED
-                || mReaderModePanel.getPanelState() == PanelState.MAXIMIZED);
+
+        // Only dismiss the panel if the close was a result of user interaction.
+        if (reason != StateChangeReason.FLING && reason != StateChangeReason.SWIPE
+                && reason != StateChangeReason.CLOSE_BUTTON) {
+            return;
+        }
+
+        // Record close button usage.
+        if (reason == StateChangeReason.CLOSE_BUTTON) {
+            RecordHistogram.recordBooleanHistogram("DomDistiller.BarCloseButtonUsage",
+                    mReaderModePanel.getPanelState() == PanelState.EXPANDED
+                    || mReaderModePanel.getPanelState() == PanelState.MAXIMIZED);
+        }
 
         int currentTabId = mTabModelSelector.getCurrentTabId();
         if (!mTabStatusMap.containsKey(currentTabId)) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerDelegate.java
index ffaf1699..fc1afdd5b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerDelegate.java
@@ -35,9 +35,9 @@
     void createNewTab(String url);
 
     /**
-     * Notify the manager that the panel was closed using the "x" icon.
+     * Notify the manager that the panel has completely closed.
      */
-    void onCloseButtonPressed();
+    void onClosed(StateChangeReason reason);
 
     /**
      * Get the WebContents of the page that is being distilled.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java
index ee0a710..3ddd6cc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java
@@ -14,6 +14,7 @@
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.BrowsingDataType;
+import org.chromium.chrome.browser.TimePeriod;
 import org.chromium.chrome.browser.preferences.ButtonPreference;
 import org.chromium.chrome.browser.preferences.ClearBrowsingDataCheckBoxPreference;
 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
@@ -25,8 +26,9 @@
 import java.util.EnumSet;
 
 /**
- * Modal dialog with options for selection the type of browsing data
- * to clear (history, cookies), triggered from a preference.
+ * Preference screen that allows the user to clear browsing data.
+ * The user can choose which types of data to clear (history, cookies, etc), and the time range
+ * from which to clear data.
  */
 public class ClearBrowsingDataPreferences extends PreferenceFragment
         implements PrefServiceBridge.OnClearBrowsingDataListener,
@@ -106,7 +108,6 @@
     private static final String PREF_CACHE = "clear_cache_checkbox";
     private static final String PREF_PASSWORDS = "clear_passwords_checkbox";
     private static final String PREF_FORM_DATA = "clear_form_data_checkbox";
-    private static final String PREF_BOOKMARKS = "clear_bookmarks_checkbox";
 
     private static final String PREF_SUMMARY = "summary";
     private static final String PREF_TIME_RANGE = "time_period_spinner";
@@ -118,16 +119,14 @@
     public static final String TAG = "ClearBrowsingDataPreferences";
 
     /**
-     * Enum for Dialog options to be displayed in the dialog.
+     * The various data types that can be cleared via this screen.
      */
     public enum DialogOption {
         CLEAR_HISTORY(BrowsingDataType.HISTORY, PREF_HISTORY),
         CLEAR_COOKIES_AND_SITE_DATA(BrowsingDataType.COOKIES, PREF_COOKIES),
         CLEAR_CACHE(BrowsingDataType.CACHE, PREF_CACHE),
         CLEAR_PASSWORDS(BrowsingDataType.PASSWORDS, PREF_PASSWORDS),
-        CLEAR_FORM_DATA(BrowsingDataType.FORM_DATA, PREF_FORM_DATA),
-        // Clear bookmarks is only used by ClearSyncData dialog.
-        CLEAR_BOOKMARKS_DATA(BrowsingDataType.BOOKMARKS, PREF_BOOKMARKS);
+        CLEAR_FORM_DATA(BrowsingDataType.FORM_DATA, PREF_FORM_DATA);
 
         private final int mDataType;
         private final String mPreferenceKey;
@@ -159,7 +158,7 @@
         /**
          * Constructs this time period spinner option.
          * @param timePeriod The time period represented as an int from the shared enum
-         *     {@link org.chromium.chrome.browser.TimePeriod}.
+         *     {@link TimePeriod}.
          * @param title The text that will be used to represent this item in the spinner.
          */
         public TimePeriodSpinnerOption(int timePeriod, String title) {
@@ -168,8 +167,7 @@
         }
 
         /**
-         * @return The time period represented as an int from the shared enum
-         *     {@link org.chromium.chrome.browser.TimePeriod}
+         * @return The time period represented as an int from the shared enum {@link TimePeriod}
          */
         public int getTimePeriod() {
             return mTimePeriod;
@@ -182,10 +180,9 @@
     }
 
     private ProgressDialog mProgressDialog;
-    private boolean mCanDeleteBrowsingHistory;
     private Item[] mItems;
 
-    protected final EnumSet<DialogOption> getSelectedOptions() {
+    private final EnumSet<DialogOption> getSelectedOptions() {
         EnumSet<DialogOption> selected = EnumSet.noneOf(DialogOption.class);
         for (Item item : mItems) {
             if (item.isSelected()) selected.add(item.getOption());
@@ -197,9 +194,10 @@
      * Requests the browsing data corresponding to the given dialog options to be deleted.
      * @param options The dialog options whose corresponding data should be deleted.
      */
-    protected final void clearBrowsingData(EnumSet<DialogOption> options) {
-        int[] dataTypes = new int[options.size()];
+    private final void clearBrowsingData(EnumSet<DialogOption> options) {
+        showProgressDialog();
 
+        int[] dataTypes = new int[options.size()];
         int i = 0;
         for (DialogOption option : options) {
             dataTypes[i] = option.getDataType();
@@ -209,10 +207,8 @@
         PrefServiceBridge.getInstance().clearBrowsingData(this, dataTypes);
     }
 
-    protected void dismissProgressDialog() {
-        android.util.Log.i(TAG, "in dismissProgressDialog");
+    private void dismissProgressDialog() {
         if (mProgressDialog != null && mProgressDialog.isShowing()) {
-            android.util.Log.i(TAG, "progress dialog dismissed");
             mProgressDialog.dismiss();
         }
         mProgressDialog = null;
@@ -222,7 +218,7 @@
      * Returns the Array of dialog options. Options are displayed in the same
      * order as they appear in the array.
      */
-    protected DialogOption[] getDialogOptions() {
+    private DialogOption[] getDialogOptions() {
         return new DialogOption[] {
             DialogOption.CLEAR_HISTORY,
             DialogOption.CLEAR_COOKIES_AND_SITE_DATA,
@@ -239,15 +235,15 @@
         Activity activity = getActivity();
 
         TimePeriodSpinnerOption[] options = new TimePeriodSpinnerOption[] {
-                new TimePeriodSpinnerOption(org.chromium.chrome.browser.TimePeriod.LAST_HOUR,
+                new TimePeriodSpinnerOption(TimePeriod.LAST_HOUR,
                         activity.getString(R.string.clear_browsing_data_period_hour)),
-                new TimePeriodSpinnerOption(org.chromium.chrome.browser.TimePeriod.LAST_DAY,
+                new TimePeriodSpinnerOption(TimePeriod.LAST_DAY,
                         activity.getString(R.string.clear_browsing_data_period_day)),
-                new TimePeriodSpinnerOption(org.chromium.chrome.browser.TimePeriod.LAST_WEEK,
+                new TimePeriodSpinnerOption(TimePeriod.LAST_WEEK,
                         activity.getString(R.string.clear_browsing_data_period_week)),
-                new TimePeriodSpinnerOption(org.chromium.chrome.browser.TimePeriod.FOUR_WEEKS,
+                new TimePeriodSpinnerOption(TimePeriod.FOUR_WEEKS,
                         activity.getString(R.string.clear_browsing_data_period_four_weeks)),
-                new TimePeriodSpinnerOption(org.chromium.chrome.browser.TimePeriod.EVERYTHING,
+                new TimePeriodSpinnerOption(TimePeriod.EVERYTHING,
                         activity.getString(R.string.clear_browsing_data_period_everything))};
 
         return options;
@@ -258,7 +254,7 @@
      * @param option The option in question.
      * @return boolean Whether the given option should be preselected.
      */
-    protected boolean isOptionSelectedByDefault(DialogOption option) {
+    private boolean isOptionSelectedByDefault(DialogOption option) {
         return PrefServiceBridge.getInstance().getBrowsingDataDeletionPreference(
             option.getDataType());
     }
@@ -276,8 +272,7 @@
     @Override
     public boolean onPreferenceClick(Preference preference) {
         if (preference.getKey().equals(PREF_CLEAR_BUTTON)) {
-            dismissProgressDialog();
-            onOptionSelected();
+            clearBrowsingData(getSelectedOptions());
             return true;
         }
         return false;
@@ -393,18 +388,9 @@
         }
     }
 
-    /**
-     * Called when PositiveButton is clicked for the dialog.
-     */
-    protected void onOptionSelected() {
-        showProgressDialog();
-        clearBrowsingData(getSelectedOptions());
-    }
-
-    protected final void showProgressDialog() {
+    private final void showProgressDialog() {
         if (getActivity() == null) return;
 
-        android.util.Log.i(TAG, "progress dialog shown");
         mProgressDialog = ProgressDialog.show(getActivity(),
                 getActivity().getString(R.string.clear_browsing_data_progress_title),
                 getActivity().getString(R.string.clear_browsing_data_progress_message), true,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/AndroidEduAndChildAccountHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/services/AndroidEduAndChildAccountHelper.java
index 2bdd20f..022ceba 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/services/AndroidEduAndChildAccountHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/services/AndroidEduAndChildAccountHelper.java
@@ -7,7 +7,6 @@
 import android.content.Context;
 
 import org.chromium.base.Callback;
-import org.chromium.base.Log;
 import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.childaccounts.ChildAccountService;
 
@@ -42,23 +41,19 @@
      * @param appContext The application context.
      */
     public void start(Context appContext) {
-        Log.d(TAG, "before checking child and EDU");
         ChildAccountService.checkHasChildAccount(appContext, this);
         ((ChromeApplication) appContext).checkIsAndroidEduDevice(this);
         // TODO(aruslan): Should we start a watchdog to kill if Child/Edu stuff takes too long?
-        Log.d(TAG, "returning from start");
     }
 
     private void checkDone() {
         if (mIsAndroidEduDevice == null || mHasChildAccount == null) return;
-        Log.d(TAG, "parameters are ready");
         onParametersReady();
     }
 
     // AndroidEdu.OwnerCheckCallback:
     @Override
     public void onSchoolCheckDone(boolean isAndroidEduDevice) {
-        Log.d(TAG, "onSchoolCheckDone");
         mIsAndroidEduDevice = isAndroidEduDevice;
         checkDone();
     }
@@ -66,7 +61,6 @@
     // Callback<Boolean>:
     @Override
     public void onResult(Boolean hasChildAccount) {
-        Log.d(TAG, "onChildAccountChecked");
         mHasChildAccount = hasChildAccount;
         checkDone();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ClearSyncDataPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ClearSyncDataPreferences.java
deleted file mode 100644
index 1e6c605..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ClearSyncDataPreferences.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.sync.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.AsyncTask;
-
-import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataPreferences;
-import org.chromium.chrome.browser.provider.ChromeBrowserProviderClient;
-import org.chromium.chrome.browser.signin.SigninManager;
-
-import java.util.EnumSet;
-
-/**
- * Modal dialog for clearing sync data. This allows the user to clear browsing data as well as
- * other synced data types like bookmarks.
- */
-public class ClearSyncDataPreferences extends ClearBrowsingDataPreferences {
-    private Context mApplicationContext;
-
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mApplicationContext = context.getApplicationContext();
-    }
-
-    @Override
-    @SuppressWarnings("deprecation")
-    public void onAttach(Activity activity) {
-        super.onAttach(activity);
-        mApplicationContext = activity.getApplicationContext();
-    }
-
-    @Override
-    protected DialogOption[] getDialogOptions() {
-        return DialogOption.values();
-    }
-
-    @Override
-    protected boolean isOptionSelectedByDefault(DialogOption option) {
-        return true;
-    }
-
-    @Override
-    protected void onOptionSelected() {
-        if (mApplicationContext == null) return;
-
-        showProgressDialog();
-
-        // Bookmarks will be deleted locally, and not passed on to the native side.
-        final EnumSet<DialogOption> selectedOptions = getSelectedOptions();
-        final boolean shouldDeleteBookmarks =
-                selectedOptions.contains(DialogOption.CLEAR_BOOKMARKS_DATA);
-        selectedOptions.remove(DialogOption.CLEAR_BOOKMARKS_DATA);
-
-        // Clear bookmarks first and then clear browsing data. Clear browsing data will remove
-        // the progress dialog.
-        // TODO(shashishekhar) We should not need an async task here, since bookmarks operations
-        // are on UI thread. ChromeBrowserProvider enforces that call to Bookmark API is not on
-        // the UI thread. http://crbug.com/225050
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... arg0) {
-                if (shouldDeleteBookmarks) {
-                    ChromeBrowserProviderClient.removeAllUserBookmarks(mApplicationContext);
-                }
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(Void result) {
-                clearBrowsingData(selectedOptions);
-
-                if (shouldDeleteBookmarks) {
-                    // onPostExecute is back in the UI thread.
-                    SigninManager.get(mApplicationContext).clearLastSignedInUser();
-                }
-            }
-        }.execute();
-    }
-}
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index eb6d92d..10b56ef 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -445,9 +445,6 @@
       <message name="IDS_CLEAR_FORM_DATA_TITLE" desc="Title for Clear Form Data in Clear Browsing Data preference">
         Autofill form data
       </message>
-      <message name="IDS_CLEAR_BOOKMARKS_TITLE" desc="Title for Clear Bookmarks data in Clear Synced Data dialog">
-        Bookmarks
-      </message>
       <message name="IDS_CLEAR_BROWSING_DATA_PROGRESS_TITLE" desc='Title for the progress dialog used when waiting for "clear browsing data" to complete.'>
         Clearing browsing data
       </message>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java
index e106e6a..c635b5f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastPositionTransferTest.java
@@ -4,10 +4,13 @@
 
 package org.chromium.chrome.browser.media.remote;
 
+import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE;
+
 import android.graphics.Rect;
 import android.test.suitebuilder.annotation.LargeTest;
 
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content.browser.test.util.JavaScriptUtils;
 
@@ -133,6 +136,7 @@
     /** Test for crbug.com/425105 */
     @Feature({"VideoFling"})
     @LargeTest
+    @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) // Flaky - crbug.com/593840
     public void testPositionUpdate() throws InterruptedException, TimeoutException {
         final Tab tab = getActivity().getActivityTab();
         final Rect videoRect = prepareDefaultVideofromPage(DEFAULT_VIDEO_PAGE, tab);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
index a9b26f6..0e62a48 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
@@ -12,19 +12,21 @@
 import org.chromium.base.ThreadUtils;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.preferences.ButtonPreference;
+import org.chromium.chrome.browser.preferences.PrefServiceBridge;
 import org.chromium.chrome.browser.preferences.Preferences;
+import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataPreferences.DialogOption;
 import org.chromium.chrome.browser.webapps.WebappRegistry;
 import org.chromium.chrome.test.ChromeActivityTestCaseBase;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 
 import java.util.Arrays;
-import java.util.EnumSet;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
- * Performs integration tests with ClearBrowsingDataPreferences.
+ * Integration tests for ClearBrowsingDataPreferences.
  */
 public class ClearBrowsingDataPreferencesTest
         extends ChromeActivityTestCaseBase<ChromeActivity> {
@@ -61,8 +63,9 @@
         });
         mCallbackCalled = false;
 
+        setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_COOKIES_AND_SITE_DATA));
         final Preferences preferences =
-                startPreferences(CookiesClearBrowsingDataPreferences.class.getName());
+                startPreferences(ClearBrowsingDataPreferences.class.getName());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -105,8 +108,10 @@
      */
     @MediumTest
     public void testClearingEverything() throws Exception {
+        setDataTypesToClear(Arrays.asList(DialogOption.values()));
+
         final Preferences preferences =
-                startPreferences(ClearEverythingBrowsingDataPreferences.class.getName());
+                startPreferences(ClearBrowsingDataPreferences.class.getName());
 
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
@@ -141,46 +146,16 @@
         });
     }
 
-    /**
-     * A testing version of ClearBrowsingDataPreferences that preselects the cookies option.
-     * Must be public, as ChromeActivityTestCaseBase.startPreferences references it by name.
-     */
-    public static class CookiesClearBrowsingDataPreferences extends ClearBrowsingDataPreferences {
-        private static final EnumSet<DialogOption> DEFAULT_OPTIONS = EnumSet.of(
-                ClearBrowsingDataPreferences.DialogOption.CLEAR_COOKIES_AND_SITE_DATA);
-
-        @Override
-        protected boolean isOptionSelectedByDefault(DialogOption option) {
-            return DEFAULT_OPTIONS.contains(option);
-        }
-    }
-
-    /**
-     * A testing version of ClearBrowsingDataPreferences that includes all possible options,
-     * and preselects all of them. Must be public, as ChromeActivityTestCaseBase.startPreferences
-     * references it by name.
-     */
-    public static class ClearEverythingBrowsingDataPreferences
-            extends ClearBrowsingDataPreferences {
-        @Override
-        protected void onOptionSelected() {
-            // All options should be selected.
-            EnumSet<DialogOption> options = getSelectedOptions();
-            assertEquals(EnumSet.allOf(DialogOption.class), options);
-
-            // Bookmarks currently must be handled on the Java side, and not passed to C++.
-            options.remove(DialogOption.CLEAR_BOOKMARKS_DATA);
-            clearBrowsingData(options);
-        }
-
-        @Override
-        protected DialogOption[] getDialogOptions() {
-            return DialogOption.values();
-        }
-
-        @Override
-        protected boolean isOptionSelectedByDefault(DialogOption option) {
-            return true;
-        }
+    private void setDataTypesToClear(final List<DialogOption> typesToClear) {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                for (DialogOption option : DialogOption.values()) {
+                    boolean enabled = typesToClear.contains(option);
+                    PrefServiceBridge.getInstance().setBrowsingDataDeletionPreference(
+                            option.getDataType(), enabled);
+                }
+            }
+        });
     }
 }
diff --git a/chrome/app/OWNERS b/chrome/app/OWNERS
index c555dc7..4ea929b 100644
--- a/chrome/app/OWNERS
+++ b/chrome/app/OWNERS
@@ -21,6 +21,7 @@
 per-file media_router_strings.grdp*=wez@chromium.org
 
 per-file settings*strings*=dbeam@chromium.org
+per-file settings*strings*=dpapad@chromium.org
 per-file settings*strings*=dschuyler@chromium.org
 per-file settings*strings*=michaelpg@chromium.org
 per-file settings*strings*=stevenjb@chromium.org
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index e737b9a..5eae9de 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -5440,7 +5440,7 @@
     Can't access network library
   </message>
   <message name="IDS_LOGIN_ERROR_KEYBOARD_SWITCH_HINT" desc="A hint text for the login and lock screens about layout switching">
-    Hit Shift-Alt to switch keyboard layout.
+    Hit Control-Shift-Space to switch keyboard layout.
   </message>
   <message name="IDS_LOGIN_ERROR_CAPS_LOCK_HINT" desc="A hint text for the login and lock screens that Caps Lock is on">
     Caps Lock is on.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 9541d09..3f4a837 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -12999,6 +12999,12 @@
       <message name="IDS_FLAGS_ENABLE_PASSWORD_SEPARATED_SIGNIN_FLOW_DESCRIPTION" desc="Description for the flag to enable the new gaia password-separated sign in flow.">
         When enabled, signing in to the browser will use a new gaia password-separated sign in flow.
       </message>
+      <message name="IDS_FLAGS_ENABLE_MATERIAL_DESIGN_USER_MANAGER_NAME" desc="Title for the flag to enable the new material design user manager.">
+        Enable Material Design User Manager
+      </message>
+      <message name="IDS_FLAGS_ENABLE_MATERIAL_DESIGN_USER_MANAGER_DESCRIPTION" desc="Description for the flag to enable the new material design user manager.">
+        When enabled, the Switch person button in the avatar menu launches the new Material Design user manager.
+      </message>
 
       <message name="IDS_FLAGS_GOOGLE_PROFILE_INFO_NAME" desc="Title for the flag to enable the google profile information">
         Google profile name and icon
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index ef15445..5120d6c 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -239,7 +239,7 @@
     You have certificates from these organizations that identify you:
   </message>
 
-  <!-- Certificate Manager Page, Edit Certificate Authority Trust dialog-->
+  <!-- Certificate Manager Page, edit certificate authority trust dialog-->
   <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_TITLE" desc="Title of the certificate manager edit trust dialog">
     Certificate authority
   </message>
@@ -259,6 +259,29 @@
     Trust this certificate for identifying software makers.
   </message>
 
+  <!-- Certificate Manager Page, delete certificate confirmation dialog -->
+  <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_TITLE" desc="Title of a certificate manager dialog for confirming deletion of a user certificate">
+    Delete certificate "<ph name="CERTIFICATE_NAME">$1<ex>VeriSign Browser Certificate</ex></ph>"?
+  </message>
+  <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_DESCRIPTION" desc="Description of impact of deleting a user certificate">
+    If you delete one of your own certificates, you can no longer use it to identify yourself.
+  </message>
+  <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_TITLE" desc="Title of a certificate manager dialog for confirming deletion of a server certificate">
+    Delete server certificate "<ph name="CERTIFICATE_NAME">$1<ex>www.example.com</ex></ph>"?
+  </message>
+  <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_DESCRIPTION" desc="Description of impact of deleting a user certificate">
+    If you delete a server certificate, you restore the usual security checks for that server and require it uses a valid certificate.
+  </message>
+  <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_TITLE" desc="Title of a certificate manager dialog for confirming deletion of a certification authority certificate">
+    Delete CA certificate "<ph name="CERTIFICATE_NAME">$1<ex>Verisign Class 1 Public Primary Certification Authority</ex></ph>"?
+  </message>
+  <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_DESCRIPTION" desc="Description of impact of deleting a user certificate">
+    If you delete a Certification Authority (CA) certificate, your browser will no longer trust any certificates issued by that CA.
+  </message>
+  <message name="IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_OTHER_TITLE" desc="Title of a certificate manager dialog for confirming deletion of a certificate of other type">
+    Delete certificate "<ph name="CERTIFICATE_NAME">$1<ex>Example Certificate</ex></ph>"?
+  </message>
+
   <!-- Clear Browsing Data -->
   <message name="IDS_SETTINGS_CLEAR_FOLLOWING_ITEMS_FROM" desc="Label at the top of the client area of the dialog, preceding the period combo box">
     Clear the following items from
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 13b958c5..c5a0116 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1153,6 +1153,11 @@
      IDS_FLAGS_ENABLE_PASSWORD_SEPARATED_SIGNIN_FLOW_DESCRIPTION,
      kOsMac | kOsWin | kOsLinux,
      FEATURE_VALUE_TYPE(switches::kUsePasswordSeparatedSigninFlow)},
+    {"enable-material-design-user-manager",
+     IDS_FLAGS_ENABLE_MATERIAL_DESIGN_USER_MANAGER_NAME,
+     IDS_FLAGS_ENABLE_MATERIAL_DESIGN_USER_MANAGER_DESCRIPTION,
+     kOsMac | kOsWin | kOsLinux,
+     FEATURE_VALUE_TYPE(switches::kMaterialDesignUserManager)},
     {"enable-google-profile-info", IDS_FLAGS_GOOGLE_PROFILE_INFO_NAME,
      IDS_FLAGS_GOOGLE_PROFILE_INFO_DESCRIPTION, kOsMac | kOsWin | kOsLinux,
      SINGLE_VALUE_TYPE(switches::kGoogleProfileInfo)},
diff --git a/chrome/browser/android/DEPS b/chrome/browser/android/DEPS
index 4fc151f..15d2265 100644
--- a/chrome/browser/android/DEPS
+++ b/chrome/browser/android/DEPS
@@ -7,6 +7,7 @@
   "+components/toolbar",
   "+components/web_contents_delegate_android",
   "+cc/layers/layer.h",
+  "+cc/layers/layer_settings.h",
   "+sandbox/linux/seccomp-bpf/sandbox_bpf.h",
   "+sync/android",
   "+sync/test/fake_server/android",
diff --git a/chrome/browser/android/compositor/compositor_view.cc b/chrome/browser/android/compositor/compositor_view.cc
index 6958080..edc8b07e 100644
--- a/chrome/browser/android/compositor/compositor_view.cc
+++ b/chrome/browser/android/compositor/compositor_view.cc
@@ -19,6 +19,7 @@
 #include "base/trace_event/trace_event.h"
 #include "cc/layers/layer.h"
 #include "cc/layers/layer_lists.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/layers/texture_layer.h"
 #include "chrome/browser/android/compositor/layer/toolbar_layer.h"
@@ -83,7 +84,7 @@
     : layer_title_cache_(layer_title_cache),
       tab_content_manager_(tab_content_manager),
       root_layer_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       scene_layer_(nullptr),
       current_surface_format_(0),
       content_width_(0),
diff --git a/chrome/browser/android/compositor/decoration_title.cc b/chrome/browser/android/compositor/decoration_title.cc
index 7bbbf22..9eac932 100644
--- a/chrome/browser/android/compositor/decoration_title.cc
+++ b/chrome/browser/android/compositor/decoration_title.cc
@@ -9,6 +9,7 @@
 #include "base/i18n/rtl.h"
 #include "base/logging.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "cc/resources/scoped_ui_resource.h"
 #include "chrome/browser/android/compositor/layer_title_cache.h"
@@ -32,13 +33,13 @@
                                  int favicon_end_padding,
                                  bool is_incognito,
                                  bool is_rtl)
-    : layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
+    : layer_(cc::Layer::Create(cc::LayerSettings())),
       layer_opaque_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       layer_fade_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       layer_favicon_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       title_resource_id_(title_resource_id),
       favicon_resource_id_(favicon_resource_id),
       spinner_resource_id_(spinner_resource_id),
diff --git a/chrome/browser/android/compositor/layer/content_layer.cc b/chrome/browser/android/compositor/layer/content_layer.cc
index 281b0fe..e83a2c4 100644
--- a/chrome/browser/android/compositor/layer/content_layer.cc
+++ b/chrome/browser/android/compositor/layer/content_layer.cc
@@ -7,6 +7,7 @@
 #include "base/lazy_instance.h"
 #include "cc/layers/layer.h"
 #include "cc/layers/layer_lists.h"
+#include "cc/layers/layer_settings.h"
 #include "chrome/browser/android/compositor/layer/thumbnail_layer.h"
 #include "chrome/browser/android/compositor/tab_content_manager.h"
 #include "content/public/browser/android/compositor.h"
@@ -145,7 +146,7 @@
 }
 
 ContentLayer::ContentLayer(TabContentManager* tab_content_manager)
-    : layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
+    : layer_(cc::Layer::Create(cc::LayerSettings())),
       content_attached_(false),
       static_attached_(false),
       tab_content_manager_(tab_content_manager) {
diff --git a/chrome/browser/android/compositor/layer/contextual_search_layer.cc b/chrome/browser/android/compositor/layer/contextual_search_layer.cc
index 7e0c7b0..0a7bd64 100644
--- a/chrome/browser/android/compositor/layer/contextual_search_layer.cc
+++ b/chrome/browser/android/compositor/layer/contextual_search_layer.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/android/compositor/layer/contextual_search_layer.h"
 
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/nine_patch_layer.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/layers/ui_resource_layer.h"
@@ -406,24 +407,24 @@
     ui::ResourceManager* resource_manager)
     : OverlayPanelLayer(resource_manager),
       search_context_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       search_provider_icon_sprite_(CrushedSpriteLayer::Create()),
       arrow_icon_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       search_promo_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       search_promo_container_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       peek_promo_container_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       peek_promo_ripple_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
       peek_promo_text_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       progress_bar_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
       progress_bar_background_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())) {
+          cc::NinePatchLayer::Create(cc::LayerSettings())) {
   // Search Peek Promo
   peek_promo_container_->SetIsDrawable(true);
   peek_promo_container_->SetBackgroundColor(kSearchBarBackgroundColor);
diff --git a/chrome/browser/android/compositor/layer/crushed_sprite_layer.cc b/chrome/browser/android/compositor/layer/crushed_sprite_layer.cc
index b745880a..06677fc3 100644
--- a/chrome/browser/android/compositor/layer/crushed_sprite_layer.cc
+++ b/chrome/browser/android/compositor/layer/crushed_sprite_layer.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/android/compositor/layer/crushed_sprite_layer.h"
 
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "content/public/browser/android/compositor.h"
 #include "ui/android/resources/crushed_sprite_resource.h"
@@ -116,7 +117,7 @@
 
 CrushedSpriteLayer::CrushedSpriteLayer()
     : layer_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       frame_count_(-1),
       previous_frame_(-1) {
   layer_->SetIsDrawable(true);
diff --git a/chrome/browser/android/compositor/layer/overlay_panel_layer.cc b/chrome/browser/android/compositor/layer/overlay_panel_layer.cc
index 1a7f394d..5645763 100644
--- a/chrome/browser/android/compositor/layer/overlay_panel_layer.cc
+++ b/chrome/browser/android/compositor/layer/overlay_panel_layer.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/android/compositor/layer/overlay_panel_layer.h"
 
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/nine_patch_layer.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/layers/ui_resource_layer.h"
@@ -260,24 +261,24 @@
 OverlayPanelLayer::OverlayPanelLayer(
     ui::ResourceManager* resource_manager)
     : resource_manager_(resource_manager),
-      layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
+      layer_(cc::Layer::Create(cc::LayerSettings())),
       panel_shadow_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
       bar_background_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       bar_text_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       bar_shadow_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       panel_icon_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       close_icon_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       content_view_container_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
-      text_container_(cc::Layer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
+      text_container_(cc::Layer::Create(cc::LayerSettings())),
       bar_border_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())) {
+          cc::SolidColorLayer::Create(cc::LayerSettings())) {
   layer_->SetMasksToBounds(false);
   layer_->SetIsDrawable(true);
 
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.cc b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
index a61779c8..ebe10b2e 100644
--- a/chrome/browser/android/compositor/layer/tab_handle_layer.cc
+++ b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
@@ -6,6 +6,7 @@
 
 #include "base/i18n/rtl.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/resources/scoped_ui_resource.h"
 #include "chrome/browser/android/compositor/decoration_title.h"
@@ -178,13 +179,13 @@
 
 TabHandleLayer::TabHandleLayer(LayerTitleCache* layer_title_cache)
     : layer_title_cache_(layer_title_cache),
-      layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
+      layer_(cc::Layer::Create(cc::LayerSettings())),
       close_button_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       decoration_tab_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
       border_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       brightness_(1.0f),
       foreground_(false) {
   decoration_tab_->SetIsDrawable(true);
diff --git a/chrome/browser/android/compositor/layer/tab_layer.cc b/chrome/browser/android/compositor/layer/tab_layer.cc
index f3f263eb..a33e085 100644
--- a/chrome/browser/android/compositor/layer/tab_layer.cc
+++ b/chrome/browser/android/compositor/layer/tab_layer.cc
@@ -7,6 +7,7 @@
 #include "base/i18n/rtl.h"
 #include "cc/layers/layer.h"
 #include "cc/layers/layer_lists.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/nine_patch_layer.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/layers/ui_resource_layer.h"
@@ -585,23 +586,23 @@
     : incognito_(incognito),
       resource_manager_(resource_manager),
       layer_title_cache_(layer_title_cache),
-      layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
+      layer_(cc::Layer::Create(cc::LayerSettings())),
       toolbar_layer_(ToolbarLayer::Create(resource_manager)),
-      title_(cc::Layer::Create(content::Compositor::LayerSettings())),
+      title_(cc::Layer::Create(cc::LayerSettings())),
       content_(ContentLayer::Create(tab_content_manager)),
       padding_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       close_button_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       front_border_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
       front_border_inner_shadow_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
       contour_shadow_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
-      shadow_(cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
+      shadow_(cc::NinePatchLayer::Create(cc::LayerSettings())),
       back_logo_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       brightness_(1.f) {
   layer_->AddChild(shadow_);
   layer_->AddChild(contour_shadow_);
diff --git a/chrome/browser/android/compositor/layer/thumbnail_layer.cc b/chrome/browser/android/compositor/layer/thumbnail_layer.cc
index 6be1445..1df0ea0 100644
--- a/chrome/browser/android/compositor/layer/thumbnail_layer.cc
+++ b/chrome/browser/android/compositor/layer/thumbnail_layer.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/android/compositor/layer/thumbnail_layer.h"
 
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "chrome/browser/android/thumbnail/thumbnail.h"
 #include "content/public/browser/android/compositor.h"
@@ -51,7 +52,7 @@
 
 ThumbnailLayer::ThumbnailLayer()
     : layer_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())) {
+          cc::UIResourceLayer::Create(cc::LayerSettings())) {
   layer_->SetIsDrawable(true);
 }
 
diff --git a/chrome/browser/android/compositor/layer/toolbar_layer.cc b/chrome/browser/android/compositor/layer/toolbar_layer.cc
index ea88538..692d6b01 100644
--- a/chrome/browser/android/compositor/layer/toolbar_layer.cc
+++ b/chrome/browser/android/compositor/layer/toolbar_layer.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/android/compositor/layer/toolbar_layer.h"
 
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/nine_patch_layer.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/layers/ui_resource_layer.h"
@@ -149,21 +150,21 @@
 
 ToolbarLayer::ToolbarLayer(ui::ResourceManager* resource_manager)
     : resource_manager_(resource_manager),
-      layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
+      layer_(cc::Layer::Create(cc::LayerSettings())),
       toolbar_background_layer_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       url_bar_background_layer_(
-          cc::NinePatchLayer::Create(content::Compositor::LayerSettings())),
+          cc::NinePatchLayer::Create(cc::LayerSettings())),
       bitmap_layer_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       progress_bar_layer_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       progress_bar_background_layer_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       anonymize_layer_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       debug_layer_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       brightness_(1.f) {
   toolbar_background_layer_->SetIsDrawable(true);
   layer_->AddChild(toolbar_background_layer_);
diff --git a/chrome/browser/android/compositor/scene_layer/scene_layer.cc b/chrome/browser/android/compositor/scene_layer/scene_layer.cc
index d81ea0c0..697134f 100644
--- a/chrome/browser/android/compositor/scene_layer/scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/scene_layer.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/android/compositor/scene_layer/scene_layer.h"
 
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "content/public/browser/android/compositor.h"
 #include "jni/SceneLayer_jni.h"
 
@@ -21,7 +22,7 @@
 SceneLayer::SceneLayer(JNIEnv* env, jobject jobj)
     : SceneLayer(env,
                  jobj,
-                 cc::Layer::Create(content::Compositor::LayerSettings())) {
+                 cc::Layer::Create(cc::LayerSettings())) {
 }
 
 SceneLayer::SceneLayer(JNIEnv* env,
diff --git a/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc
index 22af415..2058d6e 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.h"
 
 #include "base/android/jni_android.h"
+#include "cc/layers/layer_settings.h"
 #include "chrome/browser/android/compositor/layer/content_layer.h"
 #include "chrome/browser/android/compositor/layer/tab_layer.h"
 #include "chrome/browser/android/compositor/layer_title_cache.h"
@@ -24,7 +25,7 @@
       layer_title_cache_(nullptr),
       tab_content_manager_(nullptr),
       background_color_(SK_ColorWHITE),
-      own_tree_(cc::Layer::Create(content::Compositor::LayerSettings())) {
+      own_tree_(cc::Layer::Create(cc::LayerSettings())) {
   layer()->AddChild(own_tree_);
 }
 
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
index 28cd4103..48fd5c8b 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h"
 
 #include "base/android/jni_android.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/resources/scoped_ui_resource.h"
 #include "chrome/browser/android/compositor/layer/tab_handle_layer.h"
 #include "chrome/browser/android/compositor/layer_title_cache.h"
@@ -18,11 +19,11 @@
 TabStripSceneLayer::TabStripSceneLayer(JNIEnv* env, jobject jobj)
     : SceneLayer(env, jobj),
       tab_strip_layer_(
-          cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
+          cc::SolidColorLayer::Create(cc::LayerSettings())),
       new_tab_button_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       model_selector_button_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
+          cc::UIResourceLayer::Create(cc::LayerSettings())),
       background_tab_brightness_(1.f),
       brightness_(1.f),
       write_index_(0),
diff --git a/chrome/browser/android/data_usage/data_use_matcher.cc b/chrome/browser/android/data_usage/data_use_matcher.cc
index 21e435c..1be71a5 100644
--- a/chrome/browser/android/data_usage/data_use_matcher.cc
+++ b/chrome/browser/android/data_usage/data_use_matcher.cc
@@ -15,7 +15,7 @@
 #include "base/time/default_tick_clock.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
-#include "chrome/browser/android/data_usage/external_data_use_observer.h"
+#include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h"
 #include "third_party/re2/src/re2/re2.h"
 #include "url/gurl.h"
 
@@ -25,16 +25,14 @@
 
 DataUseMatcher::DataUseMatcher(
     const base::WeakPtr<DataUseTabModel>& data_use_tab_model,
-    const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
-    const base::WeakPtr<ExternalDataUseObserver>& external_data_use_observer,
+    const ExternalDataUseObserverBridge* external_data_use_observer_bridge,
     const base::TimeDelta& default_matching_rule_expiration_duration)
     : data_use_tab_model_(data_use_tab_model),
       default_matching_rule_expiration_duration_(
           default_matching_rule_expiration_duration),
       tick_clock_(new base::DefaultTickClock()),
-      io_task_runner_(io_task_runner),
-      external_data_use_observer_(external_data_use_observer) {
-  DCHECK(io_task_runner_);
+      external_data_use_observer_bridge_(external_data_use_observer_bridge) {
+  DCHECK(external_data_use_observer_bridge_);
 }
 
 DataUseMatcher::~DataUseMatcher() {}
@@ -92,14 +90,8 @@
   UMA_HISTOGRAM_COUNTS_100("DataUsage.MatchingRulesCount.Invalid",
                            invalid_rules);
 
-  DCHECK(io_task_runner_);
-
-  // Notify |external_data_use_observer_| if it should register as a data use
-  // observer.
-  io_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&ExternalDataUseObserver::ShouldRegisterAsDataUseObserver,
-                 external_data_use_observer_, !matching_rules_.empty()));
+  external_data_use_observer_bridge_->ShouldRegisterAsDataUseObserver(
+      !matching_rules_.empty());
 }
 
 bool DataUseMatcher::MatchesURL(const GURL& url, std::string* label) const {
@@ -149,12 +141,7 @@
 
 void DataUseMatcher::FetchMatchingRules() {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(io_task_runner_);
-
-  // Notify |external_data_use_observer_| to fetch the rules.
-  io_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&ExternalDataUseObserver::FetchMatchingRules,
-                            external_data_use_observer_));
+  external_data_use_observer_bridge_->FetchMatchingRules();
 }
 
 bool DataUseMatcher::HasValidRules() const {
diff --git a/chrome/browser/android/data_usage/data_use_matcher.h b/chrome/browser/android/data_usage/data_use_matcher.h
index 9d1a12c..f905ab09 100644
--- a/chrome/browser/android/data_usage/data_use_matcher.h
+++ b/chrome/browser/android/data_usage/data_use_matcher.h
@@ -18,7 +18,6 @@
 #include "chrome/browser/android/data_usage/data_use_tab_model.h"
 
 namespace base {
-class SingleThreadTaskRunner;
 class TickClock;
 }
 
@@ -32,7 +31,7 @@
 
 namespace android {
 
-class ExternalDataUseObserver;
+class ExternalDataUseObserverBridge;
 
 // DataUseMatcher stores the matching URL patterns and package names along with
 // the labels. It also provides functionality to get the matching label for a
@@ -41,8 +40,7 @@
  public:
   DataUseMatcher(
       const base::WeakPtr<DataUseTabModel>& data_use_tab_model,
-      const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
-      const base::WeakPtr<ExternalDataUseObserver>& external_data_use_observer,
+      const ExternalDataUseObserverBridge* external_data_use_observer_bridge,
       const base::TimeDelta& default_matching_rule_expiration_duration);
 
   ~DataUseMatcher();
@@ -67,7 +65,7 @@
                              std::string* label) const WARN_UNUSED_RESULT;
 
   // Fetches the matching rules asynchronously from
-  // |external_data_use_observer_|.
+  // |external_data_use_observer_bridge_|.
   void FetchMatchingRules();
 
   // Returns true if there is any valid matching rule.
@@ -137,12 +135,13 @@
 
   // TickClock used for obtaining the current time.
   scoped_ptr<base::TickClock> tick_clock_;
-  // |io_task_runner_| is used to call ExternalDataUseObserver methods on
-  // IO thread.
-  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
 
-  // |external_data_use_observer_| is notified when matching rules are fetched.
-  base::WeakPtr<ExternalDataUseObserver> external_data_use_observer_;
+  // Pointer to the ExternalDataUseObserverBridge owned by
+  // ExternalDataUseObserver. DataUseTabModel (owner of |this|) and
+  // ExternalDataUseObserverBridge are owned by ExternalDataUseObserver, and are
+  // destroyed in that order. So |external_data_use_observer_bridge_| is
+  // guaranteed to be non-null.
+  const ExternalDataUseObserverBridge* external_data_use_observer_bridge_;
 
   DISALLOW_COPY_AND_ASSIGN(DataUseMatcher);
 };
diff --git a/chrome/browser/android/data_usage/data_use_matcher_unittest.cc b/chrome/browser/android/data_usage/data_use_matcher_unittest.cc
index 318e519..df2631b 100644
--- a/chrome/browser/android/data_usage/data_use_matcher_unittest.cc
+++ b/chrome/browser/android/data_usage/data_use_matcher_unittest.cc
@@ -16,7 +16,7 @@
 #include "base/test/histogram_tester.h"
 #include "base/time/tick_clock.h"
 #include "base/time/time.h"
-#include "chrome/browser/android/data_usage/external_data_use_observer.h"
+#include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -56,6 +56,14 @@
   DISALLOW_COPY_AND_ASSIGN(NowTestTickClock);
 };
 
+class TestExternalDataUseObserverBridge
+    : public chrome::android::ExternalDataUseObserverBridge {
+ public:
+  TestExternalDataUseObserverBridge() {}
+  void FetchMatchingRules() const override {}
+  void ShouldRegisterAsDataUseObserver(bool should_register) const override{};
+};
+
 }  // namespace
 
 namespace chrome {
@@ -68,10 +76,10 @@
  public:
   DataUseMatcherTest()
       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+        external_data_use_observer_bridge_(
+            new TestExternalDataUseObserverBridge()),
         data_use_matcher_(base::WeakPtr<DataUseTabModel>(),
-                          content::BrowserThread::GetMessageLoopProxyForThread(
-                              content::BrowserThread::IO),
-                          base::WeakPtr<ExternalDataUseObserver>(),
+                          external_data_use_observer_bridge_.get(),
                           base::TimeDelta::FromSeconds(
                               kDefaultMatchingRuleExpirationDurationSeconds)) {}
 
@@ -93,6 +101,7 @@
 
  private:
   content::TestBrowserThreadBundle thread_bundle_;
+  scoped_ptr<ExternalDataUseObserverBridge> external_data_use_observer_bridge_;
   DataUseMatcher data_use_matcher_;
   DISALLOW_COPY_AND_ASSIGN(DataUseMatcherTest);
 };
diff --git a/chrome/browser/android/data_usage/data_use_tab_model.cc b/chrome/browser/android/data_usage/data_use_tab_model.cc
index 3920c647..e245bbc 100644
--- a/chrome/browser/android/data_usage/data_use_tab_model.cc
+++ b/chrome/browser/android/data_usage/data_use_tab_model.cc
@@ -149,16 +149,15 @@
 }
 
 void DataUseTabModel::InitOnUIThread(
-    const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
-    const base::WeakPtr<ExternalDataUseObserver>& external_data_use_observer) {
+    const ExternalDataUseObserverBridge* external_data_use_observer_bridge) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(io_task_runner);
+  DCHECK(external_data_use_observer_bridge);
 
   tick_clock_.reset(new base::DefaultTickClock());
-  data_use_matcher_.reset(new DataUseMatcher(
-      GetWeakPtr(), io_task_runner, external_data_use_observer,
-      GetDefaultMatchingRuleExpirationDuration()));
+  data_use_matcher_.reset(
+      new DataUseMatcher(GetWeakPtr(), external_data_use_observer_bridge,
+                         GetDefaultMatchingRuleExpirationDuration()));
 }
 
 void DataUseTabModel::OnNavigationEvent(SessionID::id_type tab_id,
@@ -265,6 +264,7 @@
     bool is_control_app_installed) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK_NE(is_control_app_installed_, is_control_app_installed);
+  DCHECK(data_use_matcher_);
 
   is_control_app_installed_ = is_control_app_installed;
   std::vector<std::string> empty;
diff --git a/chrome/browser/android/data_usage/data_use_tab_model.h b/chrome/browser/android/data_usage/data_use_tab_model.h
index d1680993..2d71ffa 100644
--- a/chrome/browser/android/data_usage/data_use_tab_model.h
+++ b/chrome/browser/android/data_usage/data_use_tab_model.h
@@ -13,7 +13,6 @@
 #include "base/containers/hash_tables.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
@@ -21,20 +20,19 @@
 #include "base/time/time.h"
 #include "chrome/browser/android/data_usage/tab_data_use_entry.h"
 #include "components/sessions/core/session_id.h"
+#include "url/gurl.h"
 
 namespace base {
 class SingleThreadTaskRunner;
 class TickClock;
 }
 
-class GURL;
-
 namespace chrome {
 
 namespace android {
 
 class DataUseMatcher;
-class ExternalDataUseObserver;
+class ExternalDataUseObserverBridge;
 
 // Models tracking and labeling of data usage within each Tab. Within each tab,
 // the model tracks the data use of a sequence of navigations in a "tracking
@@ -85,11 +83,13 @@
 
   DataUseTabModel();
 
-  // Initializes |this| on UI thread. |external_data_use_observer| is the weak
-  // pointer to ExternalDataUseObserver object that owns |this|.
+  // Initializes |this| on UI thread. |external_data_use_observer_bridge| is the
+  // pointer to ExternalDataUseObserverBridge object. DataUseTabModel and
+  // ExternalDataUseObserverBridge objects are owned by ExternalDataUseObserver
+  // and DataUseTabModel is destroyed first followed by
+  // ExternalDataUseObserverBridge.
   void InitOnUIThread(
-      const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
-      const base::WeakPtr<ExternalDataUseObserver>& external_data_use_observer);
+      const ExternalDataUseObserverBridge* external_data_use_observer_bridge);
 
   virtual ~DataUseTabModel();
 
diff --git a/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc b/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc
index 75f7e0b9..99af0ea 100644
--- a/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc
+++ b/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc
@@ -19,6 +19,7 @@
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/data_usage/data_use_matcher.h"
+#include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h"
 #include "chrome/browser/android/data_usage/tab_data_use_entry.h"
 #include "components/data_usage/core/data_use_aggregator.h"
 #include "components/data_usage/core/data_use_amortizer.h"
@@ -67,27 +68,33 @@
   MOCK_METHOD1(NotifyTrackingEnding, void(SessionID::id_type tab_id));
 };
 
+class TestExternalDataUseObserverBridge
+    : public chrome::android::ExternalDataUseObserverBridge {
+ public:
+  TestExternalDataUseObserverBridge() {}
+  void FetchMatchingRules() const override {}
+  void ShouldRegisterAsDataUseObserver(bool should_register) const override{};
+};
+
 }  // namespace
 
 namespace chrome {
 
 namespace android {
 
-class ExternalDataUseObserver;
-
 class DataUseTabModelTest : public testing::Test {
  public:
   DataUseTabModelTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
+      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+        external_data_use_observer_bridge_(
+            new TestExternalDataUseObserverBridge()) {}
 
  protected:
   void SetUp() override {
     base::RunLoop().RunUntilIdle();
     data_use_tab_model_.reset(new DataUseTabModel());
     data_use_tab_model_->InitOnUIThread(
-        content::BrowserThread::GetMessageLoopProxyForThread(
-            content::BrowserThread::IO),
-        base::WeakPtr<ExternalDataUseObserver>());
+        external_data_use_observer_bridge_.get());
 
     tick_clock_ = new base::SimpleTestTickClock();
 
@@ -189,6 +196,7 @@
 
  private:
   content::TestBrowserThreadBundle thread_bundle_;
+  scoped_ptr<ExternalDataUseObserverBridge> external_data_use_observer_bridge_;
 
   DISALLOW_COPY_AND_ASSIGN(DataUseTabModelTest);
 };
diff --git a/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc b/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc
index 13ae8f6..527c936 100644
--- a/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc
+++ b/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc
@@ -33,6 +33,8 @@
 const char kFooLabel[] = "foo_label";
 const char kFooPackage[] = "com.foo";
 
+}  // namespace
+
 class TestDataUseTabModel : public DataUseTabModel {
  public:
   TestDataUseTabModel() {}
@@ -48,10 +50,6 @@
       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
   DataUseUITabModel* data_use_ui_tab_model() { return &data_use_ui_tab_model_; }
 
-  ExternalDataUseObserver* external_data_use_observer() const {
-    return external_data_use_observer_.get();
-  }
-
   TestDataUseTabModel* data_use_tab_model() const {
     return data_use_tab_model_.get();
   }
@@ -80,7 +78,7 @@
 
     data_use_tab_model_.reset(new TestDataUseTabModel());
     data_use_tab_model_->InitOnUIThread(
-        io_task_runner_, external_data_use_observer_->GetWeakPtr());
+        external_data_use_observer_->external_data_use_observer_bridge_);
     data_use_ui_tab_model_.SetDataUseTabModel(data_use_tab_model_.get());
     data_use_tab_model_->OnControlAppInstallStateChange(true);
   }
@@ -95,8 +93,6 @@
   scoped_ptr<TestDataUseTabModel> data_use_tab_model_;
 };
 
-}  // namespace
-
 // Tests that DataUseTabModel is notified of tab closure and navigation events,
 // and DataUseTabModel notifies DataUseUITabModel.
 TEST_F(DataUseUITabModelTest, ReportTabEventsTest) {
diff --git a/chrome/browser/android/data_usage/external_data_use_observer.cc b/chrome/browser/android/data_usage/external_data_use_observer.cc
index a1dba79..210b5db 100644
--- a/chrome/browser/android/data_usage/external_data_use_observer.cc
+++ b/chrome/browser/android/data_usage/external_data_use_observer.cc
@@ -133,13 +133,13 @@
     const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
     const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
     : data_use_aggregator_(data_use_aggregator),
+      external_data_use_observer_bridge_(new ExternalDataUseObserverBridge()),
       data_use_tab_model_(new DataUseTabModel()),
       last_data_report_submitted_ticks_(base::TimeTicks()),
       pending_report_bytes_(0),
       ui_task_runner_(ui_task_runner),
       previous_report_time_(base::Time::Now()),
       last_matching_rules_fetch_time_(base::TimeTicks::Now()),
-      external_data_use_observer_bridge_(new ExternalDataUseObserverBridge()),
       total_bytes_buffered_(0),
       fetch_matching_rules_duration_(
           base::TimeDelta::FromSeconds(GetFetchMatchingRulesDurationSeconds())),
@@ -162,12 +162,11 @@
   ui_task_runner_->PostTask(FROM_HERE,
                             base::Bind(&DataUseTabModel::InitOnUIThread,
                                        base::Unretained(data_use_tab_model_),
-                                       io_task_runner, GetWeakPtr()));
+                                       external_data_use_observer_bridge_));
 
-  // Initialize the ExternalDataUseObserverBridge object. Initialization will
-  // also trigger the fetching of matching rules. It is okay to use
-  // base::Unretained here since |external_data_use_observer_bridge_| is
-  // owned by |this|, and is destroyed on UI thread when |this| is destroyed.
+  // Initialize the ExternalDataUseObserverBridge object. It is okay to use
+  // base::Unretained here since |external_data_use_observer_bridge_| is owned
+  // by |this|, and is destroyed on UI thread when |this| is destroyed.
   ui_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&ExternalDataUseObserverBridge::Init,
@@ -181,17 +180,18 @@
   if (registered_as_data_use_observer_)
     data_use_aggregator_->RemoveObserver(this);
 
+  // Delete |data_use_tab_model_| on the UI thread. |data_use_tab_model_| should
+  // be deleted before |external_data_use_observer_bridge_|.
+  if (!ui_task_runner_->DeleteSoon(FROM_HERE, data_use_tab_model_)) {
+    NOTIMPLEMENTED() << " DataUseTabModel was not deleted successfully";
+  }
+
   // Delete |external_data_use_observer_bridge_| on the UI thread.
   if (!ui_task_runner_->DeleteSoon(FROM_HERE,
                                    external_data_use_observer_bridge_)) {
     NOTIMPLEMENTED()
         << " ExternalDataUseObserverBridge was not deleted successfully";
   }
-
-  // Delete |data_use_tab_model_| on the UI thread.
-  if (!ui_task_runner_->DeleteSoon(FROM_HERE, data_use_tab_model_)) {
-    NOTIMPLEMENTED() << " DataUseTabModel was not deleted successfully";
-  }
 }
 
 void ExternalDataUseObserver::OnReportDataUseDone(bool success) {
diff --git a/chrome/browser/android/data_usage/external_data_use_observer.h b/chrome/browser/android/data_usage/external_data_use_observer.h
index ec9c92b..1e34b88 100644
--- a/chrome/browser/android/data_usage/external_data_use_observer.h
+++ b/chrome/browser/android/data_usage/external_data_use_observer.h
@@ -82,8 +82,8 @@
   // successfully submitted to the external data use observer by Java.
   void OnReportDataUseDone(bool success);
 
-  // Called by DataUseMatcher. |should_register| is true if |this| should
-  // register as a data use observer.
+  // Called by ExternalDataUseObserverBridge. |should_register| is true if
+  // |this| should register as a data use observer.
   void ShouldRegisterAsDataUseObserver(bool should_register);
 
   // Fetches the matching rules asynchronously.
@@ -93,6 +93,7 @@
 
  private:
   friend class DataUseTabModelTest;
+  friend class DataUseUITabModelTest;
   friend class ExternalDataUseObserverTest;
   FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, BufferDataUseReports);
   FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, BufferSize);
@@ -218,6 +219,11 @@
   // Aggregator that sends data use observations to |this|.
   data_usage::DataUseAggregator* data_use_aggregator_;
 
+  // |external_data_use_observer_bridge_| is owned by |this|, and interacts with
+  // the Java code. It is created on IO thread but afterwards, should only be
+  // accessed on UI thread.
+  ExternalDataUseObserverBridge* external_data_use_observer_bridge_;
+
   // Maintains tab sessions and is owned by |this|. It is created on IO thread
   // but afterwards, should only be accessed on UI thread.
   DataUseTabModel* data_use_tab_model_;
@@ -244,11 +250,6 @@
   // Time when the matching rules were last fetched.
   base::TimeTicks last_matching_rules_fetch_time_;
 
-  // |external_data_use_observer_bridge_| is owned by |this|, and interacts with
-  // the Java code. It is created on IO thread but afterwards, should only be
-  // accessed on UI thread.
-  ExternalDataUseObserverBridge* external_data_use_observer_bridge_;
-
   // Total number of bytes transmitted or received across all the buffered
   // reports.
   int64_t total_bytes_buffered_;
diff --git a/chrome/browser/android/data_usage/external_data_use_observer_bridge.cc b/chrome/browser/android/data_usage/external_data_use_observer_bridge.cc
index 63e4966..9ef7a35a 100644
--- a/chrome/browser/android/data_usage/external_data_use_observer_bridge.cc
+++ b/chrome/browser/android/data_usage/external_data_use_observer_bridge.cc
@@ -172,7 +172,19 @@
     jobject obj,
     bool is_control_app_installed) const {
   DCHECK(thread_checker_.CalledOnValidThread());
-  data_use_tab_model_->OnControlAppInstallStateChange(is_control_app_installed);
+  if (data_use_tab_model_) {
+    data_use_tab_model_->OnControlAppInstallStateChange(
+        is_control_app_installed);
+  }
+}
+
+void ExternalDataUseObserverBridge::ShouldRegisterAsDataUseObserver(
+    bool should_register) const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  io_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&ExternalDataUseObserver::ShouldRegisterAsDataUseObserver,
+                 external_data_use_observer_, should_register));
 }
 
 bool RegisterExternalDataUseObserver(JNIEnv* env) {
diff --git a/chrome/browser/android/data_usage/external_data_use_observer_bridge.h b/chrome/browser/android/data_usage/external_data_use_observer_bridge.h
index da3b8f1..8e8a0c8 100644
--- a/chrome/browser/android/data_usage/external_data_use_observer_bridge.h
+++ b/chrome/browser/android/data_usage/external_data_use_observer_bridge.h
@@ -39,7 +39,7 @@
 class ExternalDataUseObserverBridge {
  public:
   ExternalDataUseObserverBridge();
-  ~ExternalDataUseObserverBridge();
+  virtual ~ExternalDataUseObserverBridge();
 
   // Initializes |this| on UI thread by constructing the
   // |j_external_data_use_observer_|, and fetches matching rules from
@@ -51,7 +51,7 @@
   // Fetches matching rules from Java. Returns result asynchronously via
   // FetchMatchingRulesDone. FetchMatchingRules should not be called if a
   // fetch to matching rules is already in progress.
-  void FetchMatchingRules() const;
+  virtual void FetchMatchingRules() const;
 
   // Called by Java when new matching rules have been fetched.
   // |app_package_name| is the package name of the app that should be matched.
@@ -93,6 +93,10 @@
                                       jobject obj,
                                       bool is_control_app_installed) const;
 
+  // Called by DataUseMatcher to notify |external_data_use_observer_| if it
+  // should register as a data use observer.
+  virtual void ShouldRegisterAsDataUseObserver(bool should_register) const;
+
  private:
   // Java listener that provides regular expressions to |this|. Data use
   // reports are submitted to |j_external_data_use_observer_|.
@@ -103,6 +107,7 @@
   base::WeakPtr<ExternalDataUseObserver> external_data_use_observer_;
 
   // |data_use_tab_model_| is notified of the matching rules on UI thread.
+  // |data_use_tab_model_| may be null.
   base::WeakPtr<DataUseTabModel> data_use_tab_model_;
 
   // The construction time of |this|.
diff --git a/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc b/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
index 5768b3f..ae69a61d 100644
--- a/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
+++ b/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
@@ -389,47 +389,57 @@
 // control app is not installed  or if more than zero valid rules have been
 // fetched.
 TEST_F(ExternalDataUseObserverTest, MatchingRuleFetchOnControlAppInstall) {
-  // Matching rules not fetched on navigation if control app is not installed.
-  external_data_use_observer()->last_matching_rules_fetch_time_ =
-      base::TimeTicks();
-  external_data_use_observer()->data_use_tab_model_->is_control_app_installed_ =
-      false;
-  external_data_use_observer()->data_use_tab_model_->OnNavigationEvent(
-      kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL),
-      std::string());
-  EXPECT_TRUE(
-      external_data_use_observer()->last_matching_rules_fetch_time_.is_null());
+  {
+    // Matching rules not fetched on navigation if control app is not installed.
+    external_data_use_observer()->last_matching_rules_fetch_time_ =
+        base::TimeTicks();
+    external_data_use_observer()
+        ->data_use_tab_model_->is_control_app_installed_ = false;
+    base::HistogramTester histogram_tester;
+    external_data_use_observer()->data_use_tab_model_->OnNavigationEvent(
+        kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL),
+        std::string());
+    base::RunLoop().RunUntilIdle();
+    histogram_tester.ExpectTotalCount("DataUsage.MatchingRulesCount.Valid", 0);
+  }
 
-  // Matching rules are fetched when control app is installed.
-  external_data_use_observer()
-      ->data_use_tab_model_->OnControlAppInstallStateChange(true);
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(
-      external_data_use_observer()->last_matching_rules_fetch_time_.is_null());
+  {
+    // Matching rules are fetched when control app is installed.
+    base::HistogramTester histogram_tester;
+    external_data_use_observer()
+        ->data_use_tab_model_->OnControlAppInstallStateChange(true);
+    base::RunLoop().RunUntilIdle();
+    histogram_tester.ExpectTotalCount("DataUsage.MatchingRulesCount.Valid", 1);
+  }
 
-  // Matching rules fetched on every navigation if control app is installed and
-  // zero rules are available.
-  external_data_use_observer()->last_matching_rules_fetch_time_ =
-      base::TimeTicks();
-  external_data_use_observer()->data_use_tab_model_->OnNavigationEvent(
-      kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL),
-      std::string());
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(
-      external_data_use_observer()->last_matching_rules_fetch_time_.is_null());
+  {
+    // Matching rules fetched on every navigation if control app is installed
+    // and zero rules are available.
+    external_data_use_observer()->last_matching_rules_fetch_time_ =
+        base::TimeTicks();
+    base::HistogramTester histogram_tester;
+    external_data_use_observer()->data_use_tab_model_->OnNavigationEvent(
+        kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL),
+        std::string());
+    base::RunLoop().RunUntilIdle();
+    histogram_tester.ExpectTotalCount("DataUsage.MatchingRulesCount.Valid", 1);
+  }
 
-  // Matching rules not fetched on navigation if control app is installed and
-  // more than zero rules are available.
-  AddDefaultMatchingRule();
-  external_data_use_observer()->last_matching_rules_fetch_time_ =
-      base::TimeTicks();
-  EXPECT_TRUE(
-      external_data_use_observer()->last_matching_rules_fetch_time_.is_null());
-  external_data_use_observer()->data_use_tab_model_->OnNavigationEvent(
-      kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL),
-      std::string());
-  EXPECT_TRUE(
-      external_data_use_observer()->last_matching_rules_fetch_time_.is_null());
+  {
+    // Matching rules not fetched on navigation if control app is installed and
+    // more than zero rules are available.
+    AddDefaultMatchingRule();
+    external_data_use_observer()->last_matching_rules_fetch_time_ =
+        base::TimeTicks();
+    EXPECT_TRUE(external_data_use_observer()
+                    ->last_matching_rules_fetch_time_.is_null());
+    base::HistogramTester histogram_tester;
+    external_data_use_observer()->data_use_tab_model_->OnNavigationEvent(
+        kDefaultTabId, DataUseTabModel::TRANSITION_LINK, GURL(kDefaultURL),
+        std::string());
+    base::RunLoop().RunUntilIdle();
+    histogram_tester.ExpectTotalCount("DataUsage.MatchingRulesCount.Valid", 0);
+  }
 }
 
 // Tests if data use reports are sent only after the total bytes sent/received
@@ -594,6 +604,8 @@
 
   // Create another ExternalDataUseObserver object.
   ReplaceExternalDataUseObserver(variation_params);
+  histogram_tester.ExpectTotalCount(kUMAMatchingRuleFirstFetchDurationHistogram,
+                                    0);
 
   // Trigger the control app install, and matching rules will be fetched.
   external_data_use_observer()
diff --git a/chrome/browser/android/dev_tools_server.cc b/chrome/browser/android/dev_tools_server.cc
index 0d05398..fcd5dd67 100644
--- a/chrome/browser/android/dev_tools_server.cc
+++ b/chrome/browser/android/dev_tools_server.cc
@@ -225,7 +225,7 @@
 }
 
 bool DevToolsServer::IsStarted() const {
-  return devtools_http_handler_;
+  return !!devtools_http_handler_;
 }
 
 bool RegisterDevToolsServer(JNIEnv* env) {
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
index b591905..8264846 100644
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/histogram.h"
 #include "base/trace_event/trace_event.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "chrome/browser/android/compositor/tab_content_manager.h"
 #include "chrome/browser/android/metrics/uma_utils.h"
 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
@@ -121,7 +122,7 @@
 
 TabAndroid::TabAndroid(JNIEnv* env, jobject obj)
     : weak_java_tab_(env, obj),
-      content_layer_(cc::Layer::Create(content::Compositor::LayerSettings())),
+      content_layer_(cc::Layer::Create(cc::LayerSettings())),
       tab_content_manager_(NULL),
       synced_tab_delegate_(new browser_sync::SyncedTabDelegateAndroid(this)) {
   Java_Tab_setNativePtr(env, obj, reinterpret_cast<intptr_t>(this));
diff --git a/chrome/browser/android/webapps/webapp_registry.cc b/chrome/browser/android/webapps/webapp_registry.cc
index 588e3ad..f021511 100644
--- a/chrome/browser/android/webapps/webapp_registry.cc
+++ b/chrome/browser/android/webapps/webapp_registry.cc
@@ -13,9 +13,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "jni/WebappRegistry_jni.h"
 
-// static
-void WebappRegistry::UnregisterWebapps(
-    const base::Closure& callback) {
+void WebappRegistry::UnregisterWebapps(const base::Closure& callback) {
   JNIEnv* env = base::android::AttachCurrentThread();
   uintptr_t callback_pointer = reinterpret_cast<uintptr_t>(
       new base::Closure(callback));
@@ -28,7 +26,7 @@
 
 // Callback used by Java when all web apps have been unregistered.
 void OnWebappsUnregistered(JNIEnv* env,
-                           const JavaParamRef<jclass>& klass,
+                           const JavaParamRef<jclass>& clazz,
                            jlong jcallback) {
   base::Closure* callback = reinterpret_cast<base::Closure*>(jcallback);
   callback->Run();
diff --git a/chrome/browser/android/webapps/webapp_registry.h b/chrome/browser/android/webapps/webapp_registry.h
index 26357bc..2d0a2cb 100644
--- a/chrome/browser/android/webapps/webapp_registry.h
+++ b/chrome/browser/android/webapps/webapp_registry.h
@@ -12,18 +12,22 @@
 
 // WebappRegistry is the C++ counterpart of
 // org.chromium.chrome.browser.webapp's WebappRegistry in Java.
+// All methods in this class which make JNI calls should be declared virtual and
+// mocked out in C++ unit tests. The JNI call cannot be made in this environment
+// as the Java side will not be initialised.
 class WebappRegistry {
  public:
+  WebappRegistry() { }
+  virtual ~WebappRegistry() { }
+
   // Registers JNI hooks.
   static bool RegisterWebappRegistry(JNIEnv* env);
 
   // Cleans up data stored by web apps.
-  static void UnregisterWebapps(const base::Closure& callback);
+  virtual void UnregisterWebapps(const base::Closure& callback);
 
  private:
-  ~WebappRegistry() = delete;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(WebappRegistry);
+  DISALLOW_COPY_AND_ASSIGN(WebappRegistry);
 };
 
 #endif  // CHROME_BROWSER_ANDROID_WEBAPPS_WEBAPP_REGISTRY_H_
diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc
index a07aab0..0749c86 100644
--- a/chrome/browser/browsing_data/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover.cc
@@ -301,6 +301,9 @@
       is_removing_(false),
       main_context_getter_(browser_context->GetRequestContext()),
       media_context_getter_(browser_context->GetMediaRequestContext()),
+#if BUILDFLAG(ANDROID_JAVA_UI)
+      webapp_registry_(new WebappRegistry()),
+#endif
       weak_ptr_factory_(this) {
   DCHECK(browser_context);
 }
@@ -927,7 +930,7 @@
 #if BUILDFLAG(ANDROID_JAVA_UI)
   if (remove_mask & REMOVE_WEBAPP_DATA) {
     waiting_for_clear_webapp_data_ = true;
-    WebappRegistry::UnregisterWebapps(
+    webapp_registry_->UnregisterWebapps(
         base::Bind(&BrowsingDataRemover::OnClearedWebappData,
                    weak_ptr_factory_.GetWeakPtr()));
   }
@@ -969,6 +972,13 @@
   storage_partition_for_testing_ = storage_partition;
 }
 
+#if BUILDFLAG(ANDROID_JAVA_UI)
+void BrowsingDataRemover::OverrideWebappRegistryForTesting(
+    scoped_ptr<WebappRegistry> webapp_registry) {
+  webapp_registry_.reset(webapp_registry.release());
+}
+#endif
+
 base::Time BrowsingDataRemover::CalculateBeginDeleteTime(
     TimePeriod time_period) {
   base::TimeDelta diff;
diff --git a/chrome/browser/browsing_data/browsing_data_remover.h b/chrome/browser/browsing_data/browsing_data_remover.h
index f0c7432..fc2dfd9d 100644
--- a/chrome/browser/browsing_data/browsing_data_remover.h
+++ b/chrome/browser/browsing_data/browsing_data_remover.h
@@ -52,6 +52,10 @@
 class URLRequestContextGetter;
 }
 
+#if BUILDFLAG(ANDROID_JAVA_UI)
+class WebappRegistry;
+#endif
+
 // BrowsingDataRemover is responsible for removing data related to browsing:
 // visits in url database, downloads, cookies ...
 class BrowsingDataRemover : public KeyedService
@@ -253,6 +257,11 @@
   void OverrideStoragePartitionForTesting(
       content::StoragePartition* storage_partition);
 
+#if BUILDFLAG(ANDROID_JAVA_UI)
+  void OverrideWebappRegistryForTesting(
+      scoped_ptr<WebappRegistry> webapp_registry);
+#endif
+
  private:
   // The clear API needs to be able to toggle removing_ in order to test that
   // only one BrowsingDataRemover instance can be called at a time.
@@ -472,6 +481,12 @@
   // We do not own this.
   content::StoragePartition* storage_partition_for_testing_ = nullptr;
 
+#if BUILDFLAG(ANDROID_JAVA_UI)
+  // WebappRegistry makes calls across the JNI. In unit tests, the Java side is
+  // not initialised, so the registry must be mocked out.
+  scoped_ptr<WebappRegistry> webapp_registry_;
+#endif
+
   base::WeakPtrFactory<BrowsingDataRemover> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemover);
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 223fd0c..a9665474 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -76,6 +76,10 @@
 #include "ui/gfx/favicon_size.h"
 #include "url/origin.h"
 
+#if BUILDFLAG(ANDROID_JAVA_UI)
+#include "chrome/browser/android/webapps/webapp_registry.h"
+#endif
+
 #if defined(OS_CHROMEOS)
 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
@@ -260,6 +264,19 @@
   DISALLOW_COPY_AND_ASSIGN(TestStoragePartition);
 };
 
+#if BUILDFLAG(ANDROID_JAVA_UI)
+class TestWebappRegistry : public WebappRegistry {
+ public:
+  TestWebappRegistry() : WebappRegistry() { }
+
+  void UnregisterWebapps(const base::Closure& callback) override {
+    // Mocks out a JNI call and runs the callback as a delayed task.
+    BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, callback,
+                                   base::TimeDelta::FromMilliseconds(10));
+  }
+};
+#endif
+
 // Custom matcher to test the equivalence of two URL filters. Since those are
 // blackbox predicates, we can only approximate the equivalence by testing
 // whether the filter give the same answer for several URLs. This is currently
@@ -942,6 +959,13 @@
         BrowsingDataRemover::RegisterOnBrowsingDataRemovedCallback(
             base::Bind(&BrowsingDataRemoverTest::NotifyWithDetails,
                        base::Unretained(this)));
+
+#if BUILDFLAG(ANDROID_JAVA_UI)
+    BrowsingDataRemover* remover =
+        BrowsingDataRemoverFactory::GetForBrowserContext(profile_.get());
+    remover->OverrideWebappRegistryForTesting(
+        scoped_ptr<WebappRegistry>(new TestWebappRegistry()));
+#endif
   }
 
   ~BrowsingDataRemoverTest() override {}
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 086d2bc..e5b6c8e 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -39,6 +39,19 @@
   StartTest();
 }
 
+// Test fixture class for details panel.
+// TODO(ryoh): remove after we release details panel feature.
+class FileManagerDetailsPanelBrowserTest : public FileManagerBrowserTest {
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    FileManagerBrowserTestBase::SetUpCommandLine(command_line);
+    command_line->AppendSwitch("--enable-files-details-panel");
+  }
+};
+
+IN_PROC_BROWSER_TEST_P(FileManagerDetailsPanelBrowserTest, Test) {
+  StartTest();
+}
+
 // Unlike TEST/TEST_F, which are macros that expand to further macros,
 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
 // stringizes the arguments. As a result, macros passed as parameters (such as
@@ -167,6 +180,13 @@
                       "deleteMenuItemIsDisabledWhenNoItemIsSelected"),
         TestParameter(NOT_IN_GUEST_MODE, "deleteOneItemFromToolbar")));
 
+WRAPPED_INSTANTIATE_TEST_CASE_P(
+    DetailsPanel,
+    FileManagerDetailsPanelBrowserTest,
+    ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openDetailsPanel"),
+                      TestParameter(NOT_IN_GUEST_MODE,
+                                    "openDetailsPanelForSingleFile")));
+
 #if defined(DISABLE_SLOW_FILESAPP_TESTS)
 #define MAYBE_DirectoryTreeContextMenu DISABLED_DirectoryTreeContextMenu
 #else
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc b/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc
index dc0e911..d8fa49d 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_loader.cc
@@ -45,8 +45,12 @@
 };
 
 // Crops |image| to the square format and downsizes the image to
-// |target_size| in pixels.
-SkBitmap CropImage(const SkBitmap& image, int target_size) {
+// |target_size| in pixels. On success, returns true and stores the cropped
+// image in |bitmap| and the bytes representation in |byytes|.
+bool CropImage(const SkBitmap& image,
+               int target_size,
+               SkBitmap* bitmap,
+               user_manager::UserImage::Bytes* bytes) {
   DCHECK_GT(target_size, 0);
 
   SkBitmap final_image;
@@ -64,7 +68,16 @@
   } else {
     final_image = cropped_image;
   }
-  return final_image;
+
+  // Encode the cropped image to web-compatible bytes representation
+  scoped_ptr<user_manager::UserImage::Bytes> encoded =
+      user_manager::UserImage::Encode(final_image);
+  if (!encoded)
+    return false;
+
+  bitmap->swap(final_image);
+  bytes->swap(*encoded);
+  return true;
 }
 
 // Handles the decoded image returned from ImageDecoder through the
@@ -85,8 +98,16 @@
   void OnImageDecoded(const SkBitmap& decoded_image) override;
   void OnDecodeImageFailed() override;
 
-  // Called after the image is transformed (cropped and downsized) as needed.
-  void OnImageFinalized(const SkBitmap& image);
+  // Called after the image is cropped (and downsized) as needed.
+  void OnImageCropped(SkBitmap* bitmap,
+                      user_manager::UserImage::Bytes* bytes,
+                      bool succeeded);
+
+  // Called after the image is finalized. |image_bytes_regenerated| is true
+  // if |image_bytes| is regenerated from the cropped image.
+  void OnImageFinalized(const SkBitmap& image,
+                        const user_manager::UserImage::Bytes& image_bytes,
+                        bool image_bytes_regenerated);
 
  private:
   const ImageInfo image_info_;
@@ -100,19 +121,38 @@
 void UserImageRequest::OnImageDecoded(const SkBitmap& decoded_image) {
   int target_size = image_info_.pixels_per_side;
   if (target_size > 0) {
-    // Transforming an image could be expensive, hence posting to the
-    // background thread.
+    // Cropping an image could be expensive, hence posting to the background
+    // thread.
+    SkBitmap* bitmap = new SkBitmap;
+    user_manager::UserImage::Bytes* bytes = new user_manager::UserImage::Bytes;
     base::PostTaskAndReplyWithResult(
         background_task_runner_.get(), FROM_HERE,
-        base::Bind(&CropImage, decoded_image, target_size),
-        base::Bind(&UserImageRequest::OnImageFinalized,
-                   weak_ptr_factory_.GetWeakPtr()));
+        base::Bind(&CropImage, decoded_image, target_size, bitmap, bytes),
+        base::Bind(&UserImageRequest::OnImageCropped,
+                   weak_ptr_factory_.GetWeakPtr(), base::Owned(bitmap),
+                   base::Owned(bytes)));
   } else {
-    OnImageFinalized(decoded_image);
+    OnImageFinalized(decoded_image, image_data_,
+                     false /* image_bytes_regenerated */);
   }
 }
 
-void UserImageRequest::OnImageFinalized(const SkBitmap& image) {
+void UserImageRequest::OnImageCropped(SkBitmap* bitmap,
+                                      user_manager::UserImage::Bytes* bytes,
+                                      bool succeeded) {
+  DCHECK_GT(image_info_.pixels_per_side, 0);
+
+  if (!succeeded) {
+    OnDecodeImageFailed();
+    return;
+  }
+  OnImageFinalized(*bitmap, *bytes, true /* image_bytes_regenerated */);
+}
+
+void UserImageRequest::OnImageFinalized(
+    const SkBitmap& image,
+    const user_manager::UserImage::Bytes& image_bytes,
+    bool image_bytes_regenerated) {
   SkBitmap final_image = image;
   // Make the SkBitmap immutable as we won't modify it. This is important
   // because otherwise it gets duplicated during painting, wasting memory.
@@ -120,9 +160,10 @@
   gfx::ImageSkia final_image_skia =
       gfx::ImageSkia::CreateFrom1xBitmap(final_image);
   final_image_skia.MakeThreadSafe();
-  user_manager::UserImage user_image(final_image_skia, image_data_);
+  user_manager::UserImage user_image(final_image_skia, image_bytes);
   user_image.set_file_path(image_info_.file_path);
-  if (image_info_.image_codec == ImageDecoder::ROBUST_JPEG_CODEC)
+  if (image_info_.image_codec == ImageDecoder::ROBUST_JPEG_CODEC ||
+      image_bytes_regenerated)
     user_image.MarkAsSafe();
   image_info_.loaded_cb.Run(user_image);
   delete this;
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
index d702cabe..9d48c4d6 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
@@ -150,23 +150,27 @@
 
 bool SaveImage(const user_manager::UserImage& user_image,
                const base::FilePath& image_path) {
-  user_manager::UserImage safe_image;
-  const user_manager::UserImage::Bytes* encoded_image = NULL;
+  // This should always be true, because of the following reasons:
+  //
+  // 1) Profile image from Google account -> UserImage is created with
+  //    CreateAndEncode() that generates safe bytes representation.
+  // 2) Profile image from user-specified image -> The bytes representation
+  //    is regenerated after the original image is decoded and cropped.
+  // 3) Profile image from policy (via OnExternalDataFetched()) -> JPEG is
+  //    only allowed and ROBUST_JPEG_CODEC is used.
+  //
+  // However, check the value just in case because an unsafe image should
+  // never be saved.
   if (!user_image.is_safe_format()) {
-    safe_image = user_manager::UserImage::CreateAndEncode(user_image.image());
-    encoded_image = &safe_image.image_bytes();
-    UMA_HISTOGRAM_MEMORY_KB("UserImage.RecodedJpegSize", encoded_image->size());
-  } else if (user_image.has_image_bytes()) {
-    encoded_image = &user_image.image_bytes();
-  } else {
-    NOTREACHED() << "image data bytes missing.";
+    LOG(ERROR) << "User image is not in safe format";
     return false;
   }
 
-  if (!encoded_image->size() ||
+  const user_manager::UserImage::Bytes& image_bytes = user_image.image_bytes();
+  if (image_bytes.empty() ||
       base::WriteFile(image_path,
-                      reinterpret_cast<const char*>(&(*encoded_image)[0]),
-                      encoded_image->size()) == -1) {
+                      reinterpret_cast<const char*>(image_bytes.data()),
+                      image_bytes.size()) == -1) {
     LOG(ERROR) << "Failed to save image to file.";
     return false;
   }
diff --git a/chrome/browser/chromeos/net/cert_verify_proc_chromeos_unittest.cc b/chrome/browser/chromeos/net/cert_verify_proc_chromeos_unittest.cc
index 4f268c6..7925cb2 100644
--- a/chrome/browser/chromeos/net/cert_verify_proc_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/net/cert_verify_proc_chromeos_unittest.cc
@@ -65,14 +65,14 @@
     ASSERT_TRUE(certs_1_[0]->Equals(certs_2_[0].get()));
     ASSERT_TRUE(certs_1_[1]->Equals(certs_2_[1].get()));
     ASSERT_FALSE(certs_1_[2]->Equals(certs_2_[2].get()));
-    ASSERT_EQ("C CA", certs_1_[2]->subject().common_name);
-    ASSERT_EQ("C CA", certs_2_[2]->subject().common_name);
+    ASSERT_EQ("C CA - Multi-root", certs_1_[2]->subject().common_name);
+    ASSERT_EQ("C CA - Multi-root", certs_2_[2]->subject().common_name);
 
     root_1_.push_back(certs_1_.back());
     root_2_.push_back(certs_2_.back());
 
-    ASSERT_EQ("D Root CA", root_1_[0]->subject().common_name);
-    ASSERT_EQ("E Root CA", root_2_[0]->subject().common_name);
+    ASSERT_EQ("D Root CA - Multi-root", root_1_[0]->subject().common_name);
+    ASSERT_EQ("E Root CA - Multi-root", root_2_[0]->subject().common_name);
   }
 
   int VerifyWithAdditionalTrustAnchors(
@@ -144,7 +144,7 @@
             Verify(verify_proc_default_.get(), server.get(), &verify_root));
   // User 1 should now verify successfully through the D root.
   EXPECT_EQ(net::OK, Verify(verify_proc_1_.get(), server.get(), &verify_root));
-  EXPECT_EQ("CN=D Root CA", verify_root);
+  EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
   // User 2 should still fail.
   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
             Verify(verify_proc_2_.get(), server.get(), &verify_root));
@@ -160,10 +160,10 @@
             Verify(verify_proc_default_.get(), server.get(), &verify_root));
   // User 1 should still verify successfully through the D root.
   EXPECT_EQ(net::OK, Verify(verify_proc_1_.get(), server.get(), &verify_root));
-  EXPECT_EQ("CN=D Root CA", verify_root);
+  EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
   // User 2 should now verify successfully through the E root.
   EXPECT_EQ(net::OK, Verify(verify_proc_2_.get(), server.get(), &verify_root));
-  EXPECT_EQ("CN=E Root CA", verify_root);
+  EXPECT_EQ("CN=E Root CA - Multi-root", verify_root);
 
   // Delete D root.
   EXPECT_TRUE(db_1_->DeleteCertAndKey(root_1_[0].get()));
@@ -174,7 +174,7 @@
             Verify(verify_proc_1_.get(), server.get(), &verify_root));
   // User 2 should still verify successfully through the E root.
   EXPECT_EQ(net::OK, Verify(verify_proc_2_.get(), server.get(), &verify_root));
-  EXPECT_EQ("CN=E Root CA", verify_root);
+  EXPECT_EQ("CN=E Root CA - Multi-root", verify_root);
 
   // Delete E root.
   EXPECT_TRUE(db_2_->DeleteCertAndKey(root_2_[0].get()));
@@ -219,13 +219,13 @@
                                              additional_trust_anchors,
                                              server.get(),
                                              &verify_root));
-  EXPECT_EQ("CN=D Root CA", verify_root);
+  EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
   EXPECT_EQ(net::OK,
             VerifyWithAdditionalTrustAnchors(verify_proc_1_.get(),
                                              additional_trust_anchors,
                                              server.get(),
                                              &verify_root));
-  EXPECT_EQ("CN=D Root CA", verify_root);
+  EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
   // User 2 should still fail.
   EXPECT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
             VerifyWithAdditionalTrustAnchors(verify_proc_2_.get(),
@@ -262,19 +262,19 @@
                                              additional_trust_anchors,
                                              server.get(),
                                              &verify_root));
-  EXPECT_EQ("CN=D Root CA", verify_root);
+  EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
   EXPECT_EQ(net::OK,
             VerifyWithAdditionalTrustAnchors(verify_proc_1_.get(),
                                              additional_trust_anchors,
                                              server.get(),
                                              &verify_root));
-  EXPECT_EQ("CN=D Root CA", verify_root);
+  EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
   EXPECT_EQ(net::OK,
             VerifyWithAdditionalTrustAnchors(verify_proc_2_.get(),
                                              additional_trust_anchors,
                                              server.get(),
                                              &verify_root));
-  EXPECT_EQ("CN=D Root CA", verify_root);
+  EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
 }
 
 class CertVerifyProcChromeOSOrderingTest
@@ -355,13 +355,13 @@
           EXPECT_EQ(expected_user1_result,
                     Verify(verify_proc_1_.get(), server.get(), &verify_root));
           if (expected_user1_result == net::OK)
-            EXPECT_EQ("CN=D Root CA", verify_root);
+            EXPECT_EQ("CN=D Root CA - Multi-root", verify_root);
           break;
         case '2':
           EXPECT_EQ(expected_user2_result,
                     Verify(verify_proc_2_.get(), server.get(), &verify_root));
           if (expected_user2_result == net::OK)
-            EXPECT_EQ("CN=E Root CA", verify_root);
+            EXPECT_EQ("CN=E Root CA - Multi-root", verify_root);
           break;
         default:
           FAIL();
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
index 3e0d695..d6cf238 100644
--- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -11,6 +11,7 @@
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/policy/device_local_account.h"
@@ -850,6 +851,27 @@
         DecodeIntegerValue(container.display_rotation_default()).release(),
         nullptr);
   }
+
+  if (policy.has_usb_detachable_whitelist()) {
+    const em::UsbDetachableWhitelistProto& container(
+        policy.usb_detachable_whitelist());
+    base::ListValue* whitelist = new base::ListValue();
+    RepeatedPtrField<em::UsbDeviceIdProto>::const_iterator entry;
+    for (entry = container.id().begin(); entry != container.id().end();
+         ++entry) {
+      base::DictionaryValue* ids = new base::DictionaryValue();
+      if (entry->has_vendor_id()) {
+        ids->SetString("vid", base::StringPrintf("%04X", entry->vendor_id()));
+      }
+      if (entry->has_product_id()) {
+        ids->SetString("pid", base::StringPrintf("%04X", entry->product_id()));
+      }
+      whitelist->Append(ids);
+    }
+    policies->Set(key::kUsbDetachableWhitelist, POLICY_LEVEL_MANDATORY,
+                  POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, whitelist,
+                  nullptr);
+  }
 }
 
 }  // namespace
diff --git a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
index a6eacb6..3526c27 100644
--- a/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
+++ b/chrome/browser/chromeos/policy/proto/chrome_device_policy.proto
@@ -667,6 +667,21 @@
   optional LoginBehavior login_authentication_behavior = 1 [default = GAIA];
 }
 
+// Identifiers of a USB device or device family.
+message UsbDeviceIdProto {
+  // USB Vendor Identifier (aka idVendor).
+  optional int32 vendor_id = 1;
+  // USB Product Identifier (aka idProduct).
+  optional int32 product_id = 2;
+}
+
+// This setting contains the list of USB devices to detach from the kernel
+// drivers in order to use them in web applications.
+// The list is used by the permission_broker daemon.
+message UsbDetachableWhitelistProto {
+  repeated UsbDeviceIdProto id = 1;
+}
+
 message ChromeDeviceSettingsProto {
   optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1;
   optional UserWhitelistProto user_whitelist = 2;
@@ -714,4 +729,5 @@
   optional AllowKioskAppControlChromeVersionProto
       allow_kiosk_app_control_chrome_version = 40;
   optional LoginAuthenticationBehaviorProto login_authentication_behavior = 41;
+  optional UsbDetachableWhitelistProto usb_detachable_whitelist = 42;
 }
diff --git a/chrome/browser/data_saver/data_saver_browsertest.cc b/chrome/browser/data_saver/data_saver_browsertest.cc
index 3c8e38264c..0929030 100644
--- a/chrome/browser/data_saver/data_saver_browsertest.cc
+++ b/chrome/browser/data_saver/data_saver_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -14,6 +15,8 @@
 #include "content/public/test/browser_test_base.h"
 #include "content/public/test/browser_test_utils.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"
 
 class DataSaverBrowserTest : public InProcessBrowserTest {
  protected:
@@ -45,3 +48,59 @@
   EnableDataSaver(false);
   VerifySaveDataHeader("None");
 }
+
+class DataSaverWithServerBrowserTest : public InProcessBrowserTest {
+ protected:
+  void Init() {
+    test_server_.reset(new net::EmbeddedTestServer());
+    test_server_->RegisterRequestHandler(
+        base::Bind(&DataSaverWithServerBrowserTest::VerifySaveDataHeader,
+                   base::Unretained(this)));
+    test_server_->ServeFilesFromSourceDirectory("chrome/test/data");
+  }
+  void EnableDataSaver(bool enabled) {
+    PrefService* prefs = browser()->profile()->GetPrefs();
+    prefs->SetBoolean(prefs::kDataSaverEnabled, enabled);
+  }
+
+  scoped_ptr<net::test_server::HttpResponse> VerifySaveDataHeader(
+      const net::test_server::HttpRequest& request) {
+    auto save_data_header_it = request.headers.find("save-data");
+
+    if (!expected_save_data_header_.empty()) {
+      EXPECT_TRUE(save_data_header_it != request.headers.end());
+      EXPECT_EQ(expected_save_data_header_, save_data_header_it->second);
+    } else {
+      EXPECT_TRUE(save_data_header_it == request.headers.end());
+    }
+    return scoped_ptr<net::test_server::HttpResponse>();
+  }
+
+  scoped_ptr<net::EmbeddedTestServer> test_server_;
+  std::string expected_save_data_header_;
+};
+
+IN_PROC_BROWSER_TEST_F(DataSaverWithServerBrowserTest, ReloadPage) {
+  Init();
+  ASSERT_TRUE(test_server_->Start());
+  EnableDataSaver(true);
+
+  expected_save_data_header_ = "on";
+  ui_test_utils::NavigateToURL(browser(),
+                               test_server_->GetURL("/google/google.html"));
+
+  // Reload the webpage and expect the main and the subresources will get the
+  // correct save-data header.
+  expected_save_data_header_ = "on";
+  chrome::Reload(browser(), CURRENT_TAB);
+  content::WaitForLoadStop(
+      browser()->tab_strip_model()->GetActiveWebContents());
+
+  // Reload the webpage with data saver disabled, and expect all the resources
+  // will get no save-data header.
+  EnableDataSaver(false);
+  expected_save_data_header_ = "";
+  chrome::Reload(browser(), CURRENT_TAB);
+  content::WaitForLoadStop(
+      browser()->tab_strip_model()->GetActiveWebContents());
+}
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
index 42b7e947..7315d2f 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
@@ -18,6 +18,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/test/browser_test_utils.h"
+#include "extensions/common/switches.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
@@ -29,6 +30,8 @@
 struct TestFlags {
   bool expect_screens;
   bool expect_windows;
+  bool expect_tabs;
+  bool expect_audio;
   content::DesktopMediaID selected_source;
   bool cancelled;
 
@@ -96,12 +99,16 @@
 
   // DesktopCaptureChooseDesktopMediaFunction::PickerFactory interface.
   scoped_ptr<DesktopMediaList> CreateModel(bool show_screens,
-                                           bool show_windows) override {
+                                           bool show_windows,
+                                           bool show_tabs,
+                                           bool show_audio) override {
     EXPECT_LE(current_test_, tests_count_);
     if (current_test_ >= tests_count_)
       return scoped_ptr<DesktopMediaList>();
     EXPECT_EQ(test_flags_[current_test_].expect_screens, show_screens);
     EXPECT_EQ(test_flags_[current_test_].expect_windows, show_windows);
+    EXPECT_EQ(test_flags_[current_test_].expect_tabs, show_tabs);
+    EXPECT_EQ(test_flags_[current_test_].expect_audio, show_audio);
     return scoped_ptr<DesktopMediaList>(new FakeDesktopMediaList());
   }
 
@@ -154,33 +161,61 @@
 #define MAYBE_ChooseDesktopMedia ChooseDesktopMedia
 #endif
 IN_PROC_BROWSER_TEST_F(DesktopCaptureApiTest, MAYBE_ChooseDesktopMedia) {
+  // For tab and audio share, we need to turn on the flag, because the
+  // functionality is currently behind the flags.
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      extensions::switches::kEnableTabForDesktopShare);
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      extensions::switches::kEnableDesktopCaptureAudio);
+
   // Each element in the following array corresponds to one test in
   // chrome/test/data/extensions/api_test/desktop_capture/test.js .
   TestFlags test_flags[] = {
-    // pickerUiCanceled()
-    { true, true,
-      content::DesktopMediaID() },
-    // chooseMedia()
-    { true, true,
-      content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
-                              content::DesktopMediaID::kNullId) },
-    // screensOnly()
-    { true, false,
-      content::DesktopMediaID() },
-    // WindowsOnly()
-    { false, true,
-      content::DesktopMediaID() },
-    // chooseMediaAndGetStream()
-    { true, true,
-      content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
-                              webrtc::kFullDesktopScreenId) },
-    // chooseMediaAndTryGetStreamWithInvalidId()
-    { true, true,
-      content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
-                              webrtc::kFullDesktopScreenId) },
-    // cancelDialog()
-    { true, true,
-      content::DesktopMediaID(), true },
+      // pickerUiCanceled()
+      {true, true, false, false, content::DesktopMediaID()},
+      // chooseMedia()
+      {true, true, false, false,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               content::DesktopMediaID::kNullId)},
+      // screensOnly()
+      {true, false, false, false, content::DesktopMediaID()},
+      // WindowsOnly()
+      {false, true, false, false, content::DesktopMediaID()},
+      // tabOnly()
+      {false, false, true, false, content::DesktopMediaID()},
+      // audioShare()
+      {true, true, true, true, content::DesktopMediaID()},
+      // chooseMediaAndGetStream()
+      {true, true, false, false,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               webrtc::kFullDesktopScreenId)},
+      // chooseMediaAndTryGetStreamWithInvalidId()
+      {true, true, false, false,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               webrtc::kFullDesktopScreenId)},
+      // cancelDialog()
+      {true, true, false, false, content::DesktopMediaID(), true},
+      // tabShareWithAudioGetStream()
+      {false, false, true, true,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_WEB_CONTENTS, 0,
+                               true)},
+      // windowShareWithAudioGetStream()
+      {false, true, false, true,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_WINDOW, 0, true)},
+      // screenShareWithAudioGetStream()
+      {true, false, false, true,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               webrtc::kFullDesktopScreenId, true)},
+      // tabShareWithoutAudioGetStream()
+      {false, false, true, true,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_WEB_CONTENTS, 0)},
+      // windowShareWithoutAudioGetStream()
+      {false, true, false, true,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_WINDOW, 0)},
+      // screenShareWithoutAudioGetStream()
+      {true, false, false, true,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               webrtc::kFullDesktopScreenId)},
   };
   picker_factory_.SetTestFlags(test_flags, arraysize(test_flags));
   ASSERT_TRUE(RunExtensionTest("desktop_capture")) << message_;
@@ -207,15 +242,16 @@
       browser(), GetURLForPath("example.com", "/example.com.html"));
 
   TestFlags test_flags[] = {
-    { true, true,
-      content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
-                              content::DesktopMediaID::kNullId) },
-    { true, true,
-      content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
-                              content::DesktopMediaID::kNullId) },
-    { true, true,
-      content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
-                              content::DesktopMediaID::kNullId), true },
+      {true, true, false, false,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               content::DesktopMediaID::kNullId)},
+      {true, true, false, false,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               content::DesktopMediaID::kNullId)},
+      {true, true, false, false,
+       content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN,
+                               content::DesktopMediaID::kNullId),
+       true},
   };
   picker_factory_.SetTestFlags(test_flags, arraysize(test_flags));
 
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
index 4e0903d..d30e240 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -120,8 +120,8 @@
       web_contents->GetTopLevelNativeWindow();
   scoped_ptr<DesktopMediaList> media_list;
   if (g_picker_factory) {
-    media_list = g_picker_factory->CreateModel(
-        show_screens, show_windows);
+    media_list = g_picker_factory->CreateModel(show_screens, show_windows,
+                                               show_tabs, request_audio);
     picker_ = g_picker_factory->CreatePicker();
   } else {
     std::vector<scoped_ptr<DesktopMediaList>> media_lists;
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h
index c7116a67..3295faf 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.h
@@ -27,7 +27,9 @@
   class PickerFactory {
    public:
     virtual scoped_ptr<DesktopMediaList> CreateModel(bool show_screens,
-                                                     bool show_windows) = 0;
+                                                     bool show_windows,
+                                                     bool show_tabs,
+                                                     bool show_audio) = 0;
     virtual scoped_ptr<DesktopMediaPicker> CreatePicker() = 0;
    protected:
     virtual ~PickerFactory() {}
diff --git a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
index 3160400..d4c5e3c 100644
--- a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
+++ b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
@@ -128,7 +128,7 @@
 
 }  // anonymous namespace
 
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Metrics) {
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_Metrics) {
   base::UserActionTester user_action_tester;
 
   base::FieldTrialList::CreateFieldTrial("apitestfieldtrial2", "group1");
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 19db4d8..6463858 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -4337,7 +4337,7 @@
                                       profile())->GetIndexedDBContext();
   idb_context->SetTaskRunnerForTesting(
       base::MessageLoop::current()->task_runner().get());
-  base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
+  base::FilePath idb_path = idb_context->GetFilePathForTesting(ext_url);
   EXPECT_TRUE(base::CreateDirectory(idb_path));
   EXPECT_TRUE(base::DirectoryExists(idb_path));
 
@@ -4458,7 +4458,7 @@
                                       profile())->GetIndexedDBContext();
   idb_context->SetTaskRunnerForTesting(
       base::MessageLoop::current()->task_runner().get());
-  base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
+  base::FilePath idb_path = idb_context->GetFilePathForTesting(origin1);
   EXPECT_TRUE(base::CreateDirectory(idb_path));
   EXPECT_TRUE(base::DirectoryExists(idb_path));
 
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index 1779322..54925e9 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/profiles/profile_window.h"
 
 #include <stddef.h>
+#include <string>
+#include <vector>
 
 #include "base/command_line.h"
 #include "base/files/file_path.h"
@@ -197,7 +199,8 @@
     return;
 
   // Tell the webui which user should be focused.
-  std::string page = chrome::kChromeUIUserManagerURL;
+  std::string page = switches::IsMaterialDesignUserManager() ?
+      chrome::kChromeUIMdUserManagerUrl : chrome::kChromeUIUserManagerURL;
 
   if (tutorial_mode == profiles::USER_MANAGER_TUTORIAL_OVERVIEW) {
     page += profiles::kUserManagerDisplayTutorial;
diff --git a/chrome/browser/resources/settings/OWNERS b/chrome/browser/resources/settings/OWNERS
index 4391dc29..300b7b9 100644
--- a/chrome/browser/resources/settings/OWNERS
+++ b/chrome/browser/resources/settings/OWNERS
@@ -1,3 +1,5 @@
+dbeam@chromium.org
+dpapad@chromium.org
 dschuyler@chromium.org
 michaelpg@chromium.org
 stevenjb@chromium.org
diff --git a/chrome/browser/resources/settings/advanced_page/advanced_page.js b/chrome/browser/resources/settings/advanced_page/advanced_page.js
index b50f6887..ddc47fe 100644
--- a/chrome/browser/resources/settings/advanced_page/advanced_page.js
+++ b/chrome/browser/resources/settings/advanced_page/advanced_page.js
@@ -43,7 +43,7 @@
 
   /** @private */
   onDomChange_: function() {
-    var systemPage = /** @type {?SystemPageElement} */(
+    var systemPage = /** @type {?SettingsSystemPageElement} */(
         this.$$('settings-system-page'));
     if (systemPage && !systemPage.delegate)
       systemPage.delegate = new settings.SystemPageDelegateImpl;
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_delete_confirmation_dialog.html b/chrome/browser/resources/settings/certificate_manager_page/certificate_delete_confirmation_dialog.html
new file mode 100644
index 0000000..ee6c4bd
--- /dev/null
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_delete_confirmation_dialog.html
@@ -0,0 +1,28 @@
+<link rel="import" href="chrome://resources/html/polymer_config.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://md-settings/i18n_setup.html">
+<link rel="import" href="chrome://md-settings/settings_dialog.html">
+<link rel="import" href="chrome://md-settings/settings_shared_css.html">
+<link rel="import" href="chrome://md-settings/certificate_manager_page/certificates_browser_proxy.html">
+
+<dom-module id="settings-certificate-delete-confirmation-dialog">
+  <template>
+    <style include="settings-shared"></style>
+    <settings-dialog id="dialog">
+      <div class="title">[[getTitleText_(model, certificateType)]]</div>
+      <div class="body">
+        <div>[[getDescriptionText_(model, certificateType)]]</div>
+      </div>
+      <div class="button-container">
+        <paper-button class="cancel-button" on-tap="onCancelTap_">
+          $i18n{cancel}
+        </paper-button>
+        <paper-button id="ok" class="action-button" on-tap="onOkTap_">
+          $i18n{ok}
+        </paper-button>
+      </div>
+    </settings-dialog>
+  </template>
+  <script src="certificate_delete_confirmation_dialog.js"></script>
+</dom-module>
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_delete_confirmation_dialog.js b/chrome/browser/resources/settings/certificate_manager_page/certificate_delete_confirmation_dialog.js
new file mode 100644
index 0000000..e9da85e
--- /dev/null
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_delete_confirmation_dialog.js
@@ -0,0 +1,93 @@
+// 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.
+
+/**
+ * @fileoverview A confirmation dialog allowing the user to delete various types
+ * of certificates.
+ */
+Polymer({
+  is: 'settings-certificate-delete-confirmation-dialog',
+
+  properties: {
+    /** @private {!settings.CertificatesBrowserProxy} */
+    browserProxy_: Object,
+
+    /** @type {!CertificateSubnode} */
+    model: Object,
+
+    /** @type {!settings.CertificateType} */
+    certificateType: String,
+  },
+
+  /** @override */
+  ready: function() {
+    this.browserProxy_ = settings.CertificatesBrowserProxyImpl.getInstance();
+  },
+
+  /** @override */
+  attached: function() {
+    this.$.dialog.open();
+  },
+
+  /**
+   * @private
+   * @return {string}
+   */
+  getTitleText_: function() {
+    /**
+     * @param {string} localizedMessageId
+     * @return {string}
+     */
+    var getString = function(localizedMessageId) {
+      return loadTimeData.getStringF(localizedMessageId, this.model.name);
+    }.bind(this);
+
+    switch (this.certificateType) {
+      case settings.CertificateType.PERSONAL:
+        return getString('certificateManagerDeleteUserTitle');
+      case settings.CertificateType.SERVER:
+        return getString('certificateManagerDeleteServerTitle');
+      case settings.CertificateType.CA:
+        return getString('certificateManagerDeleteCaTitle');
+      case settings.CertificateType.OTHER:
+        return getString('certificateManagerDeleteOtherTitle');
+    }
+    assertNotReached();
+  },
+
+  /**
+   * @private
+   * @return {string}
+   */
+  getDescriptionText_: function() {
+    var getString = loadTimeData.getString.bind(loadTimeData);
+    switch (this.certificateType) {
+      case settings.CertificateType.PERSONAL:
+        return getString('certificateManagerDeleteUserDescription');
+      case settings.CertificateType.SERVER:
+        return getString('certificateManagerDeleteServerDescription');
+      case settings.CertificateType.CA:
+        return getString('certificateManagerDeleteCaDescription');
+      case settings.CertificateType.OTHER:
+        return '';
+    }
+    assertNotReached();
+  },
+
+  /** @private */
+  onCancelTap_: function() {
+    this.$.dialog.close();
+  },
+
+  /** @private */
+  onOkTap_: function() {
+    this.browserProxy_.deleteCertificate(this.model.id).then(function() {
+      this.$.dialog.close();
+    }.bind(this),
+    /** @param {!CertificatesError} error */
+    function(error) {
+      // TODO(dpapad): Display error here.
+    });
+  },
+});
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html b/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html
index c3c5ca8..a7f2acb 100644
--- a/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificate_manager_page.html
@@ -4,6 +4,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-tabs/paper-tabs.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
 <link rel="import" href="chrome://md-settings/certificate_manager_page/ca_trust_edit_dialog.html">
+<link rel="import" href="chrome://md-settings/certificate_manager_page/certificate_delete_confirmation_dialog.html">
 
 <dom-module id="settings-certificate-manager-page">
   <link rel="import" type="css" href="certificate_manager_page.css">
diff --git a/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js b/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js
index 26d6749..cf2cbe4 100644
--- a/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js
+++ b/chrome/browser/resources/settings/certificate_manager_page/certificates_browser_proxy.js
@@ -64,6 +64,17 @@
 var CertificatesImportError;
 
 cr.define('settings', function() {
+  /**
+   * Enumeration of all possible certificate types.
+   * @enum {string}
+   */
+  var CertificateType = {
+    CA: 'ca',
+    OTHER: 'other',
+    PERSONAL: 'personal',
+    SERVER: 'server',
+  };
+
   /** @interface */
   function CertificatesBrowserProxy() {}
 
@@ -83,7 +94,8 @@
 
     /**
      * @param {string} id
-     * @return {!Promise}
+     * @return {!Promise} A promise resolved when the certificate has been
+     *     deleted successfully or rejected with a CertificatesError.
      */
     deleteCertificate: function(id) {},
 
@@ -250,5 +262,6 @@
 
   return {
     CertificatesBrowserProxyImpl: CertificatesBrowserProxyImpl,
+    CertificateType: CertificateType,
   };
 });
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd
index 5e0af9d..58201e9 100644
--- a/chrome/browser/resources/settings/settings_resources.grd
+++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -184,6 +184,12 @@
       <structure name="IDR_SETTINGS_CERTIFICATES_CA_TRUST_EDIT_DIALOG_HTML"
                  file="certificate_manager_page/ca_trust_edit_dialog.html"
                  type="chrome_html" />
+      <structure name="IDR_SETTINGS_CERTIFICATES_CERTIFICATE_DELETE_CONFIRMATION_DIALOG_JS"
+                 file="certificate_manager_page/certificate_delete_confirmation_dialog.js"
+                 type="chrome_html" />
+      <structure name="IDR_SETTINGS_CERTIFICATES_CERTIFICATE_DELETE_CONFIRMATION_DIALOG_HTML"
+                 file="certificate_manager_page/certificate_delete_confirmation_dialog.html"
+                 type="chrome_html" />
       <structure name="IDR_SETTINGS_CLEAR_BROWSING_DATA_PAGE_CSS"
                  file="clear_browsing_data_page/clear_browsing_data_page.css"
                  type="chrome_html" />
diff --git a/chrome/browser/ui/android/bluetooth_chooser_android.cc b/chrome/browser/ui/android/bluetooth_chooser_android.cc
index 5631e64..a24ef89f 100644
--- a/chrome/browser/ui/android/bluetooth_chooser_android.cc
+++ b/chrome/browser/ui/android/bluetooth_chooser_android.cc
@@ -7,13 +7,18 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ssl/chrome_security_state_model_client.h"
 #include "chrome/browser/ui/android/view_android_helper.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
+#include "components/prefs/pref_service.h"
+#include "components/url_formatter/elide_url.h"
 #include "content/public/browser/android/content_view_core.h"
 #include "content/public/browser/render_frame_host.h"
 #include "jni/BluetoothChooserDialog_jni.h"
 #include "ui/android/window_android.h"
+#include "url/gurl.h"
 #include "url/origin.h"
 
 using base::android::AttachCurrentThread;
@@ -40,8 +45,14 @@
 
   // Create (and show) the BluetoothChooser dialog.
   JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jstring> origin_string =
-      ConvertUTF8ToJavaString(env, origin.Serialize());
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
+  std::string languages =
+      profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
+  base::android::ScopedJavaLocalRef<jstring> origin_string =
+      base::android::ConvertUTF16ToJavaString(
+          env, url_formatter::FormatUrlForSecurityDisplay(
+                   frame->GetLastCommittedURL(), languages));
   java_dialog_.Reset(Java_BluetoothChooserDialog_create(
       env, window_android.obj(), origin_string.obj(),
       security_model_client->GetSecurityInfo().security_level,
diff --git a/chrome/browser/ui/cocoa/app_menu/menu_tracked_button.mm b/chrome/browser/ui/cocoa/app_menu/menu_tracked_button.mm
index 40dfcb4..0570c66 100644
--- a/chrome/browser/ui/cocoa/app_menu/menu_tracked_button.mm
+++ b/chrome/browser/ui/cocoa/app_menu/menu_tracked_button.mm
@@ -4,6 +4,8 @@
 
 #import "chrome/browser/ui/cocoa/app_menu/menu_tracked_button.h"
 
+#include "ui/base/cocoa/cocoa_base_utils.h"
+
 @interface MenuTrackedButton (Private)
 - (void)doHighlight:(BOOL)highlight;
 - (void)checkMouseInRect;
@@ -84,7 +86,7 @@
 // exit mouse events and thus polling is necessary.
 - (void)checkMouseInRect {
   NSPoint point = [NSEvent mouseLocation];
-  point = [[self window] convertScreenToBase:point];
+  point = ui::ConvertPointFromScreenToWindow([self window], point);
   point = [self convertPoint:point fromView:nil];
   if (!NSPointInRect(point, [self insetBounds])) {
     [self doHighlight:NO];
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
index af7d072..88b426a 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
@@ -11,6 +11,7 @@
 #import "chrome/browser/ui/cocoa/autofill/autofill_bubble_controller.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 typedef BOOL (^FieldFilterBlock)(NSView<AutofillInputField>*);
 
@@ -215,8 +216,8 @@
     [[errorBubbleController_ bubble] setAlignment:
         info_bubble::kAlignLeftEdgeToAnchorEdge];
   }
-  [errorBubbleController_ setAnchorPoint:
-      [parentWindow convertBaseToScreen:anchorPoint]];
+  [errorBubbleController_ setAnchorPoint:ui::ConvertPointFromWindowToScreen(
+                                             parentWindow, anchorPoint)];
 
   errorBubbleAnchorView_ = field;
   [errorBubbleController_ showWindow:self];
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
index 432582ef..320cc9d7 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_section_container.mm
@@ -9,6 +9,7 @@
 #include <algorithm>
 
 #include "base/mac/foundation_util.h"
+#include "base/mac/sdk_forward_declarations.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/autofill/autofill_dialog_view_delegate.h"
@@ -405,8 +406,7 @@
 
   // Get the frame rectangle for the designated field, in screen coordinates.
   NSRect textFrameInScreen = [field convertRect:[field bounds] toView:nil];
-  textFrameInScreen.origin =
-      [[field window] convertBaseToScreen:textFrameInScreen.origin];
+  textFrameInScreen = [[field window] convertRectToScreen:textFrameInScreen];
 
   // And adjust for gfx::Rect being flipped compared to OSX coordinates.
   NSScreen* screen = [[NSScreen screens] firstObject];
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_tooltip_controller.mm b/chrome/browser/ui/cocoa/autofill/autofill_tooltip_controller.mm
index b2a66dc..d16b635 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_tooltip_controller.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_tooltip_controller.mm
@@ -7,6 +7,7 @@
 #include "base/mac/foundation_util.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_bubble_controller.h"
 #import "ui/base/cocoa/base_view.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/hover_image_button.h"
 
 // Delay time before tooltip shows/hides.
@@ -164,8 +165,8 @@
   // Compute anchor point (in window coords - views might be flipped).
   NSRect viewRect = [view_ convertRect:[view_ bounds] toView:nil];
   NSPoint anchorPoint = NSMakePoint(NSMidX(viewRect), NSMinY(viewRect));
-  [bubbleController_ setAnchorPoint:
-      [[[self view] window] convertBaseToScreen:anchorPoint]];
+  [bubbleController_ setAnchorPoint:ui::ConvertPointFromWindowToScreen(
+      [[self view] window], anchorPoint)];
   [bubbleController_ showWindow:self];
 }
 
diff --git a/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm b/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm
index 3c8c92b..c072c34 100644
--- a/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/new_credit_card_bubble_cocoa.mm
@@ -17,6 +17,7 @@
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "content/public/browser/web_contents.h"
 #include "skia/ext/skia_utils_mac.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #include "ui/base/cocoa/window_size_constants.h"
 #include "ui/native_theme/native_theme.h"
@@ -235,9 +236,8 @@
     anchor_point.y = NSMaxY([anchor_view bounds]) - anchor_point.y;
   anchor_point = [anchor_view convertPoint:anchor_point toView:nil];
 
-  NSRect frame = NSZeroRect;
-  frame.origin = anchor_point;
-  anchor_point = [parent_window convertBaseToScreen:anchor_point];
+  anchor_point =
+      ui::ConvertPointFromWindowToScreen(parent_window, anchor_point);
   [bubbleController_ showAtAnchor:anchor_point];
 }
 
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
index 969b3db..46bf2f6e 100644
--- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
+++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
@@ -14,6 +14,7 @@
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "grit/components_strings.h"
 #include "skia/ext/skia_utils_mac.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/controls/hyperlink_text_view.h"
 #import "ui/base/cocoa/window_size_constants.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -198,8 +199,8 @@
 
   NSPoint anchorPoint =
       [[browserWindowController toolbarController] saveCreditCardBubblePoint];
-  anchorPoint =
-      [[browserWindowController window] convertBaseToScreen:anchorPoint];
+  anchorPoint = ui::ConvertPointFromWindowToScreen(
+      [browserWindowController window], anchorPoint);
 
   if ((self = [super initWithWindow:window
                        parentWindow:[browserWindowController window]
diff --git a/chrome/browser/ui/cocoa/base_bubble_controller.mm b/chrome/browser/ui/cocoa/base_bubble_controller.mm
index a25299786..3d84e03 100644
--- a/chrome/browser/ui/cocoa/base_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/base_bubble_controller.mm
@@ -16,6 +16,7 @@
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h"
 #include "components/bubble/bubble_controller.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 @interface BaseBubbleController (Private)
 - (void)registerForNotifications;
@@ -68,7 +69,7 @@
   NSRect bounds = [view convertRect:[view bounds] toView:nil];
   NSPoint anchor = NSMakePoint(NSMinX(bounds) + offset.x,
                                NSMinY(bounds) + offset.y);
-  anchor = [window convertBaseToScreen:anchor];
+  anchor = ui::ConvertPointFromWindowToScreen(window, anchor);
   return [self initWithWindowNibPath:nibPath
                         parentWindow:window
                           anchoredAt:anchor];
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
index f0b85f5..704dcbea 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.mm
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include "base/mac/bundle_locations.h"
+#include "base/mac/sdk_forward_declarations.h"
 #include "base/strings/sys_string_conversions.h"
 #import "chrome/browser/bookmarks/bookmark_model_factory.h"
 #import "chrome/browser/bookmarks/managed_bookmark_service_factory.h"
@@ -23,6 +24,7 @@
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/browser/bookmark_node_data.h"
 #import "components/bookmarks/managed/managed_bookmark_service.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/theme_provider.h"
 
 using bookmarks::BookmarkModel;
@@ -496,14 +498,12 @@
     // popping up from the bookmark bar itself.  In this case, start
     // BELOW the parent button.  Our left is the button left; our top
     // is bottom of button's parent view.
-    NSPoint buttonBottomLeftInScreen =
-        [[parentButton_ window]
-            convertBaseToScreen:[parentButton_
-                                    convertPoint:NSZeroPoint toView:nil]];
-    NSPoint bookmarkBarBottomLeftInScreen =
-        [[parentButton_ window]
-            convertBaseToScreen:[[parentButton_ superview]
-                                    convertPoint:NSZeroPoint toView:nil]];
+    NSPoint buttonBottomLeftInScreen = ui::ConvertPointFromWindowToScreen(
+        [parentButton_ window],
+        [parentButton_ convertPoint:NSZeroPoint toView:nil]);
+    NSPoint bookmarkBarBottomLeftInScreen = ui::ConvertPointFromWindowToScreen(
+        [parentButton_ window],
+        [[parentButton_ superview] convertPoint:NSZeroPoint toView:nil]);
     newWindowTopLeft = NSMakePoint(
         buttonBottomLeftInScreen.x + bookmarks::kBookmarkBarButtonOffset,
         bookmarkBarBottomLeftInScreen.y + bookmarks::kBookmarkBarMenuOffset);
@@ -538,9 +538,9 @@
     NSPoint topOfWindow = NSMakePoint(0,
                                       NSMaxY([parentButton_ frame]) -
                                           bookmarks::kBookmarkVerticalPadding);
-    topOfWindow = [[parentButton_ window]
-                   convertBaseToScreen:[[parentButton_ superview]
-                                        convertPoint:topOfWindow toView:nil]];
+    topOfWindow = ui::ConvertPointFromWindowToScreen(
+        [parentButton_ window],
+        [[parentButton_ superview] convertPoint:topOfWindow toView:nil]);
     newWindowTopLeft.y = topOfWindow.y +
                          2 * bookmarks::kBookmarkVerticalPadding;
   }
@@ -1040,8 +1040,8 @@
   NSButton* button = parentButton_.get();
   NSRect parentButtonGlobalFrame =
       [button convertRect:[button bounds] toView:nil];
-  parentButtonGlobalFrame.origin =
-      [[button window] convertBaseToScreen:parentButtonGlobalFrame.origin];
+  parentButtonGlobalFrame =
+      [[button window] convertRectToScreen:parentButtonGlobalFrame];
   for (NSScreen* screen in [NSScreen screens]) {
     if (NSIntersectsRect([screen frame], parentButtonGlobalFrame))
       return screen;
@@ -1064,19 +1064,19 @@
 // Note [theEvent window] may not be our window, as we also get these messages
 // forwarded from BookmarkButton's mouse tracking loop.
 - (void)mouseMovedOrDragged:(NSEvent*)theEvent {
-  NSPoint eventScreenLocation =
-      [[theEvent window] convertBaseToScreen:[theEvent locationInWindow]];
+  NSPoint eventScreenLocation = ui::ConvertPointFromWindowToScreen(
+      [theEvent window], [theEvent locationInWindow]);
 
   // Base hot spot calculations on the positions of the scroll arrow views.
   NSRect testRect = [scrollDownArrowView_ frame];
   NSPoint testPoint = [visibleView_ convertPoint:testRect.origin
                                                   toView:nil];
-  testPoint = [[self window] convertBaseToScreen:testPoint];
+  testPoint = ui::ConvertPointFromWindowToScreen([self window], testPoint);
   CGFloat closeToTopOfScreen = testPoint.y;
 
   testRect = [scrollUpArrowView_ frame];
   testPoint = [visibleView_ convertPoint:testRect.origin toView:nil];
-  testPoint = [[self window] convertBaseToScreen:testPoint];
+  testPoint = ui::ConvertPointFromWindowToScreen([self window], testPoint);
   CGFloat closeToBottomOfScreen = testPoint.y + testRect.size.height;
   if (eventScreenLocation.y <= closeToBottomOfScreen &&
       ![scrollUpArrowView_ isHidden]) {
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
index e516532..fa15a13 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <cmath>
+
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
@@ -20,8 +22,7 @@
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
 #include "ui/base/cocoa/animation_utils.h"
-
-#include <cmath>
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 using base::ASCIIToUTF16;
 using bookmarks::BookmarkModel;
@@ -269,8 +270,8 @@
   NSPoint buttonOriginInWindow =
       [parentButton convertRect:[parentButton bounds]
                          toView:nil].origin;
-  NSPoint buttonOriginInScreen =
-      [[parentButton window] convertBaseToScreen:buttonOriginInWindow];
+  NSPoint buttonOriginInScreen = ui::ConvertPointFromWindowToScreen(
+      [parentButton window], buttonOriginInWindow);
   // Within margin
   EXPECT_LE(std::abs(pt.x - buttonOriginInScreen.x),
             bookmarks::kBookmarkMenuOverlap + 1);
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
index f78e17a..53df21e 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
@@ -24,6 +24,7 @@
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/user_metrics.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
 using base::UserMetricsAction;
@@ -144,7 +145,7 @@
   // which will occur for some unit tests.
   NSPoint arrowTip = bwc ? [bwc bookmarkBubblePoint] :
       NSMakePoint([window frame].size.width, [window frame].size.height);
-  arrowTip = [parentWindow convertBaseToScreen:arrowTip];
+  arrowTip = ui::ConvertPointFromWindowToScreen(parentWindow, arrowTip);
   NSPoint bubbleArrowTip = [bubble arrowTip];
   bubbleArrowTip = [bubble convertPoint:bubbleArrowTip toView:nil];
   arrowTip.y -= bubbleArrowTip.y;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm
index bb689e5..6eea9367 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button.mm
@@ -15,6 +15,7 @@
 #import "chrome/browser/ui/cocoa/view_id_util.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "content/public/browser/user_metrics.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/nsview_additions.h"
 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
 
@@ -109,7 +110,7 @@
     NSRect bounds = [self bounds];
     point = NSMakePoint(NSMidX(bounds), NSMidY(bounds));
     point = [self convertPoint:point toView:nil];
-    point = [[self window] convertBaseToScreen:point];
+    point = ui::ConvertPointFromWindowToScreen([self window], point);
   }
 
   return point;
diff --git a/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm b/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm
index 3873c46..50a20aa 100644
--- a/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm
+++ b/chrome/browser/ui/cocoa/browser/exclusive_access_controller_views.mm
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/views/exclusive_access_bubble_views.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/gfx/mac/coordinate_conversion.h"
 
 ExclusiveAccessController::ExclusiveAccessController(
@@ -167,7 +168,8 @@
 
 gfx::Point ExclusiveAccessController::GetCursorPointInParent() const {
   NSWindow* window = [controller_ window];
-  NSPoint location = [window convertScreenToBase:[NSEvent mouseLocation]];
+  NSPoint location =
+      ui::ConvertPointFromScreenToWindow(window, [NSEvent mouseLocation]);
   return gfx::Point(location.x,
                     NSHeight([[window contentView] frame]) - location.y);
 }
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index 7fd16e93..c660dfd7a 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -1171,8 +1171,9 @@
       NSPoint tabOrigin = destinationFrame.origin;
       tabOrigin = [[dragController tabStripView] convertPoint:tabOrigin
                                                        toView:nil];
-      tabOrigin = [[dragController window] convertBaseToScreen:tabOrigin];
-      tabOrigin = [[self window] convertScreenToBase:tabOrigin];
+      tabOrigin = ui::ConvertPointFromWindowToScreen([dragController window],
+                                                     tabOrigin);
+      tabOrigin = ui::ConvertPointFromScreenToWindow([self window], tabOrigin);
       tabOrigin = [[self tabStripView] convertPoint:tabOrigin fromView:nil];
       destinationFrame.origin = tabOrigin;
 
@@ -1559,8 +1560,8 @@
 
   if (chrome::ToolkitViewsDialogsEnabled()) {
     chrome::ShowBookmarkBubbleViewsAtPoint(
-        gfx::ScreenPointFromNSPoint(
-            [[self window] convertBaseToScreen:[self bookmarkBubblePoint]]),
+        gfx::ScreenPointFromNSPoint(ui::ConvertPointFromWindowToScreen(
+            [self window], [self bookmarkBubblePoint])),
         [[self window] contentView], bookmarkBubbleObserver_.get(),
         browser_.get(), url, alreadyMarked);
   } else {
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
index 44da54d..dbaec96 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -1131,15 +1131,19 @@
 }
 
 - (BOOL)shouldUseCustomAppKitFullscreenTransition:(BOOL)enterFullScreen {
-  // Custom fullscreen transitions should only be available in OSX 10.10+.
+  // Custom fullscreen transitions should only be available in OSX 10.9+.
   if (base::mac::IsOSMountainLionOrEarlier())
     return NO;
 
-  // Disable the custom exit animation in OSX 10.9:
-  // https://code.google.com/p/chromium/issues/detail?id=526327#c3.
+  // Disable the custom exit animation in OSX 10.9: http://crbug.com/526327#c3.
   if (base::mac::IsOSMavericks() && !enterFullScreen)
     return NO;
 
+  // TODO(spqchan): Fix Flash fullscreen animation in popups.
+  // See http://crbug.com/566588.
+  if ([self isFullscreenForTabContent] && browser_->is_type_popup())
+    return NO;
+
   NSView* root = [[self.window contentView] superview];
   if (!root.layer)
     return NO;
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.mm
index db2d495..ec7db250 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.mm
@@ -7,6 +7,7 @@
 #include <map>
 
 #include "base/logging.h"
+#include "base/mac/sdk_forward_declarations.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet.h"
 #include "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_info.h"
 #import "chrome/browser/ui/cocoa/web_contents_modal_dialog_host_cocoa.h"
@@ -317,7 +318,7 @@
     viewFrame.size.height += NSMinY(customSheetFrame) - NSMinY(sheetFrame);
   }
 
-  viewFrame.origin = [[parentView window] convertBaseToScreen:viewFrame.origin];
+  viewFrame = [[parentView window] convertRectToScreen:viewFrame];
   return viewFrame;
 }
 
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
index 6566d21..5c0b0d5 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include "base/mac/sdk_forward_declarations.h"
 #include "base/macros.h"
 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
@@ -159,7 +160,7 @@
 
   NSRect GetViewFrameInScreenCoordinates(NSView* view) {
     NSRect rect = [view convertRect:[view bounds] toView:nil];
-    rect.origin = [[view window] convertBaseToScreen:rect.origin];
+    rect = [[view window] convertRectToScreen:rect];
     return rect;
   }
 
diff --git a/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm b/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm
index f4772551..ef99973 100644
--- a/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm
+++ b/chrome/browser/ui/cocoa/download/download_started_animation_mac.mm
@@ -17,6 +17,7 @@
 #include "grit/theme_resources.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h"
 #include "third_party/skia/include/utils/mac/SkCGUtils.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/image/image.h"
@@ -68,7 +69,7 @@
 
     NSPoint origin = [tabContentsView frame].origin;
     origin = [tabContentsView convertPoint:origin toView:nil];
-    origin = [parentWindow convertBaseToScreen:origin];
+    origin = ui::ConvertPointFromWindowToScreen(parentWindow, origin);
 
     // Create the animation object to assist in animating and fading.
     CGFloat animationHeight = MIN(bounds.height(), 4 * imageHeight);
diff --git a/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm b/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm
index 6e59f9a2..03717c0 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_action_button_interactive_uitest.mm
@@ -30,6 +30,7 @@
 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "extensions/common/feature_switch.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/events/test/cocoa_test_event_utils.h"
 
 namespace {
@@ -75,7 +76,7 @@
   NSRect bounds = [view bounds];
   NSPoint center = NSMakePoint(NSMidX(bounds), NSMidY(bounds));
   center = [view convertPoint:center toView:nil];
-  center = [window convertBaseToScreen:center];
+  center = ui::ConvertPointFromWindowToScreen(window, center);
   return NSMakePoint(center.x, [screen frame].size.height - center.y);
 }
 
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index 118e94a..3f97173 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -31,6 +31,7 @@
 #include "grit/theme_resources.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h"
 #include "ui/base/cocoa/appkit_utils.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/material_design/material_design_controller.h"
 
 NSString* const kBrowserActionVisibilityChangedNotification =
@@ -1048,7 +1049,7 @@
   NSPoint anchor = [self popupPointForView:anchorView
                                 withBounds:[anchorView bounds]];
 
-  anchor = [[containerView_ window] convertBaseToScreen:anchor];
+  anchor = ui::ConvertPointFromWindowToScreen([containerView_ window], anchor);
   activeBubble_ = [[ToolbarActionsBarBubbleMac alloc]
       initWithParentWindow:[containerView_ window]
                anchorPoint:anchor
diff --git a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
index 537389ed..f36c90c 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_installed_bubble_controller.mm
@@ -48,6 +48,7 @@
 #import "skia/ext/skia_utils_mac.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/controls/hyperlink_text_view.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -588,8 +589,8 @@
 }
 
 - (void)updateAnchorPosition {
-  self.anchorPoint =
-      [self.parentWindow convertBaseToScreen:[self calculateArrowPoint]];
+  self.anchorPoint = ui::ConvertPointFromWindowToScreen(
+      self.parentWindow, [self calculateArrowPoint]);
 }
 
 - (IBAction)onManageShortcutClicked:(id)sender {
diff --git a/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm b/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm
index 66ff65cb..f599771 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_message_bubble_browsertest_mac.mm
@@ -10,6 +10,7 @@
 #import "chrome/browser/ui/cocoa/extensions/toolbar_actions_bar_bubble_mac.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
 #include "chrome/browser/ui/extensions/extension_message_bubble_browsertest.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 namespace {
 
@@ -39,9 +40,11 @@
   CGFloat refLowY = [expectedReferenceView isFlipped] ?
       NSMaxY(referenceFrame) : NSMinY(referenceFrame);
   NSPoint refLowerLeft = NSMakePoint(NSMinX(referenceFrame), refLowY);
-  NSPoint refLowerLeftInScreen = [window convertBaseToScreen:refLowerLeft];
+  NSPoint refLowerLeftInScreen =
+      ui::ConvertPointFromWindowToScreen(window, refLowerLeft);
   NSPoint refLowerRight = NSMakePoint(NSMaxX(referenceFrame), refLowY);
-  NSPoint refLowerRightInScreen = [window convertBaseToScreen:refLowerRight];
+  NSPoint refLowerRightInScreen =
+      ui::ConvertPointFromWindowToScreen(window, refLowerRight);
 
   // The bubble should be below the reference view, but not too far below.
   EXPECT_LE(NSMaxY(bubbleFrame), refLowerLeftInScreen.y);
diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
index b192160..a714d48 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
@@ -23,6 +23,7 @@
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_source.h"
 #include "extensions/browser/notification_types.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/cocoa/window_size_constants.h"
 
 using content::BrowserContext;
@@ -176,7 +177,7 @@
   if (!window.get())
     return nil;
 
-  anchoredAt = [parentWindow convertBaseToScreen:anchoredAt];
+  anchoredAt = ui::ConvertPointFromWindowToScreen(parentWindow, anchoredAt);
   if ((self = [super initWithWindow:window
                        parentWindow:parentWindow
                          anchoredAt:anchoredAt])) {
diff --git a/chrome/browser/ui/cocoa/framed_browser_window.mm b/chrome/browser/ui/cocoa/framed_browser_window.mm
index 0b1c319..4dd76859 100644
--- a/chrome/browser/ui/cocoa/framed_browser_window.mm
+++ b/chrome/browser/ui/cocoa/framed_browser_window.mm
@@ -17,6 +17,7 @@
 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
 #import "chrome/browser/ui/cocoa/themed_window.h"
 #include "grit/theme_resources.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/cocoa/nsgraphics_context_additions.h"
 #import "ui/base/cocoa/nsview_additions.h"
 #include "ui/base/material_design/material_design_controller.h"
@@ -167,7 +168,7 @@
 // The tab strip view covers our window buttons. So we add hit testing here
 // to find them properly and return them to the accessibility system.
 - (id)accessibilityHitTest:(NSPoint)point {
-  NSPoint windowPoint = [self convertScreenToBase:point];
+  NSPoint windowPoint = ui::ConvertPointFromScreenToWindow(self, point);
   NSControl* controls[] = { closeButton_, zoomButton_, miniaturizeButton_ };
   id value = nil;
   for (size_t i = 0; i < sizeof(controls) / sizeof(controls[0]); ++i) {
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm
index 59608c9..ebd04cf 100644
--- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm
+++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_unittest.mm
@@ -18,6 +18,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 using ::testing::A;
 using ::testing::InSequence;
@@ -50,7 +51,8 @@
                const NSUInteger clickCount) {
   NSWindow* window([view window]);
   const NSPoint locationInWindow([view convertPoint:point toView:nil]);
-  const NSPoint location([window convertBaseToScreen:locationInWindow]);
+  const NSPoint location =
+      ui::ConvertPointFromWindowToScreen(window, locationInWindow);
   return [NSEvent mouseEventWithType:type
                             location:location
                        modifierFlags:0
diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm
index e737e90..2541cc0 100644
--- a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm
@@ -22,6 +22,7 @@
 #include "content/public/browser/web_contents.h"
 #include "grit/theme_resources.h"
 #include "ui/base/cocoa/appkit_utils.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/mac/coordinate_conversion.h"
@@ -268,7 +269,7 @@
   AutocompleteTextField* field = owner_->GetAutocompleteTextField();
   NSPoint anchor = GetBubblePointInFrame(frame);
   anchor = [field convertPoint:anchor toView:nil];
-  anchor = [[field window] convertBaseToScreen:anchor];
+  anchor = ui::ConvertPointFromWindowToScreen([field window], anchor);
 
   // Open bubble.
   ContentSettingBubbleModel* model =
diff --git a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
index 659f2a6..08d012f 100644
--- a/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
+++ b/chrome/browser/ui/cocoa/location_bar/zoom_decoration.mm
@@ -14,6 +14,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/ui/zoom/zoom_controller.h"
 #include "grit/theme_resources.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
 ZoomDecoration::ZoomDecoration(LocationBarViewMac* owner)
@@ -70,7 +71,7 @@
   // Find point for bubble's arrow in screen coordinates.
   NSPoint anchor = GetBubblePointInFrame(frame);
   anchor = [field convertPoint:anchor toView:nil];
-  anchor = [[field window] convertBaseToScreen:anchor];
+  anchor = ui::ConvertPointFromWindowToScreen([field window], anchor);
 
   bubble_ = [[ZoomBubbleController alloc] initWithParentWindow:[field window]
                                                       delegate:this];
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
index b4249c1d..f8a10b8 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
@@ -202,9 +202,11 @@
   popup_frame.size.height += [OmniboxPopupTopSeparatorView preferredHeight];
   popup_frame.size.height += [OmniboxPopupBottomSeparatorView preferredHeight];
   popup_frame.origin.y -= NSHeight(popup_frame);
+
   // Shift to screen coordinates.
-  popup_frame.origin =
-      [[controller window] convertBaseToScreen:popup_frame.origin];
+  if ([controller window]) {
+    popup_frame = [[controller window] convertRectToScreen:popup_frame];
+  }
 
   // Top separator.
   NSRect top_separator_frame = NSZeroRect;
diff --git a/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm b/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm
index 5acb2d8a..582a2a2 100644
--- a/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/one_click_signin_bubble_controller.mm
@@ -9,6 +9,7 @@
 #import "chrome/browser/ui/cocoa/info_bubble_window.h"
 #import "chrome/browser/ui/cocoa/one_click_signin_view_controller.h"
 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 namespace {
 
@@ -41,7 +42,7 @@
   const NSRect bounds = [appMenuButton bounds];
   NSPoint anchorPoint = NSMakePoint(NSMidX(bounds), NSMaxY(bounds));
   anchorPoint = [appMenuButton convertPoint:anchorPoint toView:nil];
-  anchorPoint = [parentWindow convertBaseToScreen:anchorPoint];
+  anchorPoint = ui::ConvertPointFromWindowToScreen(parentWindow, anchorPoint);
 
   // Create an empty window into which content is placed.
   NSRect viewBounds = [[viewController_ view] bounds];
diff --git a/chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm b/chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm
index f82f3f6..c7a9665 100644
--- a/chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm
+++ b/chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.mm
@@ -14,6 +14,7 @@
 #include "grit/theme_resources.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+RoundRect.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSColor+Luminance.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/hover_image_button.h"
 #import "ui/base/cocoa/nsview_additions.h"
 #include "ui/base/l10n/l10n_util_mac.h"
@@ -418,8 +419,8 @@
 }
 
 - (void)dragStarted:(NSPoint)initialMouseLocation {
-  NSPoint initialMouseLocationScreen =
-      [[self window] convertBaseToScreen:initialMouseLocation];
+  NSPoint initialMouseLocationScreen = ui::ConvertPointFromWindowToScreen(
+      [self window], initialMouseLocation);
   [controller_ startDrag:initialMouseLocationScreen];
 }
 
@@ -428,8 +429,8 @@
 }
 
 - (void)dragProgress:(NSPoint)mouseLocation {
-  NSPoint mouseLocationScreen =
-      [[self window] convertBaseToScreen:mouseLocation];
+  NSPoint mouseLocationScreen = ui::ConvertPointFromWindowToScreen(
+      [self window], mouseLocation);
   [controller_ drag:mouseLocationScreen];
 }
 
@@ -530,8 +531,8 @@
   dragController_.reset([[TestDragController alloc] initWithClient:self]);
   // Convert from Cocoa's screen coordinates to base coordinates since the mouse
   // event takes base (NSWindow) coordinates.
-  NSPoint mouseLocationWindow =
-      [[self window] convertScreenToBase:mouseLocation];
+  NSPoint mouseLocationWindow = ui::ConvertPointFromScreenToWindow(
+      [self window], mouseLocation);
   NSEvent* event = MakeMouseEvent(NSLeftMouseDown, mouseLocationWindow,
       modifierFlags, 0);
   [self mouseDown:event];
@@ -545,8 +546,8 @@
 - (void)dragTitlebar:(NSPoint)mouseLocation {
   // Convert from Cocoa's screen coordinates to base coordinates since the mouse
   // event takes base (NSWindow) coordinates.
-  NSPoint mouseLocationWindow =
-      [[self window] convertScreenToBase:mouseLocation];
+  NSPoint mouseLocationWindow = ui::ConvertPointFromScreenToWindow(
+      [self window], mouseLocation);
   NSEvent* event =
       MakeMouseEvent(NSLeftMouseDragged, mouseLocationWindow, 0, 0);
   [self mouseDragged:event];
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller.mm b/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller.mm
index b9139d2..4afa92bd 100644
--- a/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/passwords/passwords_bubble_controller.mm
@@ -15,6 +15,7 @@
 #import "chrome/browser/ui/cocoa/passwords/manage_passwords_view_controller.h"
 #import "chrome/browser/ui/cocoa/passwords/save_pending_password_view_controller.h"
 #import "chrome/browser/ui/cocoa/passwords/update_pending_password_view_controller.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/cocoa/window_size_constants.h"
 
 @interface ManagePasswordsBubbleController ()
@@ -115,7 +116,8 @@
   [[self bubble] setArrowLocation:arrow];
 
   // Update the anchor point.
-  anchorPoint = [[self parentWindow] convertBaseToScreen:anchorPoint];
+  anchorPoint =
+      ui::ConvertPointFromWindowToScreen([self parentWindow], anchorPoint);
   [self setAnchorPoint:anchorPoint];
 
   // Update the frame.
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
index e333694..ef503f0 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
@@ -24,6 +24,7 @@
 #import "chrome/browser/ui/cocoa/profiles/profile_chooser_controller.h"
 #include "components/signin/core/browser/signin_error_controller.h"
 #include "components/signin/core/common/profile_management_switches.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 // Space between the avatar icon and the avatar menu bubble.
 const CGFloat kMenuYOffsetAdjust = 1.0;
@@ -179,7 +180,7 @@
   NSPoint point = NSMakePoint(anchorX,
                               NSMaxY([anchor bounds]) + kMenuYOffsetAdjust);
   point = [anchor convertPoint:point toView:nil];
-  point = [[anchor window] convertBaseToScreen:point];
+  point = ui::ConvertPointFromWindowToScreen([anchor window], point);
 
   // |menuController_| will automatically release itself on close.
   profiles::BubbleViewMode viewMode;
diff --git a/chrome/browser/ui/cocoa/status_bubble_mac.mm b/chrome/browser/ui/cocoa/status_bubble_mac.mm
index 503a070..653e333c 100644
--- a/chrome/browser/ui/cocoa/status_bubble_mac.mm
+++ b/chrome/browser/ui/cocoa/status_bubble_mac.mm
@@ -22,6 +22,7 @@
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+RoundRect.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSColor+Luminance.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/cocoa/window_size_constants.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/geometry/point.h"
@@ -363,7 +364,8 @@
 
   // To start, assume default positioning in the lower left corner.
   // The window_frame position is in global (screen) coordinates.
-  window_frame.origin = [parent_ convertBaseToScreen:base_rect.origin];
+  window_frame.origin =
+      ui::ConvertPointFromWindowToScreen(parent_, base_rect.origin);
 
   // Get the cursor position relative to the top right corner of the bubble.
   gfx::Point relative_pos(mouse_pos.x() - NSMaxX(window_frame),
@@ -811,7 +813,7 @@
   NSRect screenRect;
   if ([delegate_ respondsToSelector:@selector(statusBubbleBaseFrame)]) {
     screenRect = [delegate_ statusBubbleBaseFrame];
-    screenRect.origin = [parent_ convertBaseToScreen:screenRect.origin];
+    screenRect = [parent_ convertRectToScreen:screenRect];
   } else {
     screenRect = [parent_ frame];
   }
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
index c5a6261d..69eabbc 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -62,6 +62,7 @@
 #include "skia/ext/skia_utils_mac.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h"
 #include "ui/base/cocoa/animation_utils.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/tracking_area.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/material_design/material_design_controller.h"
@@ -270,7 +271,8 @@
 - (void)trackClickForWindowMove:(NSEvent*)event {
   NSWindow* window = [self window];
   NSPoint frameOrigin = [window frame].origin;
-  NSPoint lastEventLoc = [window convertBaseToScreen:[event locationInWindow]];
+  NSPoint lastEventLoc =
+      ui::ConvertPointFromWindowToScreen(window, [event locationInWindow]);
   while ((event = [NSApp nextEventMatchingMask:
       NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask
                                     untilDate:[NSDate distantFuture]
@@ -279,7 +281,8 @@
       [event type] != NSLeftMouseUp) {
     base::mac::ScopedNSAutoreleasePool pool;
 
-    NSPoint now = [window convertBaseToScreen:[event locationInWindow]];
+    NSPoint now =
+        ui::ConvertPointFromWindowToScreen(window, [event locationInWindow]);
     frameOrigin.x += now.x - lastEventLoc.x;
     frameOrigin.y += now.y - lastEventLoc.y;
     [window setFrameOrigin:frameOrigin];
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm
index eb8de39..dd32269 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm
@@ -14,6 +14,7 @@
 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
 #import "chrome/browser/ui/cocoa/tabs/tab_view.h"
 #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
 
 const CGFloat kTearDistance = 36.0;
@@ -23,7 +24,8 @@
 static BOOL PointIsInsideView(NSPoint screenPoint, NSView* view) {
   if ([view window] == nil)
     return NO;
-  NSPoint windowPoint = [[view window] convertScreenToBase:screenPoint];
+  NSPoint windowPoint =
+      ui::ConvertPointFromScreenToWindow([view window], screenPoint);
   NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
   return [view mouse:viewPoint inRect:[view bounds]];
 }
@@ -383,9 +385,8 @@
     for (NSView* tabView in [draggedController_ tabViews]) {
       tabFrame = NSUnionRect(tabFrame, [tabView frame]);
     }
-    tabFrame.origin = [dragWindow_ convertBaseToScreen:tabFrame.origin];
-    tabFrame.origin = [[targetController_ window]
-                        convertScreenToBase:tabFrame.origin];
+    tabFrame = [dragWindow_ convertRectToScreen:tabFrame];
+    tabFrame = [[targetController_ window] convertRectFromScreen:tabFrame];
     tabFrame = [[targetController_ tabStripView]
                 convertRect:tabFrame fromView:nil];
     [targetController_ insertPlaceholderForTab:[draggedTab_ tabView]
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm
index 975b0b3..ada04dd 100644
--- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm
@@ -21,6 +21,7 @@
 #include "components/translate/core/browser/translate_ui_delegate.h"
 #include "content/public/browser/browser_context.h"
 #include "grit/components_strings.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #import "ui/base/cocoa/window_size_constants.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -166,7 +167,8 @@
 - (void)showWindow:(id)sender {
   BrowserWindowController* controller = [[self parentWindow] windowController];
   NSPoint anchorPoint = [[controller toolbarController] translateBubblePoint];
-  anchorPoint = [[self parentWindow] convertBaseToScreen:anchorPoint];
+  anchorPoint =
+      ui::ConvertPointFromWindowToScreen([self parentWindow], anchorPoint);
   [self setAnchorPoint:anchorPoint];
   [super showWindow:sender];
 }
diff --git a/chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm b/chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm
index 8c15b985..3d5b36b56 100644
--- a/chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm
+++ b/chrome/browser/ui/cocoa/validation_message_bubble_cocoa.mm
@@ -18,6 +18,7 @@
 #include "grit/theme_resources.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
 #import "ui/base/cocoa/base_view.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/flipped_view.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -148,7 +149,7 @@
   NSRect cocoaRect = [view flipRectToNSRect:anchor_in_root_view];
   NSRect windowRect = [view convertRect:cocoaRect toView:nil];
   NSPoint point = NSMakePoint(NSMidX(windowRect), NSMinY(windowRect));
-  return [[view window] convertBaseToScreen:point];
+  return ui::ConvertPointFromWindowToScreen([view window], point);
 }
 
 ValidationMessageBubbleCocoa::ValidationMessageBubbleCocoa(
diff --git a/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm b/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm
index bfae5ba..2c472ec 100644
--- a/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm
+++ b/chrome/browser/ui/cocoa/website_settings/chooser_bubble_ui_cocoa.mm
@@ -27,6 +27,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "skia/ext/skia_utils_mac.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/cocoa/controls/hyperlink_text_view.h"
 #include "ui/base/cocoa/window_size_constants.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -407,7 +408,8 @@
     anchor = NSMakePoint(NSMidX(contentFrame), NSMaxY(contentFrame));
   }
 
-  return [[self getExpectedParentWindow] convertBaseToScreen:anchor];
+  return ui::ConvertPointFromWindowToScreen([self getExpectedParentWindow],
+                                            anchor);
 }
 
 - (bool)hasLocationBar {
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 fb8f3dd..ae493f9 100644
--- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
@@ -33,6 +33,7 @@
 #include "content/public/browser/user_metrics.h"
 #include "grit/components_strings.h"
 #include "skia/ext/skia_utils_mac.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/controls/hyperlink_text_view.h"
 #import "ui/base/cocoa/menu_controller.h"
 #include "ui/base/cocoa/window_size_constants.h"
@@ -454,7 +455,8 @@
     anchor = NSMakePoint(NSMidX(contentFrame), NSMaxY(contentFrame));
   }
 
-  return [[self getExpectedParentWindow] convertBaseToScreen:anchor];
+  return ui::ConvertPointFromWindowToScreen([self getExpectedParentWindow],
+                                            anchor);
 }
 
 - (bool)hasLocationBar {
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 e3ceaff..75d6c50 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
@@ -25,6 +25,7 @@
 #include "grit/components_strings.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #import "testing/gtest_mac.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #import "ui/events/test/cocoa_test_event_utils.h"
@@ -363,7 +364,7 @@
       [BrowserWindowController browserWindowControllerForWindow:window];
   LocationBarViewMac* location_bar_bridge = [controller locationBarBridge];
   NSPoint expected = location_bar_bridge->GetPageInfoBubblePoint();
-  expected = [window convertBaseToScreen:expected];
+  expected = ui::ConvertPointFromWindowToScreen(window, expected);
   EXPECT_NSEQ(expected, anchor);
 }
 
@@ -379,7 +380,7 @@
   NSWindow* window = browser()->window()->GetNativeWindow();
   NSRect frame = [window frame];
   NSPoint expected = NSMakePoint(frame.size.width / 2, frame.size.height);
-  expected = [window convertBaseToScreen:expected];
+  expected = ui::ConvertPointFromWindowToScreen(window, expected);
   EXPECT_NSEQ(expected, anchor);
 }
 
diff --git a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
index 9934fcc2..1a4dad15 100644
--- a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
@@ -41,6 +41,7 @@
 #include "grit/components_google_chrome_strings.h"
 #include "grit/components_strings.h"
 #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/controls/hyperlink_button_cell.h"
 #import "ui/base/cocoa/flipped_view.h"
 #import "ui/base/cocoa/hover_image_button.h"
@@ -117,7 +118,7 @@
     LocationBarViewMac* location_bar = [controller locationBarBridge];
     if (location_bar) {
       NSPoint bubble_point = location_bar->GetPageInfoBubblePoint();
-      origin = [parent convertBaseToScreen:bubble_point];
+      origin = ui::ConvertPointFromWindowToScreen(parent, bubble_point);
     }
   }
   return origin;
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 5c516036..048140b 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -223,6 +223,7 @@
       is_mutating_(false),
       attach_x_(-1),
       attach_index_(-1),
+      window_finder_(new WindowFinder),
       weak_factory_(this) {
   instance_ = this;
 }
@@ -387,7 +388,8 @@
     }
   }
 
-  ContinueDragging(point_in_screen);
+  if (ContinueDragging(point_in_screen) == Liveness::DELETED)
+    return;
 }
 
 void TabDragController::EndDrag(EndDragReason reason) {
@@ -528,14 +530,19 @@
               pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance;
 }
 
-void TabDragController::ContinueDragging(const gfx::Point& point_in_screen) {
+TabDragController::Liveness TabDragController::ContinueDragging(
+    const gfx::Point& point_in_screen) {
   TRACE_EVENT1("views", "TabDragController::ContinueDragging",
                "point_in_screen", point_in_screen.ToString());
 
   DCHECK(attached_tabstrip_);
 
-  TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ?
-      GetTargetTabStripForPoint(point_in_screen) : source_tabstrip_;
+  TabStrip* target_tabstrip = source_tabstrip_;
+  if (detach_behavior_ == DETACHABLE &&
+      GetTargetTabStripForPoint(point_in_screen, &target_tabstrip) ==
+          Liveness::DELETED) {
+    return Liveness::DELETED;
+  }
   bool tab_strip_changed = (target_tabstrip != attached_tabstrip_);
 
   if (attached_tabstrip_) {
@@ -552,7 +559,7 @@
     did_restore_window_ = false;
     if (DragBrowserToNewTabStrip(target_tabstrip, point_in_screen) ==
         DRAG_BROWSER_RESULT_STOP) {
-      return;
+      return Liveness::ALIVE;
     }
   }
   if (is_dragging_window_) {
@@ -574,6 +581,7 @@
       }
     }
   }
+  return Liveness::ALIVE;
 }
 
 TabDragController::DragBrowserResultType
@@ -817,8 +825,10 @@
   return DETACH_ABOVE_OR_BELOW;
 }
 
-TabStrip* TabDragController::GetTargetTabStripForPoint(
-    const gfx::Point& point_in_screen) {
+TabDragController::Liveness TabDragController::GetTargetTabStripForPoint(
+    const gfx::Point& point_in_screen,
+    TabStrip** tab_strip) {
+  *tab_strip = nullptr;
   TRACE_EVENT1("views", "TabDragController::GetTargetTabStripForPoint",
                "point_in_screen", point_in_screen.ToString());
 
@@ -828,20 +838,29 @@
     gfx::Rect tabstrip_bounds = GetViewScreenBounds(attached_tabstrip_);
     if (DoesRectContainVerticalPointExpanded(tabstrip_bounds,
                                              kTouchVerticalDetachMagnetism,
-                                             point_in_screen.y()))
-      return attached_tabstrip_;
+                                             point_in_screen.y())) {
+      *tab_strip = attached_tabstrip_;
+      return Liveness::ALIVE;
+    }
   }
-  gfx::NativeWindow local_window =
-      GetLocalProcessWindow(point_in_screen, is_dragging_window_);
+  gfx::NativeWindow local_window;
+  const Liveness state = GetLocalProcessWindow(
+      point_in_screen, is_dragging_window_, &local_window);
+  if (state == Liveness::DELETED)
+    return Liveness::DELETED;
+
   // Do not allow dragging into a window with a modal dialog, it causes a weird
   // behavior.  See crbug.com/336691
   if (!GetModalTransient(local_window)) {
-    TabStrip* tab_strip = GetTabStripForWindow(local_window);
-    if (tab_strip && DoesTabStripContain(tab_strip, point_in_screen))
-      return tab_strip;
+    TabStrip* result = GetTabStripForWindow(local_window);
+    if (result && DoesTabStripContain(result, point_in_screen)) {
+      *tab_strip = result;
+      return Liveness::ALIVE;
+    }
   }
 
-  return is_dragging_window_ ? attached_tabstrip_ : NULL;
+  *tab_strip = is_dragging_window_ ? attached_tabstrip_ : nullptr;
+  return Liveness::ALIVE;
 }
 
 TabStrip* TabDragController::GetTabStripForWindow(gfx::NativeWindow window) {
@@ -1564,7 +1583,11 @@
 
 void TabDragController::BringWindowUnderPointToFront(
     const gfx::Point& point_in_screen) {
-  gfx::NativeWindow window = GetLocalProcessWindow(point_in_screen, true);
+  gfx::NativeWindow window;
+  if (GetLocalProcessWindow(point_in_screen, true, &window) ==
+      Liveness::DELETED) {
+    return;
+  }
 
   // Only bring browser windows to front - only windows with a TabStrip can
   // be tab drag targets.
@@ -1791,9 +1814,10 @@
   return point.OffsetFromOrigin();
 }
 
-gfx::NativeWindow TabDragController::GetLocalProcessWindow(
+TabDragController::Liveness TabDragController::GetLocalProcessWindow(
     const gfx::Point& screen_point,
-    bool exclude_dragged_view) {
+    bool exclude_dragged_view,
+    gfx::NativeWindow* window) {
   std::set<gfx::NativeWindow> exclude;
   if (exclude_dragged_view) {
     gfx::NativeWindow dragged_window =
@@ -1812,5 +1836,7 @@
       exclude.insert(browser->window()->GetNativeWindow());
   }
 #endif
-  return GetLocalProcessWindowAtPoint(screen_point, exclude);
+  base::WeakPtr<TabDragController> ref(weak_factory_.GetWeakPtr());
+  *window = window_finder_->GetLocalProcessWindowAtPoint(screen_point, exclude);
+  return ref ? Liveness::ALIVE : Liveness::DELETED;
 }
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h
index 7e47fa59..93223fd57 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h
@@ -34,9 +34,11 @@
 }
 class Browser;
 class Tab;
+class TabDragControllerTest;
 struct TabRendererData;
 class TabStrip;
 class TabStripModel;
+class WindowFinder;
 
 // TabDragController is responsible for managing the tab dragging session. When
 // the user presses the mouse on a tab a new TabDragController is created and
@@ -129,10 +131,17 @@
   void EndDrag(EndDragReason reason);
 
  private:
+  friend class TabDragControllerTest;
+
   // Used to indicate the direction the mouse has moved when attached.
   static const int kMovedMouseLeft  = 1 << 0;
   static const int kMovedMouseRight = 1 << 1;
 
+  enum class Liveness {
+    ALIVE,
+    DELETED,
+  };
+
   // Enumeration of the ways a drag session can end.
   enum EndDragType {
     // Drag session exited normally: the user released the mouse.
@@ -246,7 +255,8 @@
 
   // Invoked once a drag has started to determine the appropriate tabstrip to
   // drag to (which may be the currently attached one).
-  void ContinueDragging(const gfx::Point& point_in_screen);
+  Liveness ContinueDragging(const gfx::Point& point_in_screen)
+      WARN_UNUSED_RESULT;
 
   // Transitions dragging from |attached_tabstrip_| to |target_tabstrip|.
   // |target_tabstrip| is NULL if the mouse is not over a valid tab strip.  See
@@ -279,7 +289,8 @@
 
   // Returns the compatible TabStrip to drag to at the specified point (screen
   // coordinates), or NULL if there is none.
-  TabStrip* GetTargetTabStripForPoint(const gfx::Point& point_in_screen);
+  Liveness GetTargetTabStripForPoint(const gfx::Point& point_in_screen,
+                                     TabStrip** tab_strip);
 
   // Returns true if |tabstrip| contains the specified point in screen
   // coordinates.
@@ -445,10 +456,11 @@
     return (move_behavior_ == MOVE_VISIBILE_TABS) != 0;
   }
 
-  // Returns the NativeWindow at the specified point. If |exclude_dragged_view|
-  // is true, then the dragged view is not considered.
-  gfx::NativeWindow GetLocalProcessWindow(const gfx::Point& screen_point,
-                                          bool exclude_dragged_view);
+  // Returns the NativeWindow in |window| at the specified point. If
+  // |exclude_dragged_view| is true, then the dragged view is not considered.
+  Liveness GetLocalProcessWindow(const gfx::Point& screen_point,
+                                 bool exclude_dragged_view,
+                                 gfx::NativeWindow* window) WARN_UNUSED_RESULT;
 
   // Handles registering for notifications.
   content::NotificationRegistrar registrar_;
@@ -594,6 +606,8 @@
 
   scoped_ptr<ui::EventHandler> escape_tracker_;
 
+  scoped_ptr<WindowFinder> window_finder_;
+
   base::WeakPtrFactory<TabDragController> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(TabDragController);
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 85648dbc..46d515c4 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
@@ -28,6 +28,7 @@
 #include "chrome/browser/ui/views/tabs/tab.h"
 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
+#include "chrome/browser/ui/views/tabs/window_finder.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -192,6 +193,13 @@
   return browser2;
 }
 
+void TabDragControllerTest::SetWindowFinderForTabStrip(
+    TabStrip* tab_strip,
+    scoped_ptr<WindowFinder> window_finder) {
+  ASSERT_TRUE(tab_strip->drag_controller_.get());
+  tab_strip->drag_controller_->window_finder_ = std::move(window_finder);
+}
+
 namespace {
 
 enum InputSource {
@@ -703,6 +711,59 @@
 
 namespace {
 
+// WindowFinder that calls OnMouseCaptureLost() from
+// GetLocalProcessWindowAtPoint().
+class CaptureLoseWindowFinder : public WindowFinder {
+ public:
+  explicit CaptureLoseWindowFinder(TabStrip* tab_strip)
+      : tab_strip_(tab_strip) {}
+  ~CaptureLoseWindowFinder() override {}
+
+  // WindowFinder:
+  gfx::NativeWindow GetLocalProcessWindowAtPoint(
+      const gfx::Point& screen_point,
+      const std::set<gfx::NativeWindow>& ignore) override {
+    static_cast<views::View*>(tab_strip_)->OnMouseCaptureLost();
+    return nullptr;
+  }
+
+ private:
+  TabStrip* tab_strip_;
+
+  DISALLOW_COPY_AND_ASSIGN(CaptureLoseWindowFinder);
+};
+
+}  // namespace
+
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
+// TODO(sky,sad): Disabled as it fails due to resize locks with a real
+// compositor. crbug.com/331924
+#define MAYBE_CaptureLostDuringDrag DISABLED_CaptureLostDuringDrag
+#else
+#define MAYBE_CaptureLostDuringDrag CaptureLostDuringDrag
+#endif
+// Calls OnMouseCaptureLost() from WindowFinder::GetLocalProcessWindowAtPoint()
+// and verifies we don't crash. This simulates a crash seen on windows.
+IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
+                       MAYBE_CaptureLostDuringDrag) {
+  TabStrip* tab_strip = GetTabStripForBrowser(browser());
+
+  // Add another tab to browser().
+  AddTabAndResetBrowser(browser());
+
+  // Press on first tab so drag is active. Reset WindowFinder to one that causes
+  // capture to be lost from within GetLocalProcessWindowAtPoint(), then
+  // continue drag. The capture lost should trigger the drag to cancel.
+  ASSERT_TRUE(PressInput(GetCenterInScreenCoordinates(tab_strip->tab_at(0))));
+  ASSERT_TRUE(tab_strip->IsDragSessionActive());
+  SetWindowFinderForTabStrip(
+      tab_strip, make_scoped_ptr(new CaptureLoseWindowFinder(tab_strip)));
+  ASSERT_TRUE(DragInputTo(GetCenterInScreenCoordinates(tab_strip->tab_at(1))));
+  ASSERT_FALSE(tab_strip->IsDragSessionActive());
+}
+
+namespace {
+
 void DetachToOwnWindowStep2(DetachToBrowserTabDragControllerTest* test) {
   if (test->input_source() == INPUT_SOURCE_TOUCH)
     ASSERT_TRUE(test->ReleaseInput());
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h
index 8aa0a40..03bc238 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h
@@ -14,6 +14,7 @@
 class BrowserList;
 class TabStrip;
 class TabStripModel;
+class WindowFinder;
 
 namespace content {
 class WebContents;
@@ -45,6 +46,9 @@
   // side by side.
   Browser* CreateAnotherWindowBrowserAndRelayout();
 
+  void SetWindowFinderForTabStrip(TabStrip* tab_strip,
+                                  scoped_ptr<WindowFinder> window_finder);
+
   const BrowserList* browser_list;
 
  private:
diff --git a/chrome/browser/ui/views/tabs/window_finder.cc b/chrome/browser/ui/views/tabs/window_finder.cc
new file mode 100644
index 0000000..7f95d12
--- /dev/null
+++ b/chrome/browser/ui/views/tabs/window_finder.cc
@@ -0,0 +1,8 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/tabs/window_finder.h"
+
+WindowFinder::WindowFinder() {}
+WindowFinder::~WindowFinder() {}
diff --git a/chrome/browser/ui/views/tabs/window_finder.h b/chrome/browser/ui/views/tabs/window_finder.h
index f234306d..160fb6a 100644
--- a/chrome/browser/ui/views/tabs/window_finder.h
+++ b/chrome/browser/ui/views/tabs/window_finder.h
@@ -7,7 +7,7 @@
 
 #include <set>
 
-#include "chrome/browser/ui/host_desktop.h"
+#include "ui/gfx/native_widget_types.h"
 
 namespace aura {
 class Window;
@@ -17,9 +17,17 @@
 class Point;
 }
 
-// Returns the Window at the specified point, ignoring the windows in |ignore|.
-gfx::NativeWindow GetLocalProcessWindowAtPoint(
-    const gfx::Point& screen_point,
-    const std::set<gfx::NativeWindow>& ignore);
+class WindowFinder {
+ public:
+  WindowFinder();
+  virtual ~WindowFinder();
+
+  virtual gfx::NativeWindow GetLocalProcessWindowAtPoint(
+      const gfx::Point& screen_point,
+      const std::set<gfx::NativeWindow>& ignore);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WindowFinder);
+};
 
 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_WINDOW_FINDER_H_
diff --git a/chrome/browser/ui/views/tabs/window_finder_chromeos.cc b/chrome/browser/ui/views/tabs/window_finder_chromeos.cc
index fae410e9..b276599 100644
--- a/chrome/browser/ui/views/tabs/window_finder_chromeos.cc
+++ b/chrome/browser/ui/views/tabs/window_finder_chromeos.cc
@@ -11,7 +11,7 @@
     const gfx::Point& screen_point,
     const std::set<gfx::NativeWindow>& ignore);
 
-gfx::NativeWindow GetLocalProcessWindowAtPoint(
+gfx::NativeWindow WindowFinder::GetLocalProcessWindowAtPoint(
     const gfx::Point& screen_point,
     const std::set<gfx::NativeWindow>& ignore) {
   return GetLocalProcessWindowAtPointAsh(screen_point, ignore);
diff --git a/chrome/browser/ui/views/tabs/window_finder_mac.mm b/chrome/browser/ui/views/tabs/window_finder_mac.mm
index 8bc2303..8c1a344f 100644
--- a/chrome/browser/ui/views/tabs/window_finder_mac.mm
+++ b/chrome/browser/ui/views/tabs/window_finder_mac.mm
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/views/tabs/window_finder.h"
 
-gfx::NativeWindow GetLocalProcessWindowAtPoint(
+gfx::NativeWindow WindowFinder::GetLocalProcessWindowAtPoint(
     const gfx::Point& screen_point,
     const std::set<gfx::NativeWindow>& ignore) {
   NOTIMPLEMENTED();
diff --git a/chrome/browser/ui/views/tabs/window_finder_win.cc b/chrome/browser/ui/views/tabs/window_finder_win.cc
index 1ad001e0..5b4e528 100644
--- a/chrome/browser/ui/views/tabs/window_finder_win.cc
+++ b/chrome/browser/ui/views/tabs/window_finder_win.cc
@@ -233,7 +233,7 @@
 
 }  // namespace
 
-gfx::NativeWindow GetLocalProcessWindowAtPoint(
+gfx::NativeWindow WindowFinder::GetLocalProcessWindowAtPoint(
     const gfx::Point& screen_point,
     const std::set<gfx::NativeWindow>& ignore) {
   return LocalProcessWindowFinder::GetProcessWindowAtPoint(
diff --git a/chrome/browser/ui/views/tabs/window_finder_x11.cc b/chrome/browser/ui/views/tabs/window_finder_x11.cc
index 0fa61919..c96e03c 100644
--- a/chrome/browser/ui/views/tabs/window_finder_x11.cc
+++ b/chrome/browser/ui/views/tabs/window_finder_x11.cc
@@ -20,7 +20,7 @@
 
 }  // anonymous namespace
 
-gfx::NativeWindow GetLocalProcessWindowAtPoint(
+gfx::NativeWindow WindowFinder::GetLocalProcessWindowAtPoint(
     const gfx::Point& screen_point,
     const std::set<gfx::NativeWindow>& ignore) {
   // The X11 server is the canonical state of what the window stacking order
diff --git a/chrome/browser/ui/webui/settings/OWNERS b/chrome/browser/ui/webui/settings/OWNERS
index 52b91305..300b7b9 100644
--- a/chrome/browser/ui/webui/settings/OWNERS
+++ b/chrome/browser/ui/webui/settings/OWNERS
@@ -1,4 +1,5 @@
 dbeam@chromium.org
+dpapad@chromium.org
 dschuyler@chromium.org
 michaelpg@chromium.org
 stevenjb@chromium.org
diff --git a/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h b/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h
index b0c3f567..4741f97c 100644
--- a/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h
+++ b/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "chrome/browser/signin/easy_unlock_service_observer.h"
-#include "content/public/browser/web_ui_message_handler.h"
+#include "chrome/browser/ui/webui/settings/md_settings_ui.h"
 
 namespace content {
 class WebUIDataSource;
@@ -18,7 +18,7 @@
 namespace chromeos {
 namespace settings {
 
-class EasyUnlockSettingsHandler : public content::WebUIMessageHandler,
+class EasyUnlockSettingsHandler : public ::settings::SettingsPageUIHandler,
                                   public EasyUnlockServiceObserver {
  public:
   // Returns nullptr if EasyUnlock is not allowed for this device.
@@ -28,10 +28,10 @@
 
   ~EasyUnlockSettingsHandler() override;
 
-  // WebUIMessageHandler
+  // SettingsPageUIHandler:
   void RegisterMessages() override;
 
-  // EasyUnlockServiceObserver
+  // EasyUnlockServiceObserver:
   void OnTurnOffOperationStatusChanged() override;
 
  protected:
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 119e569..797b51a 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -202,6 +202,21 @@
        IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_EMAIL},
       {"certificateManagerCaTrustEditDialogObjSign",
        IDS_SETTINGS_CERTIFICATE_MANAGER_CA_TRUST_EDIT_DIALOG_OBJ_SIGN},
+       // Certificate delete confirmation dialog.
+      {"certificateManagerDeleteUserTitle",
+       IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_TITLE},
+      {"certificateManagerDeleteUserDescription",
+       IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_USER_DESCRIPTION},
+      {"certificateManagerDeleteServerTitle",
+       IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_TITLE},
+      {"certificateManagerDeleteServerDescription",
+       IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_SERVER_DESCRIPTION},
+      {"certificateManagerDeleteCaTitle",
+       IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_TITLE},
+      {"certificateManagerDeleteCaDescription",
+       IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_CA_DESCRIPTION},
+      {"certificateManagerDeleteOtherTitle",
+       IDS_SETTINGS_CERTIFICATE_MANAGER_DELETE_OTHER_TITLE},
   };
   AddLocalizedStringsBulk(html_source, localized_strings,
                           arraysize(localized_strings));
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc
index 2743fcbb..6ee2da9 100644
--- a/chrome/browser/ui/webui/settings/md_settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -125,12 +125,16 @@
 MdSettingsUI::~MdSettingsUI() {
 }
 
-void MdSettingsUI::AddSettingsPageUIHandler(
-    content::WebUIMessageHandler* handler_raw) {
-  scoped_ptr<content::WebUIMessageHandler> handler(handler_raw);
-  DCHECK(handler.get());
+void MdSettingsUI::RenderViewReused(
+    content::RenderViewHost* /*render_view_host*/) {
+  for (SettingsPageUIHandler* handler : handlers_)
+    handler->RenderViewReused();
+}
 
-  web_ui()->AddMessageHandler(handler.release());
+void MdSettingsUI::AddSettingsPageUIHandler(SettingsPageUIHandler* handler) {
+  DCHECK(handler);
+  handlers_.insert(handler);
+  web_ui()->AddMessageHandler(handler);  // |handler| is owned by |web_ui()|.
 }
 
 void MdSettingsUI::DidStartProvisionalLoadForFrame(
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.h b/chrome/browser/ui/webui/settings/md_settings_ui.h
index 301f4f2..0ebdcb9cf 100644
--- a/chrome/browser/ui/webui/settings/md_settings_ui.h
+++ b/chrome/browser/ui/webui/settings/md_settings_ui.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_SETTINGS_MD_SETTINGS_UI_H_
 
 #include <string>
-#include <vector>
+#include <unordered_set>
 
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
@@ -24,9 +24,13 @@
   SettingsPageUIHandler();
   ~SettingsPageUIHandler() override;
 
-  // WebUIMessageHandler implementation.
+  // WebUIMessageHandler:
   void RegisterMessages() override {}
 
+  // Called when a navigation re-uses a renderer process (i.e. reload).
+  // TODO(dbeam): move to WebUIMessageHandler?
+  virtual void RenderViewReused() {}
+
  protected:
   // Helper method for responding to JS requests initiated with
   // cr.sendWithPromise(), for the case where the returned promise should be
@@ -51,7 +55,10 @@
   explicit MdSettingsUI(content::WebUI* web_ui);
   ~MdSettingsUI() override;
 
-  // Overridden from content::WebContentsObserver:
+  // content::WebUIController:
+  void RenderViewReused(content::RenderViewHost* render_view_host) override;
+
+  // content::WebContentsObserver:
   void DidStartProvisionalLoadForFrame(
       content::RenderFrameHost* render_frame_host,
       const GURL& validated_url,
@@ -62,7 +69,10 @@
   void DocumentOnLoadCompletedInMainFrame() override;
 
  private:
-  void AddSettingsPageUIHandler(content::WebUIMessageHandler* handler);
+  void AddSettingsPageUIHandler(SettingsPageUIHandler* handler);
+
+  // Weak references; all |handlers_| are owned by |web_ui()|.
+  std::unordered_set<SettingsPageUIHandler*> handlers_;
 
   base::Time load_start_time_;
 
diff --git a/chrome/browser/ui/webui/settings/people_handler.h b/chrome/browser/ui/webui/settings/people_handler.h
index 0ae1476..4556b74 100644
--- a/chrome/browser/ui/webui/settings/people_handler.h
+++ b/chrome/browser/ui/webui/settings/people_handler.h
@@ -14,11 +14,11 @@
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/sync/sync_startup_tracker.h"
+#include "chrome/browser/ui/webui/settings/md_settings_ui.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/signin/core/browser/signin_manager_base.h"
 #include "components/sync_driver/sync_service_observer.h"
-#include "content/public/browser/web_ui_message_handler.h"
 
 #if defined(OS_CHROMEOS)
 #include "content/public/browser/notification_observer.h"
@@ -40,7 +40,7 @@
 
 namespace settings {
 
-class PeopleHandler : public content::WebUIMessageHandler,
+class PeopleHandler : public SettingsPageUIHandler,
                       public SigninManagerBase::Observer,
                       public SyncStartupTracker::Observer,
                       public LoginUIService::LoginUI,
@@ -53,7 +53,7 @@
   explicit PeopleHandler(Profile* profile);
   ~PeopleHandler() override;
 
-  // content::WebUIMessageHandler implementation.
+  // SettingsPageUIHandler implementation.
   void RegisterMessages() override;
 
   // SyncStartupTracker::Observer implementation.
diff --git a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
index 233df7c3..2a2dd77 100644
--- a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
@@ -27,19 +27,24 @@
     return;
 
   web_ui()->RegisterMessageCallback("addStartupPage",
-      base::Bind(&StartupPagesHandler::AddStartupPage,
+      base::Bind(&StartupPagesHandler::HandleAddStartupPage,
                  base::Unretained(this)));
   web_ui()->RegisterMessageCallback("onStartupPrefsPageLoad",
-      base::Bind(&StartupPagesHandler::OnStartupPrefsPageLoad,
+      base::Bind(&StartupPagesHandler::HandleOnStartupPrefsPageLoad,
                  base::Unretained(this)));
   web_ui()->RegisterMessageCallback("removeStartupPage",
-      base::Bind(&StartupPagesHandler::RemoveStartupPage,
+      base::Bind(&StartupPagesHandler::HandleRemoveStartupPage,
                  base::Unretained(this)));
   web_ui()->RegisterMessageCallback("setStartupPagesToCurrentPages",
-      base::Bind(&StartupPagesHandler::SetStartupPagesToCurrentPages,
+      base::Bind(&StartupPagesHandler::HandleSetStartupPagesToCurrentPages,
                  base::Unretained(this)));
 }
 
+void StartupPagesHandler::RenderViewReused() {
+  startup_custom_pages_table_model_.SetObserver(nullptr);
+  pref_change_registrar_.RemoveAll();
+}
+
 void StartupPagesHandler::OnModelChanged() {
   base::ListValue startup_pages;
   int page_count = startup_custom_pages_table_model_.RowCount();
@@ -70,7 +75,7 @@
   OnModelChanged();
 }
 
-void StartupPagesHandler::AddStartupPage(const base::ListValue* args) {
+void StartupPagesHandler::HandleAddStartupPage(const base::ListValue* args) {
   std::string url_string;
   if (!args->GetString(0, &url_string)) {
     DLOG(ERROR) << "Missing URL string parameter";
@@ -92,7 +97,8 @@
   SaveStartupPagesPref();
 }
 
-void StartupPagesHandler::OnStartupPrefsPageLoad(const base::ListValue* args) {
+void StartupPagesHandler::HandleOnStartupPrefsPageLoad(
+    const base::ListValue* args) {
   startup_custom_pages_table_model_.SetObserver(this);
 
   PrefService* prefService = Profile::FromWebUI(web_ui())->GetPrefs();
@@ -114,7 +120,7 @@
   startup_custom_pages_table_model_.SetURLs(startup_pref.urls);
 }
 
-void StartupPagesHandler::RemoveStartupPage(const base::ListValue* args) {
+void StartupPagesHandler::HandleRemoveStartupPage(const base::ListValue* args) {
   int selected_index;
   if (!args->GetInteger(0, &selected_index)) {
     DLOG(ERROR) << "Missing index parameter";
@@ -131,6 +137,12 @@
   SaveStartupPagesPref();
 }
 
+void StartupPagesHandler::HandleSetStartupPagesToCurrentPages(
+    const base::ListValue* args) {
+  startup_custom_pages_table_model_.SetToCurrentlyOpenPages();
+  SaveStartupPagesPref();
+}
+
 void StartupPagesHandler::SaveStartupPagesPref() {
   PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
 
@@ -143,12 +155,6 @@
   SessionStartupPref::SetStartupPref(prefs, pref);
 }
 
-void StartupPagesHandler::SetStartupPagesToCurrentPages(
-    const base::ListValue* args) {
-  startup_custom_pages_table_model_.SetToCurrentlyOpenPages();
-  SaveStartupPagesPref();
-}
-
 void StartupPagesHandler::UpdateStartupPages() {
   const SessionStartupPref startup_pref = SessionStartupPref::GetStartupPref(
       Profile::FromWebUI(web_ui())->GetPrefs());
diff --git a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.h b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.h
index f1f4868..64a4a76 100644
--- a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.h
+++ b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.h
@@ -28,8 +28,9 @@
   explicit StartupPagesHandler(content::WebUI* webui);
   ~StartupPagesHandler() override;
 
-  // OptionsPageUIHandler:
+  // SettingsPageUIHandler:
   void RegisterMessages() override;
+  void RenderViewReused() override;
 
   // ui::TableModelObserver:
   void OnModelChanged() override;
@@ -40,20 +41,20 @@
  private:
   // Adds a startup page with the given URL after the given index.
   // Called from WebUI.
-  void AddStartupPage(const base::ListValue* args);
+  void HandleAddStartupPage(const base::ListValue* args);
 
   // Informs the code that the JS page has loaded. Called from WebUI.
-  void OnStartupPrefsPageLoad(const base::ListValue* args);
+  void HandleOnStartupPrefsPageLoad(const base::ListValue* args);
 
   // Removes the startup page at the given index. Called from WebUI.
-  void RemoveStartupPage(const base::ListValue* args);
+  void HandleRemoveStartupPage(const base::ListValue* args);
+
+  // Sets the startup page set to the current pages. Called from WebUI.
+  void HandleSetStartupPagesToCurrentPages(const base::ListValue* args);
 
   // Stores the current state of the startup page preferences.
   void SaveStartupPagesPref();
 
-  // Sets the startup page set to the current pages. Called from WebUI.
-  void SetStartupPagesToCurrentPages(const base::ListValue* args);
-
   // Informs the that the preferences have changed.  It is a callback
   // for the pref changed registrar.
   void UpdateStartupPages();
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index e66e88a..32c70a9 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2466,6 +2466,7 @@
       'browser/ui/views/tabs/tab_strip_controller.h',
       'browser/ui/views/tabs/tab_strip_layout.cc',
       'browser/ui/views/tabs/tab_strip_layout.h',
+      'browser/ui/views/tabs/window_finder.cc',
       'browser/ui/views/tabs/window_finder.h',
       'browser/ui/views/tabs/window_finder_chromeos.cc',
       'browser/ui/views/tabs/window_finder_mac.mm',
diff --git a/chrome/common/extensions/api/PRESUBMIT.py b/chrome/common/extensions/api/PRESUBMIT.py
new file mode 100644
index 0000000..c4dc1aa3
--- /dev/null
+++ b/chrome/common/extensions/api/PRESUBMIT.py
@@ -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.
+
+"""Chromium presubmit script for src/extensions/common.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details on the presubmit API built into depot_tools.
+"""
+
+import sys
+
+
+def _CheckExterns(input_api, output_api):
+  original_sys_path = sys.path
+
+  join = input_api.os_path.join
+  api_root = input_api.PresubmitLocalPath()
+  src_root = join(api_root, '..', '..', '..', '..')
+  try:
+    sys.path.append(join(src_root, 'extensions', 'common', 'api'))
+    from externs_checker import ExternsChecker
+  finally:
+    sys.path = original_sys_path
+
+  externs_root = join(src_root, 'third_party', 'closure_compiler', 'externs')
+
+  api_pair_names = {
+    'autofill_private.idl': 'autofill_private.js',
+    'developer_private.idl': 'developer_private.js',
+    'bookmark_manager_private.json': 'bookmark_manager_private.js',
+    'command_line_private.json': 'command_line_private.js',
+    'file_manager_private.idl': 'file_manager_private.js',
+    'language_settings_private.idl': 'language_settings_private.js',
+    'metrics_private.json': 'metrics_private.js',
+    'passwords_private.idl': 'passwords_private.js',
+    'system_private.json': 'system_private.js',
+    'users_private.idl': 'users_private.js',
+    # TODO(rdevlin.cronin): Add more!
+  }
+  normpath = input_api.os_path.normpath
+  api_pairs = {
+      normpath(join(api_root, k)):
+          normpath(join(externs_root, v)) for k, v in api_pair_names.items()
+  }
+
+  return ExternsChecker(input_api, output_api, api_pairs).RunChecks()
+
+
+def CheckChangeOnUpload(input_api, output_api):
+  return _CheckExterns(input_api, output_api)
diff --git a/chrome/renderer/page_load_histograms.cc b/chrome/renderer/page_load_histograms.cc
index 56d2cee..20e744d1 100644
--- a/chrome/renderer/page_load_histograms.cc
+++ b/chrome/renderer/page_load_histograms.cc
@@ -881,10 +881,6 @@
     return;
   }
 
-  // Ignore multipart requests.
-  if (frame->dataSource()->response().isMultipartPayload())
-    return;
-
   DocumentState* document_state =
       DocumentState::FromDataSource(frame->dataSource());
 
diff --git a/chrome/renderer/prerender/prerender_extra_data.cc b/chrome/renderer/prerender/prerender_extra_data.cc
index 842446d3..15fee44 100644
--- a/chrome/renderer/prerender/prerender_extra_data.cc
+++ b/chrome/renderer/prerender/prerender_extra_data.cc
@@ -23,8 +23,8 @@
 // static
 const PrerenderExtraData& PrerenderExtraData::FromPrerender(
     const blink::WebPrerender& prerender) {
-  DCHECK(prerender.extraData());
-  return static_cast<const PrerenderExtraData&>(*prerender.extraData());
+  DCHECK(prerender.getExtraData());
+  return static_cast<const PrerenderExtraData&>(*prerender.getExtraData());
 }
 
 }  // namespace prerender
diff --git a/chrome/test/base/interactive_test_utils_cocoa.mm b/chrome/test/base/interactive_test_utils_cocoa.mm
index 228c0a2..ee4e8c2 100644
--- a/chrome/test/base/interactive_test_utils_cocoa.mm
+++ b/chrome/test/base/interactive_test_utils_cocoa.mm
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #import "chrome/browser/ui/cocoa/view_id_util.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 
 namespace ui_test_utils {
 
@@ -32,7 +33,7 @@
   NSRect bounds = [view bounds];
   NSPoint center = NSMakePoint(NSMidX(bounds), NSMidY(bounds));
   center = [view convertPoint:center toView:nil];
-  center = [window convertBaseToScreen:center];
+  center = ui::ConvertPointFromWindowToScreen(window, center);
   center = NSMakePoint(center.x, [screen frame].size.height - center.y);
 
   ui_controls::SendMouseMoveNotifyWhenDone(
diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc
index 9f52f06..392ff45b 100644
--- a/chrome/test/base/v8_unit_test.cc
+++ b/chrome/test/base/v8_unit_test.cc
@@ -11,6 +11,7 @@
 #include "base/strings/stringprintf.h"
 #include "chrome/common/chrome_paths.h"
 #include "third_party/WebKit/public/web/WebKit.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 
 namespace {
 
@@ -95,6 +96,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Value> function_property =
       context->Global()->Get(v8::String::NewFromUtf8(isolate, "runTest"));
@@ -209,6 +211,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
   v8::Local<v8::String> source =
       v8::String::NewFromUtf8(isolate,
                               script_source.data(),
@@ -257,6 +260,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Value> function_property = context->Global()->Get(
       v8::String::NewFromUtf8(isolate, function_name.c_str()));
diff --git a/chrome/test/data/extensions/api_test/desktop_capture/test.js b/chrome/test/data/extensions/api_test/desktop_capture/test.js
index 48956ed..cacaab2 100644
--- a/chrome/test/data/extensions/api_test/desktop_capture/test.js
+++ b/chrome/test/data/extensions/api_test/desktop_capture/test.js
@@ -2,6 +2,32 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+function onPickerResult(request_audio, audio_track_num, id) {
+  chrome.test.assertEq("string", typeof id);
+  chrome.test.assertTrue(id != "");
+  var video_constraint = { mandatory: { chromeMediaSource: "desktop",
+                                        chromeMediaSourceId: id } };
+  var audio_constraint = request_audio ? video_constraint : false;
+  navigator.webkitGetUserMedia({
+    audio: audio_constraint,
+    video: video_constraint
+  },
+    function(stream) {
+      if (audio_track_num != null)
+        chrome.test.assertEq(audio_track_num, stream.getAudioTracks().length);
+      chrome.test.succeed();
+  }, chrome.test.fail);
+}
+
+// We can support audio for screen share on Windows. For ChromeOS, it depends
+// on whether USE_CRAS is on or not, thus we disable the check here. We cannot
+// support audio on other platforms.
+var expected_audio_tracks_for_screen_share = 0;
+if (navigator.appVersion.indexOf("Windows") != -1)
+  expected_audio_tracks_for_screen_share = 1;
+else if (navigator.appVersion.indexOf("CrOS") != -1)
+  expected_audio_tracks_for_screen_share = null;
+
 chrome.test.runTests([
   function emptySourceList() {
     chrome.desktopCapture.chooseDesktopMedia(
@@ -31,7 +57,7 @@
         }));
   },
 
-  // For the following two tests FakeDestkopPickerFactory will verify that
+  // For the following four tests FakeDestkopPickerFactory will verify that
   // the right set of sources is selected when creating picker model.
   function screensOnly() {
     chrome.desktopCapture.chooseDesktopMedia(
@@ -43,21 +69,23 @@
         ["window"], chrome.test.callbackPass(function(id) {}));
   },
 
+  function tabOnly() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["tab"],
+        chrome.test.succeed);
+  },
+
+  function audioShare() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["screen", "window", "tab", "audio"],
+        chrome.test.succeed);
+  },
+
   // Show window picker and then get the selected stream using
   // getUserMedia().
   function chooseMediaAndGetStream() {
-    function onPickerResult(id) {
-      chrome.test.assertEq("string", typeof id);
-      chrome.test.assertTrue(id != "");
-      navigator.webkitGetUserMedia({
-        audio: false,
-        video: { mandatory: { chromeMediaSource: "desktop",
-                              chromeMediaSourceId: id } }
-      }, chrome.test.succeed, chrome.test.fail);
-    }
-
     chrome.desktopCapture.chooseDesktopMedia(
-        ["screen", "window"], onPickerResult);
+        ["screen", "window"], onPickerResult.bind(undefined, false, 0));
   },
 
   // Same as above but attempts to specify invalid source id.
@@ -81,5 +109,48 @@
     chrome.test.assertEq("number", typeof requestId);
     chrome.desktopCapture.cancelChooseDesktopMedia(requestId);
     chrome.test.succeed();
+  },
+
+  // For the following six, they all request audio track. Based on user's
+  // permission and the source type, it may or may not actually get the audio
+  // track.
+  // In detail:
+  //  1. We cannot support audio for Window share;
+  //  2. We can support audio for Tab share;
+  //  3. We can support audio for Screen share on Windows;
+  //  4. We can support audio for Screen Share on ChromeOS if USE_CRAS is on;
+  //  5. To actually get audio track, user permission is always necessary;
+  //  6. To actually get audio track, getUserMedia() should set audio
+  //     constraint.
+  function tabShareWithAudioPermissionGetStream() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["tab", "audio"], onPickerResult.bind(undefined, true, 1));
+  },
+
+  function windowShareWithAudioPermissionGetStream() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["window", "audio"], onPickerResult.bind(undefined, true, 0));
+  },
+
+  function screenShareWithAudioPermissionGetStream() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["screen", "audio"],
+        onPickerResult.bind(undefined, true,
+                            expected_audio_tracks_for_screen_share));
+  },
+
+  function tabShareWithoutAudioPermissionGetStream() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["tab", "audio"], onPickerResult.bind(undefined, true, 0));
+  },
+
+  function windowShareWithoutAudioPermissionGetStream() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["window", "audio"], onPickerResult.bind(undefined, true, 0));
+  },
+
+  function screenShareWithoutAudioPermissionGetStream() {
+    chrome.desktopCapture.chooseDesktopMedia(
+        ["screen", "audio"], onPickerResult.bind(undefined, true, 0));
   }
 ]);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index ad5a219..2ab6ae2 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2675,6 +2675,9 @@
     ]
   },
 
+  "UsbDetachableWhitelist": {
+  },
+
   "----- Chrome Frame policies -------------------------------------------": {},
 
   "ChromeFrameRendererSettings": {
diff --git a/chrome/test/data/webui/settings/certificate_manager_page_test.js b/chrome/test/data/webui/settings/certificate_manager_page_test.js
index b43390d..0578fc3 100644
--- a/chrome/test/data/webui/settings/certificate_manager_page_test.js
+++ b/chrome/test/data/webui/settings/certificate_manager_page_test.js
@@ -15,8 +15,9 @@
     /** @private {!Map<string, !PromiseResolver>} */
     this.resolverMap_ = new Map();
     var wrapperMethods = [
-      'getCaCertificateTrust',
+      'deleteCertificate',
       'editCaCertificateTrust',
+      'getCaCertificateTrust',
     ];
     wrapperMethods.forEach(this.resetResolver, this);
 
@@ -62,6 +63,12 @@
       });
       return Promise.resolve();
     },
+
+    /** @override */
+    deleteCertificate: function(id) {
+      this.resolverMap_.get('deleteCertificate').resolve(id);
+      return Promise.resolve();
+    },
   };
 
   /** @return {!CertificateSubnode} */
@@ -136,7 +143,51 @@
     });
   }
 
+  function registerDeleteDialogTests() {
+    /** @type {?SettingsCertificateDeleteConfirmationDialogElement} */
+    var dialog = null;
+
+    /** @type {?TestCertificatesBrowserProxy} */
+    var browserProxy = null;
+
+    /** @type {!CertificateSubnode} */
+    var model = createSampleCertificateSubnode();
+
+    suite('CertificateDeleteConfirmationDialogTests', function() {
+      setup(function() {
+        browserProxy = new TestCertificatesBrowserProxy();
+        settings.CertificatesBrowserProxyImpl.instance_ = browserProxy;
+        PolymerTest.clearBody();
+        dialog = document.createElement(
+            'settings-certificate-delete-confirmation-dialog');
+        dialog.model = model;
+        dialog.certificateType = settings.CertificateType.PERSONAL;
+        document.body.appendChild(dialog);
+      });
+
+      teardown(function() { dialog.remove(); });
+
+      test('DeleteSuccess', function() {
+        assertTrue(dialog.$.dialog.opened);
+        // Check that the dialog title includes the certificate name.
+        var titleEl = Polymer.dom(dialog.$.dialog).querySelector('.title');
+        assertTrue(titleEl.textContent.includes(model.name));
+
+        // Simulate clicking 'OK'.
+        MockInteractions.tap(dialog.$.ok);
+
+        return browserProxy.whenCalled('deleteCertificate').then(
+            function(id) {
+              assertEquals(model.id, id);
+              // Check that the dialog is closed.
+              assertFalse(dialog.$.dialog.opened);
+            });
+      });
+    });
+  }
+
   return {
     registerCaTrustEditDialogTests: registerCaTrustEditDialogTests,
+    registerDeleteDialogTests: registerDeleteDialogTests,
   };
 });
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 1ebb584..477f993 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -158,6 +158,7 @@
 
 TEST_F('CrSettingsCertificateManagerTest', 'CertificateManager', function() {
   certificate_manager_page.registerCaTrustEditDialogTests();
+  certificate_manager_page.registerDeleteDialogTests();
   mocha.run();
 });
 
diff --git a/chromecast/app/linux/cast_crash_reporter_client.cc b/chromecast/app/linux/cast_crash_reporter_client.cc
index e90d4f15..fc88ed3 100644
--- a/chromecast/app/linux/cast_crash_reporter_client.cc
+++ b/chromecast/app/linux/cast_crash_reporter_client.cc
@@ -52,7 +52,8 @@
     const std::string& process_type) {
   return process_type == switches::kRendererProcess ||
          process_type == switches::kZygoteProcess ||
-         process_type == switches::kGpuProcess;
+         process_type == switches::kGpuProcess ||
+         process_type == switches::kUtilityProcess;
 }
 
 bool CastCrashReporterClient::HandleCrashDump(const char* crashdump_filename) {
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index e1ba889..cf34a67 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -458,7 +458,8 @@
       command_line.GetSwitchValueASCII(switches::kProcessType);
 
   if (process_type == switches::kRendererProcess ||
-      process_type == switches::kGpuProcess) {
+      process_type == switches::kGpuProcess ||
+      process_type == switches::kUtilityProcess) {
     breakpad::CrashHandlerHostLinux* crash_handler =
         crash_handlers_[process_type];
     if (!crash_handler) {
diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp
index 6bb8a14..daab117a 100644
--- a/chromecast/chromecast.gyp
+++ b/chromecast/chromecast.gyp
@@ -297,7 +297,7 @@
                 ],
               }],
             ],
-            'pak_output': '<(PRODUCT_DIR)/cast_shell.pak',
+            'pak_output': '<(PRODUCT_DIR)/assets/cast_shell.pak',
           },
           'includes': [ '../build/repack_action.gypi' ],
         },
@@ -563,7 +563,6 @@
           'target_name': 'cast_shell_icudata',
           'type': 'none',
           'dependencies': [
-            'cast_shell_pak',
             '../third_party/icu/icu.gyp:icudata',
             '../v8/tools/gyp/v8.gyp:v8_external_snapshot',
           ],
@@ -571,7 +570,6 @@
             'dest_path': '<(cast_shell_assets_path)',
             'src_files': [
               '<(PRODUCT_DIR)/icudtl.dat',
-              '<(PRODUCT_DIR)/cast_shell.pak',
             ],
             'renaming_sources': [
               '<(PRODUCT_DIR)/natives_blob.bin',
diff --git a/chromecast/media/cma/backend/media_pipeline_backend_wrapper.cc b/chromecast/media/cma/backend/media_pipeline_backend_wrapper.cc
index 447981f5..ef86099 100644
--- a/chromecast/media/cma/backend/media_pipeline_backend_wrapper.cc
+++ b/chromecast/media/cma/backend/media_pipeline_backend_wrapper.cc
@@ -28,6 +28,7 @@
 
 MediaPipelineBackend::AudioDecoder*
 MediaPipelineBackendWrapper::CreateAudioDecoder() {
+  DCHECK(!is_initialized_);
   if (audio_decoder_wrapper_)
     return nullptr;
 
@@ -38,12 +39,14 @@
 
 MediaPipelineBackend::VideoDecoder*
 MediaPipelineBackendWrapper::CreateVideoDecoder() {
+  DCHECK(!is_initialized_);
   return backend_->CreateVideoDecoder();
 }
 
 bool MediaPipelineBackendWrapper::Initialize() {
+  DCHECK(!is_initialized_);
   is_initialized_ = backend_->Initialize();
-  if (is_initialized_)
+  if (is_initialized_ && audio_decoder_wrapper_)
     audio_decoder_wrapper_->SetStreamTypeVolume(stream_type_volume_);
 
   return is_initialized_;
diff --git a/components/mus/BUILD.gn b/components/mus/BUILD.gn
index 0f54042..f8e2972a 100644
--- a/components/mus/BUILD.gn
+++ b/components/mus/BUILD.gn
@@ -82,9 +82,6 @@
     "//components/mus/common:mus_common",
   ]
   deps = [
-    ":resources_100",
-    ":resources_200",
-    ":resources_strings",
     "//base",
     "//cc",
     "//cc/surfaces",
@@ -103,6 +100,9 @@
   ]
 
   data_deps = [
+    ":resources_100",
+    ":resources_200",
+    ":resources_strings",
     "//components/resource_provider",
   ]
 
diff --git a/components/mus/common/window_tracker.h b/components/mus/common/window_tracker.h
index 8446bbf3..7113f3d 100644
--- a/components/mus/common/window_tracker.h
+++ b/components/mus/common/window_tracker.h
@@ -7,8 +7,8 @@
 
 #include <vector>
 
+#include "base/macros.h"
 #include "base/stl_util.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mus {
 
diff --git a/components/mus/public/cpp/lib/window.cc b/components/mus/public/cpp/lib/window.cc
index 7078784..0fe9dbb 100644
--- a/components/mus/public/cpp/lib/window.cc
+++ b/components/mus/public/cpp/lib/window.cc
@@ -158,7 +158,7 @@
   return OwnsWindow(window->connection(), window) || IsConnectionRoot(window);
 }
 
-void EmptyEmbedCallback(bool result, ConnectionSpecificId connection_id) {}
+void EmptyEmbedCallback(bool result) {}
 
 }  // namespace
 
@@ -410,17 +410,15 @@
 }
 
 void Window::Embed(mus::mojom::WindowTreeClientPtr client) {
-  Embed(std::move(client), mus::mojom::WindowTree::kAccessPolicyDefault,
-        base::Bind(&EmptyEmbedCallback));
+  Embed(std::move(client), base::Bind(&EmptyEmbedCallback));
 }
 
 void Window::Embed(mus::mojom::WindowTreeClientPtr client,
-                   uint32_t policy_bitmask,
                    const EmbedCallback& callback) {
   if (PrepareForEmbed())
-    tree_client()->Embed(id_, std::move(client), policy_bitmask, callback);
+    tree_client()->Embed(id_, std::move(client), callback);
   else
-    callback.Run(false, 0);
+    callback.Run(false);
 }
 
 void Window::RequestClose() {
@@ -764,7 +762,7 @@
 }
 
 bool Window::PrepareForEmbed() {
-  if (!OwnsWindow(connection_, this) && !tree_client()->is_embed_root())
+  if (!OwnsWindow(connection_, this))
     return false;
 
   while (!children_.empty())
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 47ea48e..12ffb51c 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.cc
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.cc
@@ -123,7 +123,6 @@
       focused_window_(nullptr),
       binding_(this),
       tree_(nullptr),
-      is_embed_root_(false),
       delete_on_no_roots_(true),
       in_destructor_(false) {
   // Allow for a null request in tests.
@@ -350,10 +349,9 @@
 void WindowTreeClientImpl::Embed(
     Id window_id,
     mojom::WindowTreeClientPtr client,
-    uint32_t policy_bitmask,
     const mojom::WindowTree::EmbedCallback& callback) {
   DCHECK(tree_);
-  tree_->Embed(window_id, std::move(client), policy_bitmask, callback);
+  tree_->Embed(window_id, std::move(client), callback);
 }
 
 void WindowTreeClientImpl::RequestClose(Window* window) {
@@ -484,14 +482,11 @@
 void WindowTreeClientImpl::OnEmbedImpl(mojom::WindowTree* window_tree,
                                        ConnectionSpecificId connection_id,
                                        mojom::WindowDataPtr root_data,
-                                       Id focused_window_id,
-                                       uint32_t access_policy) {
+                                       Id focused_window_id) {
   // WARNING: this is only called if WindowTreeClientImpl was created as the
   // result of an embedding.
   tree_ = window_tree;
   connection_id_ = connection_id;
-  is_embed_root_ =
-      (access_policy & mojom::WindowTree::kAccessPolicyEmbedRoot) != 0;
 
   DCHECK(roots_.empty());
   Window* root = AddWindowToConnection(this, nullptr, root_data);
@@ -537,10 +532,6 @@
   return NewWindowImpl(NewWindowType::TOP_LEVEL, properties);
 }
 
-bool WindowTreeClientImpl::IsEmbedRoot() {
-  return is_embed_root_;
-}
-
 ConnectionSpecificId WindowTreeClientImpl::GetConnectionId() {
   return connection_id_;
 }
@@ -560,8 +551,7 @@
 void WindowTreeClientImpl::OnEmbed(ConnectionSpecificId connection_id,
                                    mojom::WindowDataPtr root_data,
                                    mojom::WindowTreePtr tree,
-                                   Id focused_window_id,
-                                   uint32_t access_policy) {
+                                   Id focused_window_id) {
   DCHECK(!tree_ptr_);
   tree_ptr_ = std::move(tree);
   tree_ptr_.set_connection_error_handler([this]() { delete this; });
@@ -572,7 +562,7 @@
   }
 
   OnEmbedImpl(tree_ptr_.get(), connection_id, std::move(root_data),
-              focused_window_id, access_policy);
+              focused_window_id);
 }
 
 void WindowTreeClientImpl::OnEmbeddedAppDisconnected(Id window_id) {
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 5dba11c..df214078 100644
--- a/components/mus/public/cpp/lib/window_tree_client_impl.h
+++ b/components/mus/public/cpp/lib/window_tree_client_impl.h
@@ -97,7 +97,6 @@
 
   void Embed(Id window_id,
              mojom::WindowTreeClientPtr client,
-             uint32_t policy_bitmask,
              const mojom::WindowTree::EmbedCallback& callback);
 
   void RequestClose(Window* window);
@@ -118,8 +117,6 @@
 
   bool IsRoot(Window* window) const { return roots_.count(window) > 0; }
 
-  bool is_embed_root() const { return is_embed_root_; }
-
   // Called after the window's observers have been notified of destruction (as
   // the last step of ~Window).
   void OnWindowDestroyed(Window* window);
@@ -159,8 +156,7 @@
   void OnEmbedImpl(mojom::WindowTree* window_tree,
                    ConnectionSpecificId connection_id,
                    mojom::WindowDataPtr root_data,
-                   Id focused_window_id,
-                   uint32_t access_policy);
+                   Id focused_window_id);
 
   // Overridden from WindowTreeConnection:
   void SetDeleteOnNoRoots(bool value) override;
@@ -170,7 +166,6 @@
   Window* NewWindow(const Window::SharedProperties* properties) override;
   Window* NewTopLevelWindow(
       const Window::SharedProperties* properties) override;
-  bool IsEmbedRoot() override;
   ConnectionSpecificId GetConnectionId() override;
   void AddObserver(WindowTreeConnectionObserver* observer) override;
   void RemoveObserver(WindowTreeConnectionObserver* observer) override;
@@ -179,8 +174,7 @@
   void OnEmbed(ConnectionSpecificId connection_id,
                mojom::WindowDataPtr root,
                mojom::WindowTreePtr tree,
-               Id focused_window_id,
-               uint32_t access_policy) override;
+               Id focused_window_id) override;
   void OnEmbeddedAppDisconnected(Id window_id) override;
   void OnUnembed(Id window_id) override;
   void OnLostCapture(Id window_id) override;
@@ -283,8 +277,6 @@
   // directly set this.
   mojom::WindowTree* tree_;
 
-  bool is_embed_root_;
-
   bool delete_on_no_roots_;
 
   bool in_destructor_;
diff --git a/components/mus/public/cpp/tests/test_window_tree.cc b/components/mus/public/cpp/tests/test_window_tree.cc
index ba9ebed..fa155c8 100644
--- a/components/mus/public/cpp/tests/test_window_tree.cc
+++ b/components/mus/public/cpp/tests/test_window_tree.cc
@@ -113,7 +113,6 @@
 
 void TestWindowTree::Embed(uint32_t window_id,
                            mojom::WindowTreeClientPtr client,
-                           uint32_t policy_bitmask,
                            const EmbedCallback& callback) {}
 
 void TestWindowTree::SetFocus(uint32_t change_id, uint32_t window_id) {
diff --git a/components/mus/public/cpp/tests/test_window_tree.h b/components/mus/public/cpp/tests/test_window_tree.h
index 8165c702..8c13166a 100644
--- a/components/mus/public/cpp/tests/test_window_tree.h
+++ b/components/mus/public/cpp/tests/test_window_tree.h
@@ -76,7 +76,6 @@
   void ReleaseCapture(uint32_t change_id, uint32_t window_id) override;
   void Embed(uint32_t window_id,
              mojom::WindowTreeClientPtr client,
-             uint32_t policy_bitmask,
              const EmbedCallback& callback) override;
   void SetFocus(uint32_t change_id, uint32_t window_id) override;
   void SetCanFocus(uint32_t window_id, bool can_focus) override;
diff --git a/components/mus/public/cpp/tests/window_server_test_suite.h b/components/mus/public/cpp/tests/window_server_test_suite.h
index 43565bb..45104b76 100644
--- a/components/mus/public/cpp/tests/window_server_test_suite.h
+++ b/components/mus/public/cpp/tests/window_server_test_suite.h
@@ -7,7 +7,6 @@
 
 #include "base/macros.h"
 #include "base/test/test_suite.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mus {
 
diff --git a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc
index 69c498b..a46da1b6 100644
--- a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc
+++ b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc
@@ -57,7 +57,7 @@
       : tree_client_impl_(tree_client_impl) {}
   ~WindowTreeClientImplPrivate() {}
 
-  void Init(mojom::WindowTree* window_tree, uint32_t access_policy) {
+  void Init(mojom::WindowTree* window_tree) {
     mojom::WindowDataPtr root_data(mojom::WindowData::New());
     root_data->parent_id = 0;
     root_data->window_id = 1;
@@ -69,8 +69,7 @@
     root_data->viewport_metrics->size_in_pixels =
         mojo::Size::From(gfx::Size(1000, 1000));
     root_data->viewport_metrics->device_pixel_ratio = 1;
-    tree_client_impl_->OnEmbedImpl(window_tree, 1, std::move(root_data), 0,
-                                   access_policy);
+    tree_client_impl_->OnEmbedImpl(window_tree, 1, std::move(root_data), 0);
   }
 
  private:
@@ -82,8 +81,7 @@
 class WindowTreeSetup {
  public:
   WindowTreeSetup() : tree_client_(&window_tree_delegate_, nullptr, nullptr) {
-    WindowTreeClientImplPrivate(&tree_client_)
-        .Init(&window_tree_, mojom::WindowTree::kAccessPolicyDefault);
+    WindowTreeClientImplPrivate(&tree_client_).Init(&window_tree_);
     window_tree_.GetAndClearChangeId(nullptr);
   }
 
diff --git a/components/mus/public/cpp/window.h b/components/mus/public/cpp/window.h
index a04af04..3c3e460d 100644
--- a/components/mus/public/cpp/window.h
+++ b/components/mus/public/cpp/window.h
@@ -16,7 +16,6 @@
 #include "components/mus/public/interfaces/surface_id.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/shell/public/interfaces/interface_provider.mojom.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/rect.h"
@@ -52,7 +51,7 @@
 class Window {
  public:
   using Children = std::vector<Window*>;
-  using EmbedCallback = base::Callback<void(bool, ConnectionSpecificId)>;
+  using EmbedCallback = base::Callback<void(bool)>;
   using PropertyDeallocator = void (*)(int64_t value);
   using SharedProperties = std::map<std::string, std::vector<uint8_t>>;
 
@@ -208,7 +207,6 @@
   // NOTE: callback is run synchronously if Embed() is not allowed on this
   // Window.
   void Embed(mus::mojom::WindowTreeClientPtr client,
-             uint32_t policy_bitmask,
              const EmbedCallback& callback);
 
   // TODO(sky): this API is only applicable to the WindowManager. Move it
diff --git a/components/mus/public/cpp/window_tracker.h b/components/mus/public/cpp/window_tracker.h
index 38ea000..9cbafeb 100644
--- a/components/mus/public/cpp/window_tracker.h
+++ b/components/mus/public/cpp/window_tracker.h
@@ -11,7 +11,6 @@
 #include "base/macros.h"
 #include "components/mus/common/window_tracker.h"
 #include "components/mus/public/cpp/window_observer.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mus {
 
diff --git a/components/mus/public/cpp/window_tree_connection.h b/components/mus/public/cpp/window_tree_connection.h
index d99eda2..43db0f1 100644
--- a/components/mus/public/cpp/window_tree_connection.h
+++ b/components/mus/public/cpp/window_tree_connection.h
@@ -85,9 +85,6 @@
   virtual Window* NewTopLevelWindow(
       const std::map<std::string, std::vector<uint8_t>>* properties) = 0;
 
-  // Returns true if ACCESS_POLICY_EMBED_ROOT was specified.
-  virtual bool IsEmbedRoot() = 0;
-
   // Returns the id for this connection.
   // TODO(sky): remove this. It is not necessarily correct anymore.
   virtual ConnectionSpecificId GetConnectionId() = 0;
diff --git a/components/mus/public/interfaces/window_tree.mojom b/components/mus/public/interfaces/window_tree.mojom
index 6ad39901..a30bf93b 100644
--- a/components/mus/public/interfaces/window_tree.mojom
+++ b/components/mus/public/interfaces/window_tree.mojom
@@ -69,17 +69,6 @@
 // change id in anyway, it is up to the client to assign a value and use it.
 // Generally the change id is an ever increasing integer.
 interface WindowTree {
-  const int32 kAccessPolicyDefault = 0;
-
-  // An embed root has the following abilities:
-  // . The app sees all the descendants of the window the app is ebmedded at,
-  //   even those from separate connections.
-  // . The app is able to Embed() in all the descendants of the window the app
-  //   is embedded at, even those from separate connections.
-  // Only connections originating from the WindowTreeHostFactory can grant
-  // this policy.
-  const int32 kAccessPolicyEmbedRoot = 1;
-
   // Creates a new window with the specified id. It is up to the client to
   // ensure the id is unique to the connection (the id need not be globally
   // unique). Additionally the connection id (embedded in |window_id|) must
@@ -211,9 +200,8 @@
   //
   // When a connection embeds a WindowTreeClient the originating connection no
   // longer has privileges to access or see any of the children of the window.
-  // If the window had existing children the children are removed. The one
-  // exception is the root connection and any connections with the policy
-  // kAccessPolicyEmbedRoot.
+  // If the window had existing children the children are removed. The
+  // WindowManager gets to see the whole tree.
   //
   // A window may only have one embedding in it at a time. Subsequent calls to
   // Embed() for the same window result in the currently embedded
@@ -224,15 +212,8 @@
   // The embedder can detect when the embedded app disconnects by way of
   // OnEmbeddedAppDisconnected().
   //
-  // The callback returns whether the embedding was successful, and if the
-  // embedding was successful and the originating connection is an embed root
-  // the resulting id of the new connection.
-  //
-  // policy_bitmask is a bitmask of the kAccessPolicy constants. See them for
-  // details.
-  Embed(uint32 window_id,
-        WindowTreeClient client,
-        uint32 policy_bitmask) => (bool success, uint16 connection_id);
+  // The callback returns whether the embedding was successful.
+  Embed(uint32 window_id, WindowTreeClient client) => (bool success);
 
   SetFocus(uint32 change_id, uint32 window_id);
   SetCanFocus(uint32 window_id, bool can_focus);
@@ -271,8 +252,7 @@
   OnEmbed(uint16 connection_id,
           WindowData root,
           WindowTree? tree,
-          uint32 focused_window,
-          uint32 access_policy);
+          uint32 focused_window);
 
   // Invoked when the application embedded at |window| is disconnected. In other
   // words the embedded app closes the connection to the server. This is called
diff --git a/components/mus/ws/access_policy.h b/components/mus/ws/access_policy.h
index 4ce1540..8ba6ff6 100644
--- a/components/mus/ws/access_policy.h
+++ b/components/mus/ws/access_policy.h
@@ -42,8 +42,7 @@
   // descend into |window|.
   virtual bool CanDescendIntoWindowForWindowTree(
       const ServerWindow* window) const = 0;
-  virtual bool CanEmbed(const ServerWindow* window,
-                        uint32_t policy_bitmask) const = 0;
+  virtual bool CanEmbed(const ServerWindow* window) const = 0;
   virtual bool CanChangeWindowVisibility(const ServerWindow* window) const = 0;
   virtual bool CanSetWindowSurface(const ServerWindow* window,
                                    mojom::SurfaceType surface_type) const = 0;
@@ -69,6 +68,8 @@
   // Returns the window to supply to the client when focus changes to |focused|.
   virtual const ServerWindow* GetWindowForFocusChange(
       const ServerWindow* focused) = 0;
+
+  virtual bool IsValidIdForNewWindow(const ClientWindowId& id) const = 0;
 };
 
 }  // namespace ws
diff --git a/components/mus/ws/access_policy_delegate.h b/components/mus/ws/access_policy_delegate.h
index 9b049fb..3e33de5 100644
--- a/components/mus/ws/access_policy_delegate.h
+++ b/components/mus/ws/access_policy_delegate.h
@@ -30,10 +30,6 @@
   virtual bool IsWindowRootOfAnotherTreeForAccessPolicy(
       const ServerWindow* window) const = 0;
 
-  // Returns true if SetEmbedRoot() was invoked and |window| is a descendant of
-  // the root of the connection.
-  virtual bool IsDescendantOfEmbedRoot(const ServerWindow* window) = 0;
-
  protected:
   virtual ~AccessPolicyDelegate() {}
 };
diff --git a/components/mus/ws/connection_manager.cc b/components/mus/ws/connection_manager.cc
index 2e1dd134..6096d40 100644
--- a/components/mus/ws/connection_manager.cc
+++ b/components/mus/ws/connection_manager.cc
@@ -68,11 +68,9 @@
 
 WindowTree* ConnectionManager::EmbedAtWindow(
     ServerWindow* root,
-    uint32_t policy_bitmask,
     const UserId& user_id,
     mojom::WindowTreeClientPtr client) {
-  scoped_ptr<WindowTree> tree_ptr(
-      new WindowTree(this, user_id, root, policy_bitmask));
+  scoped_ptr<WindowTree> tree_ptr(new WindowTree(this, user_id, root));
   WindowTree* tree = tree_ptr.get();
 
   mojom::WindowTreePtr window_tree_ptr;
@@ -103,8 +101,7 @@
   mojom::DisplayPtr display_ptr = display->ToMojomDisplay();
   mojom::WindowTreeClientPtr tree_client;
   factory->CreateWindowManager(std::move(display_ptr), GetProxy(&tree_client));
-  scoped_ptr<WindowTree> tree_ptr(new WindowTree(
-      this, user_id, root, mojom::WindowTree::kAccessPolicyEmbedRoot));
+  scoped_ptr<WindowTree> tree_ptr(new WindowTree(this, user_id, root));
   WindowTree* tree = tree_ptr.get();
   scoped_ptr<DefaultWindowTreeBinding> binding(new DefaultWindowTreeBinding(
       tree_ptr.get(), this, std::move(tree_client)));
diff --git a/components/mus/ws/connection_manager.h b/components/mus/ws/connection_manager.h
index 3fe49874..fc4b185e 100644
--- a/components/mus/ws/connection_manager.h
+++ b/components/mus/ws/connection_manager.h
@@ -70,7 +70,6 @@
   // See description of WindowTree::Embed() for details. This assumes
   // |transport_window_id| is valid.
   WindowTree* EmbedAtWindow(ServerWindow* root,
-                            uint32_t policy_bitmask,
                             const UserId& user_id,
                             mojom::WindowTreeClientPtr client);
 
diff --git a/components/mus/ws/default_access_policy.cc b/components/mus/ws/default_access_policy.cc
index 7c8c062..77e3e8b 100644
--- a/components/mus/ws/default_access_policy.cc
+++ b/components/mus/ws/default_access_policy.cc
@@ -8,7 +8,6 @@
 #include "components/mus/ws/server_window.h"
 
 namespace mus {
-
 namespace ws {
 
 DefaultAccessPolicy::DefaultAccessPolicy(ConnectionSpecificId connection_id,
@@ -70,26 +69,18 @@
 
 bool DefaultAccessPolicy::CanGetWindowTree(const ServerWindow* window) const {
   return WasCreatedByThisConnection(window) ||
-         delegate_->HasRootForAccessPolicy(window) ||
-         IsDescendantOfEmbedRoot(window);
+         delegate_->HasRootForAccessPolicy(window);
 }
 
 bool DefaultAccessPolicy::CanDescendIntoWindowForWindowTree(
     const ServerWindow* window) const {
   return (WasCreatedByThisConnection(window) &&
           !delegate_->IsWindowRootOfAnotherTreeForAccessPolicy(window)) ||
-         delegate_->HasRootForAccessPolicy(window) ||
-         delegate_->IsDescendantOfEmbedRoot(window);
+         delegate_->HasRootForAccessPolicy(window);
 }
 
-bool DefaultAccessPolicy::CanEmbed(const ServerWindow* window,
-                                   uint32_t policy_bitmask) const {
-  if (policy_bitmask != mojom::WindowTree::kAccessPolicyDefault)
-    return false;
-  return WasCreatedByThisConnection(window) ||
-         (delegate_->IsWindowKnownForAccessPolicy(window) &&
-          IsDescendantOfEmbedRoot(window) &&
-          !delegate_->HasRootForAccessPolicy(window));
+bool DefaultAccessPolicy::CanEmbed(const ServerWindow* window) const {
+  return WasCreatedByThisConnection(window);
 }
 
 bool DefaultAccessPolicy::CanChangeWindowVisibility(
@@ -153,21 +144,16 @@
     const ServerWindow* window,
     const ServerWindow** new_parent,
     const ServerWindow** old_parent) const {
-  if (!WasCreatedByThisConnection(window) && !IsDescendantOfEmbedRoot(window) &&
-      (!*new_parent || !IsDescendantOfEmbedRoot(*new_parent)) &&
-      (!*old_parent || !IsDescendantOfEmbedRoot(*old_parent))) {
+  if (!WasCreatedByThisConnection(window) && !*new_parent && !*old_parent)
     return false;
-  }
 
   if (*new_parent && !WasCreatedByThisConnection(*new_parent) &&
-      !delegate_->HasRootForAccessPolicy((*new_parent)) &&
-      !delegate_->IsDescendantOfEmbedRoot(*new_parent)) {
+      !delegate_->HasRootForAccessPolicy((*new_parent))) {
     *new_parent = nullptr;
   }
 
   if (*old_parent && !WasCreatedByThisConnection(*old_parent) &&
-      !delegate_->HasRootForAccessPolicy((*old_parent)) &&
-      !delegate_->IsDescendantOfEmbedRoot(*new_parent)) {
+      !delegate_->HasRootForAccessPolicy((*old_parent))) {
     *old_parent = nullptr;
   }
   return true;
@@ -190,11 +176,13 @@
   return window->id().connection_id == connection_id_;
 }
 
-bool DefaultAccessPolicy::IsDescendantOfEmbedRoot(
-    const ServerWindow* window) const {
-  return delegate_->IsDescendantOfEmbedRoot(window);
+bool DefaultAccessPolicy::IsValidIdForNewWindow(
+    const ClientWindowId& id) const {
+  // Clients using DefaultAccessPolicy only see windows they have created (for
+  // the embed point they choose the id), so it's ok for clients to use whatever
+  // id they want.
+  return true;
 }
 
 }  // namespace ws
-
 }  // namespace mus
diff --git a/components/mus/ws/default_access_policy.h b/components/mus/ws/default_access_policy.h
index af93e78..8c1c5d0b4 100644
--- a/components/mus/ws/default_access_policy.h
+++ b/components/mus/ws/default_access_policy.h
@@ -11,7 +11,6 @@
 #include "components/mus/ws/access_policy.h"
 
 namespace mus {
-
 namespace ws {
 
 class AccessPolicyDelegate;
@@ -39,8 +38,7 @@
   bool CanGetWindowTree(const ServerWindow* window) const override;
   bool CanDescendIntoWindowForWindowTree(
       const ServerWindow* window) const override;
-  bool CanEmbed(const ServerWindow* window,
-                uint32_t policy_bitmask) const override;
+  bool CanEmbed(const ServerWindow* window) const override;
   bool CanChangeWindowVisibility(const ServerWindow* window) const override;
   bool CanSetWindowSurface(const ServerWindow* window,
                            mus::mojom::SurfaceType surface_type) const override;
@@ -58,10 +56,10 @@
   const ServerWindow* GetWindowForFocusChange(
       const ServerWindow* focused) override;
   bool CanSetWindowManager() const override;
+  bool IsValidIdForNewWindow(const ClientWindowId& id) const override;
 
  private:
   bool WasCreatedByThisConnection(const ServerWindow* window) const;
-  bool IsDescendantOfEmbedRoot(const ServerWindow* window) const;
 
   const ConnectionSpecificId connection_id_;
   AccessPolicyDelegate* delegate_;
@@ -70,7 +68,6 @@
 };
 
 }  // namespace ws
-
 }  // namespace mus
 
 #endif  // COMPONENTS_MUS_WS_DEFAULT_ACCESS_POLICY_H_
diff --git a/components/mus/ws/display.cc b/components/mus/ws/display.cc
index 19291f91..e2e649e8 100644
--- a/components/mus/ws/display.cc
+++ b/components/mus/ws/display.cc
@@ -138,12 +138,6 @@
   return nullptr;
 }
 
-WindowManagerState* Display::GetFirstWindowManagerState() {
-  return window_manager_state_map_.empty()
-             ? nullptr
-             : window_manager_state_map_.begin()->second.get();
-}
-
 const WindowManagerState* Display::GetWindowManagerStateForUser(
     const UserId& user_id) const {
   auto iter = window_manager_state_map_.find(user_id);
diff --git a/components/mus/ws/display.h b/components/mus/ws/display.h
index 0df8dff..8554b99 100644
--- a/components/mus/ws/display.h
+++ b/components/mus/ws/display.h
@@ -97,8 +97,6 @@
   ServerWindow* GetRootWithId(const WindowId& id);
 
   WindowManagerState* GetWindowManagerStateWithRoot(const ServerWindow* window);
-  // TODO(sky): this is wrong, plumb through user_id.
-  WindowManagerState* GetFirstWindowManagerState();
   WindowManagerState* GetWindowManagerStateForUser(const UserId& user_id) {
     return const_cast<WindowManagerState*>(
         const_cast<const Display*>(this)->GetWindowManagerStateForUser(
diff --git a/components/mus/ws/display_binding.cc b/components/mus/ws/display_binding.cc
index 4ccb390..31ce695 100644
--- a/components/mus/ws/display_binding.cc
+++ b/components/mus/ws/display_binding.cc
@@ -25,9 +25,8 @@
 DisplayBindingImpl::~DisplayBindingImpl() {}
 
 WindowTree* DisplayBindingImpl::CreateWindowTree(ServerWindow* root) {
-  WindowTree* tree = connection_manager_->EmbedAtWindow(
-      root, mojom::WindowTree::kAccessPolicyEmbedRoot, user_id_,
-      std::move(client_));
+  WindowTree* tree =
+      connection_manager_->EmbedAtWindow(root, user_id_, std::move(client_));
   tree->ConfigureWindowManager();
   return tree;
 }
diff --git a/components/mus/ws/test_utils.cc b/components/mus/ws/test_utils.cc
index 2cb74915..1418c27 100644
--- a/components/mus/ws/test_utils.cc
+++ b/components/mus/ws/test_utils.cc
@@ -126,8 +126,7 @@
 void TestWindowTreeClient::OnEmbed(uint16_t connection_id,
                                    mojom::WindowDataPtr root,
                                    mus::mojom::WindowTreePtr tree,
-                                   Id focused_window_id,
-                                   uint32_t access_policy) {
+                                   Id focused_window_id) {
   // TODO(sky): add test coverage of |focused_window_id|.
   tracker_.OnEmbed(connection_id, std::move(root));
 }
diff --git a/components/mus/ws/test_utils.h b/components/mus/ws/test_utils.h
index f8d615df..31826d9 100644
--- a/components/mus/ws/test_utils.h
+++ b/components/mus/ws/test_utils.h
@@ -168,8 +168,7 @@
   void OnEmbed(uint16_t connection_id,
                mojom::WindowDataPtr root,
                mus::mojom::WindowTreePtr tree,
-               Id focused_window_id,
-               uint32_t access_policy) override;
+               Id focused_window_id) override;
   void OnEmbeddedAppDisconnected(uint32_t window) override;
   void OnUnembed(Id window_id) override;
   void OnLostCapture(Id window_id) override;
diff --git a/components/mus/ws/window_manager_access_policy.cc b/components/mus/ws/window_manager_access_policy.cc
index d8be6ac..16a215b 100644
--- a/components/mus/ws/window_manager_access_policy.cc
+++ b/components/mus/ws/window_manager_access_policy.cc
@@ -8,7 +8,6 @@
 #include "components/mus/ws/server_window.h"
 
 namespace mus {
-
 namespace ws {
 
 // TODO(sky): document why this differs from default for each case. Maybe want
@@ -69,8 +68,7 @@
   return true;
 }
 
-bool WindowManagerAccessPolicy::CanEmbed(const ServerWindow* window,
-                                         uint32_t policy_bitmask) const {
+bool WindowManagerAccessPolicy::CanEmbed(const ServerWindow* window) const {
   return !delegate_->HasRootForAccessPolicy(window);
 }
 
@@ -157,6 +155,14 @@
   return delegate_->IsWindowKnownForAccessPolicy(window);
 }
 
-}  // namespace ws
+bool WindowManagerAccessPolicy::IsValidIdForNewWindow(
+    const ClientWindowId& id) const {
+  // The WindowManager see windows created from other clients. If the WM doesn't
+  // use the connection id when creating windows the WM could end up with two
+  // windows with the same id. Because of this the wm must use the same
+  // connection id for all windows it creates.
+  return WindowIdFromTransportId(id.id).connection_id == connection_id_;
+}
 
+}  // namespace ws
 }  // namespace mus
diff --git a/components/mus/ws/window_manager_access_policy.h b/components/mus/ws/window_manager_access_policy.h
index 67f0e73..7cb062e 100644
--- a/components/mus/ws/window_manager_access_policy.h
+++ b/components/mus/ws/window_manager_access_policy.h
@@ -11,7 +11,6 @@
 #include "components/mus/ws/access_policy.h"
 
 namespace mus {
-
 namespace ws {
 
 class AccessPolicyDelegate;
@@ -38,8 +37,7 @@
   bool CanGetWindowTree(const ServerWindow* window) const override;
   bool CanDescendIntoWindowForWindowTree(
       const ServerWindow* window) const override;
-  bool CanEmbed(const ServerWindow* window,
-                uint32_t policy_bitmask) const override;
+  bool CanEmbed(const ServerWindow* window) const override;
   bool CanChangeWindowVisibility(const ServerWindow* window) const override;
   bool CanSetWindowSurface(const ServerWindow* window,
                            mus::mojom::SurfaceType surface_type) const override;
@@ -57,6 +55,7 @@
   const ServerWindow* GetWindowForFocusChange(
       const ServerWindow* focused) override;
   bool CanSetWindowManager() const override;
+  bool IsValidIdForNewWindow(const ClientWindowId& id) const override;
 
  private:
   bool IsWindowKnown(const ServerWindow* window) const;
@@ -68,7 +67,6 @@
 };
 
 }  // namespace ws
-
 }  // namespace mus
 
 #endif  // COMPONENTS_MUS_WS_WINDOW_MANAGER_ACCESS_POLICY_H_
diff --git a/components/mus/ws/window_manager_client_unittest.cc b/components/mus/ws/window_manager_client_unittest.cc
index 33623de..31c5a11 100644
--- a/components/mus/ws/window_manager_client_unittest.cc
+++ b/components/mus/ws/window_manager_client_unittest.cc
@@ -251,14 +251,9 @@
   // a response is received, or a timeout. On success the new WindowServer is
   // returned.
   EmbedResult Embed(Window* window) {
-    return Embed(window, mus::mojom::WindowTree::kAccessPolicyDefault);
-  }
-
-  EmbedResult Embed(Window* window, uint32_t access_policy_bitmask) {
     DCHECK(!embed_details_);
     embed_details_.reset(new EmbedDetails);
     window->Embed(ConnectAndGetWindowServerClient(),
-                  access_policy_bitmask,
                   base::Bind(&WindowServerTest::EmbedCallbackImpl,
                              base::Unretained(this)));
     embed_details_->waiting = true;
@@ -297,7 +292,6 @@
         : callback_run(false),
           result(false),
           waiting(false),
-          connection_id(0),
           connection(nullptr) {}
 
     // The callback supplied to Embed() was received.
@@ -317,10 +311,9 @@
     WindowTreeConnection* connection;
   };
 
-  void EmbedCallbackImpl(bool result, ConnectionSpecificId connection_id) {
+  void EmbedCallbackImpl(bool result) {
     embed_details_->callback_run = true;
     embed_details_->result = result;
-    embed_details_->connection_id = connection_id;
     if (embed_details_->waiting && (!result || embed_details_->connection))
       EXPECT_TRUE(WindowServerTestBase::QuitRunLoop());
   }
@@ -1034,68 +1027,6 @@
   EXPECT_TRUE(got_destroy);
 }
 
-// Verifies an embed root sees windows created beneath it from another
-// connection.
-TEST_F(WindowServerTest, EmbedRootSeesHierarchyChanged) {
-  Window* embed_window = window_manager()->NewWindow();
-  GetFirstWMRoot()->AddChild(embed_window);
-
-  WindowTreeConnection* vm2 =
-      Embed(embed_window, mus::mojom::WindowTree::kAccessPolicyEmbedRoot)
-          .connection;
-  Window* vm2_v1 = vm2->NewWindow();
-  GetFirstRoot(vm2)->AddChild(vm2_v1);
-
-  WindowTreeConnection* vm3 = Embed(vm2_v1).connection;
-  Window* vm3_v1 = vm3->NewWindow();
-  GetFirstRoot(vm3)->AddChild(vm3_v1);
-
-  // As |vm2| is an embed root it should get notified about |vm3_v1|.
-  ASSERT_TRUE(WaitForTreeSizeToMatch(vm2_v1, 2));
-}
-
-// Flaky failure: http://crbug.com/587868
-#if defined(OS_LINUX)
-#define MAYBE_EmbedFromEmbedRoot DISABLED_EmbedFromEmbedRoot
-#else
-#define MAYBE_EmbedFromEmbedRoot EmbedFromEmbedRoot
-#endif
-TEST_F(WindowServerTest, MAYBE_EmbedFromEmbedRoot) {
-  Window* embed_window = window_manager()->NewWindow();
-  GetFirstWMRoot()->AddChild(embed_window);
-
-  // Give the connection embedded at |embed_window| embed root powers.
-  const EmbedResult result1 =
-      Embed(embed_window, mus::mojom::WindowTree::kAccessPolicyEmbedRoot);
-  WindowTreeConnection* vm2 = result1.connection;
-  EXPECT_EQ(result1.connection_id, vm2->GetConnectionId());
-  Window* vm2_v1 = vm2->NewWindow();
-  GetFirstRoot(vm2)->AddChild(vm2_v1);
-
-  const EmbedResult result2 = Embed(vm2_v1);
-  WindowTreeConnection* vm3 = result2.connection;
-  EXPECT_EQ(result2.connection_id, vm3->GetConnectionId());
-  Window* vm3_v1 = vm3->NewWindow();
-  GetFirstRoot(vm3)->AddChild(vm3_v1);
-
-  // Embed from v3, the callback should not get the connection id as vm3 is not
-  // an embed root.
-  const EmbedResult result3 = Embed(vm3_v1);
-  ASSERT_TRUE(result3.connection);
-  EXPECT_EQ(0, result3.connection_id);
-
-  // As |vm2| is an embed root it should get notified about |vm3_v1|.
-  ASSERT_TRUE(WaitForTreeSizeToMatch(vm2_v1, 2));
-
-  // Embed() from vm2 in vm3_v1. This is allowed as vm2 is an embed root, and
-  // further the callback should see the connection id.
-  ASSERT_EQ(1u, vm2_v1->children().size());
-  Window* vm3_v1_in_vm2 = vm2_v1->children()[0];
-  const EmbedResult result4 = Embed(vm3_v1_in_vm2);
-  ASSERT_TRUE(result4.connection);
-  EXPECT_EQ(result4.connection_id, result4.connection->GetConnectionId());
-}
-
 TEST_F(WindowServerTest, ClientAreaChanged) {
   Window* embed_window = window_manager()->NewWindow();
   GetFirstWMRoot()->AddChild(embed_window);
diff --git a/components/mus/ws/window_manager_state.cc b/components/mus/ws/window_manager_state.cc
index 2ae1a24..081ca5e0 100644
--- a/components/mus/ws/window_manager_state.cc
+++ b/components/mus/ws/window_manager_state.cc
@@ -275,8 +275,15 @@
           ? connection_manager()->GetTreeWithId(target->id().connection_id)
           : connection_manager()->GetTreeWithRoot(target);
   if (!tree) {
-    DCHECK(!in_nonclient_area);
-    tree = connection_manager()->GetTreeWithId(target->id().connection_id);
+    if (in_nonclient_area) {
+      // Being the root of the tree means we may get events outside the bounds
+      // of the platform window. Because the root has a connection id of 0,
+      // no WindowTree is found for it and we have to special case it here.
+      DCHECK_EQ(target, root_.get());
+      tree = tree_;
+    } else {
+      tree = connection_manager()->GetTreeWithId(target->id().connection_id);
+    }
   }
 
   // TOOD(sad): Adjust this delay, possibly make this dynamic.
diff --git a/components/mus/ws/window_tree.cc b/components/mus/ws/window_tree.cc
index cf7179e..58c0f282 100644
--- a/components/mus/ws/window_tree.cc
+++ b/components/mus/ws/window_tree.cc
@@ -67,25 +67,20 @@
 
 WindowTree::WindowTree(ConnectionManager* connection_manager,
                        const UserId& user_id,
-                       ServerWindow* root,
-                       uint32_t policy_bitmask)
+                       ServerWindow* root)
     : connection_manager_(connection_manager),
       user_id_(user_id),
       id_(connection_manager_->GetAndAdvanceNextConnectionId()),
       next_window_id_(1),
       event_ack_id_(0),
-      is_embed_root_(false),
       window_manager_internal_(nullptr) {
   if (root)
     roots_.insert(root);
   // TODO(sky): pass in type rather than inferring it.
-  if (root && root->id().connection_id == kInvalidConnectionId) {
+  if (root && root->id().connection_id == kInvalidConnectionId)
     access_policy_.reset(new WindowManagerAccessPolicy(id_, this));
-    is_embed_root_ = true;
-  } else {
+  else
     access_policy_.reset(new DefaultAccessPolicy(id_, this));
-    is_embed_root_ = (policy_bitmask & WindowTree::kAccessPolicyEmbedRoot) != 0;
-  }
 }
 
 WindowTree::~WindowTree() {
@@ -114,9 +109,7 @@
     IsWindowKnown(focused_window, &focused_window_id);
 
   client()->OnEmbed(id_, WindowToWindowData(to_send.front()), std::move(tree),
-                    focused_window_id.id,
-                    is_embed_root_ ? WindowTree::kAccessPolicyEmbedRoot
-                                   : WindowTree::kAccessPolicyDefault);
+                    focused_window_id.id);
 }
 
 void WindowTree::ConfigureWindowManager() {
@@ -175,7 +168,7 @@
   // Notify our client if |tree| was embedded in any of our views.
   for (const auto* tree_root : tree->roots_) {
     const bool owns_tree_root = tree_root->id().connection_id == id_;
-    if (owns_tree_root || (is_embed_root_ && IsWindowKnown(tree_root))) {
+    if (owns_tree_root) {
       client()->OnEmbeddedAppDisconnected(
           ClientWindowIdForWindow(tree_root).id);
     }
@@ -279,20 +272,15 @@
 }
 
 bool WindowTree::Embed(const ClientWindowId& window_id,
-                       mojom::WindowTreeClientPtr client,
-                       uint32_t policy_bitmask,
-                       ConnectionSpecificId* connection_id) {
-  *connection_id = kInvalidConnectionId;
-  if (!client || !CanEmbed(window_id, policy_bitmask))
+                       mojom::WindowTreeClientPtr client) {
+  if (!client || !CanEmbed(window_id))
     return false;
   ServerWindow* window = GetWindowByClientId(window_id);
   PrepareForEmbed(window);
   // When embedding we don't know the user id of where the TreeClient came
   // from. Use an invalid id, which limits what the client is able to do.
-  WindowTree* new_tree = connection_manager_->EmbedAtWindow(
-      window, policy_bitmask, InvalidUserId(), std::move(client));
-  if (is_embed_root_)
-    *connection_id = new_tree->id();
+  connection_manager_->EmbedAtWindow(window, InvalidUserId(),
+                                     std::move(client));
   return true;
 }
 
@@ -670,14 +658,8 @@
 }
 
 bool WindowTree::IsValidIdForNewWindow(const ClientWindowId& id) const {
-  if (is_embed_root_ && WindowIdFromTransportId(id.id).connection_id != id_) {
-    // Embed roots see windows created from other connections. If they don't
-    // use the connection id when creating windows the client could end up with
-    // two windows with the same id. Because of this we restrict the ids such
-    // connections can create.
-    return false;
-  }
-  return client_id_to_window_id_map_.count(id) == 0u;
+  return client_id_to_window_id_map_.count(id) == 0u &&
+         access_policy_->IsValidIdForNewWindow(id);
 }
 
 WindowId WindowTree::GenerateNewWindowId() {
@@ -877,10 +859,9 @@
   STLDeleteValues(&created_window_map_copy);
 }
 
-bool WindowTree::CanEmbed(const ClientWindowId& window_id,
-                          uint32_t policy_bitmask) const {
+bool WindowTree::CanEmbed(const ClientWindowId& window_id) const {
   const ServerWindow* window = GetWindowByClientId(window_id);
-  return window && access_policy_->CanEmbed(window, policy_bitmask);
+  return window && access_policy_->CanEmbed(window);
 }
 
 void WindowTree::PrepareForEmbed(ServerWindow* window) {
@@ -1221,12 +1202,8 @@
 
 void WindowTree::Embed(Id transport_window_id,
                        mojom::WindowTreeClientPtr client,
-                       uint32_t policy_bitmask,
                        const EmbedCallback& callback) {
-  ConnectionSpecificId connection_id = kInvalidConnectionId;
-  const bool result = Embed(ClientWindowId(transport_window_id),
-                            std::move(client), policy_bitmask, &connection_id);
-  callback.Run(result, connection_id);
+  callback.Run(Embed(ClientWindowId(transport_window_id), std::move(client)));
 }
 
 void WindowTree::SetFocus(uint32_t change_id, Id transport_window_id) {
@@ -1394,16 +1371,5 @@
   return tree && tree != this;
 }
 
-bool WindowTree::IsDescendantOfEmbedRoot(const ServerWindow* window) {
-  if (!is_embed_root_)
-    return false;
-
-  for (const auto* root : roots_) {
-    if (root->Contains(window))
-      return true;
-  }
-  return false;
-}
-
 }  // namespace ws
 }  // namespace mus
diff --git a/components/mus/ws/window_tree.h b/components/mus/ws/window_tree.h
index 4810bd4..c4c5055 100644
--- a/components/mus/ws/window_tree.h
+++ b/components/mus/ws/window_tree.h
@@ -60,8 +60,7 @@
  public:
   WindowTree(ConnectionManager* connection_manager,
              const UserId& user_id,
-             ServerWindow* root,
-             uint32_t policy_bitmask);
+             ServerWindow* root);
   ~WindowTree() override;
 
   void Init(scoped_ptr<WindowTreeBinding> binding, mojom::WindowTreePtr tree);
@@ -105,8 +104,6 @@
 
   std::set<const ServerWindow*> roots() { return roots_; }
 
-  bool is_embed_root() const { return is_embed_root_; }
-
   const Display* GetDisplay(const ServerWindow* window) const;
   Display* GetDisplay(const ServerWindow* window) {
     return const_cast<Display*>(
@@ -137,9 +134,7 @@
       const ClientWindowId& window_id) const;
   bool SetWindowVisibility(const ClientWindowId& window_id, bool visible);
   bool Embed(const ClientWindowId& window_id,
-             mojom::WindowTreeClientPtr client,
-             uint32_t policy_bitmask,
-             ConnectionSpecificId* connection_id);
+             mojom::WindowTreeClientPtr client);
   void DispatchInputEvent(ServerWindow* target, mojom::EventPtr event);
 
   bool IsWaitingForNewTopLevelWindow(uint32_t wm_change_id);
@@ -290,7 +285,7 @@
   // Deletes all Windows we own.
   void DestroyWindows();
 
-  bool CanEmbed(const ClientWindowId& window_id, uint32_t policy_bitmask) const;
+  bool CanEmbed(const ClientWindowId& window_id) const;
   void PrepareForEmbed(ServerWindow* window);
   void RemoveChildrenAsPartOfEmbed(ServerWindow* window);
 
@@ -344,7 +339,6 @@
                      mojom::SurfaceClientPtr client) override;
   void Embed(Id transport_window_id,
              mojom::WindowTreeClientPtr client,
-             uint32_t policy_bitmask,
              const EmbedCallback& callback) override;
   void SetFocus(uint32_t change_id, Id transport_window_id) override;
   void SetCanFocus(Id transport_window_id, bool can_focus) override;
@@ -390,7 +384,6 @@
   bool IsWindowKnownForAccessPolicy(const ServerWindow* window) const override;
   bool IsWindowRootOfAnotherTreeForAccessPolicy(
       const ServerWindow* window) const override;
-  bool IsDescendantOfEmbedRoot(const ServerWindow* window) override;
 
   ConnectionManager* connection_manager_;
 
@@ -423,8 +416,6 @@
   // WindowManager the current event came from.
   WindowManagerState* event_source_wms_ = nullptr;
 
-  bool is_embed_root_;
-
   std::queue<scoped_ptr<TargetedEvent>> event_queue_;
 
   scoped_ptr<mojo::AssociatedBinding<mojom::WindowManagerClient>>
diff --git a/components/mus/ws/window_tree_client_unittest.cc b/components/mus/ws/window_tree_client_unittest.cc
index 7401a9a..f98da25a 100644
--- a/components/mus/ws/window_tree_client_unittest.cc
+++ b/components/mus/ws/window_tree_client_unittest.cc
@@ -75,7 +75,6 @@
     mojom::WindowTreeClientPtr client;
     connector->ConnectToInterface(url.get(), &client);
     tree->Embed(root_id, std::move(client),
-                mojom::WindowTree::kAccessPolicyDefault,
                 base::Bind(&EmbedCallbackImpl, &run_loop, &result));
   }
   run_loop.Run();
@@ -87,7 +86,6 @@
   base::RunLoop run_loop;
   {
     tree->Embed(root_id, std::move(client),
-                mojom::WindowTree::kAccessPolicyDefault,
                 base::Bind(&EmbedCallbackImpl, &run_loop, &result));
   }
   run_loop.Run();
@@ -540,8 +538,8 @@
       WindowTree* owner,
       Id root_id,
       int* connection_id) {
-    return EstablishConnectionViaEmbedWithPolicyBitmask(
-        owner, root_id, mojom::WindowTree::kAccessPolicyDefault, connection_id);
+    return EstablishConnectionViaEmbedWithPolicyBitmask(owner, root_id,
+                                                        connection_id);
   }
 
   scoped_ptr<TestWindowTreeClientImpl>
@@ -1768,8 +1766,8 @@
   ASSERT_TRUE(
       wt_client1()->AddWindow(BuildWindowId(connection_id_1(), 1), window_1_2));
   ASSERT_TRUE(wt_client3_.get() == nullptr);
-  wt_client3_ = EstablishConnectionViaEmbedWithPolicyBitmask(
-      wt1(), window_1_2, mojom::WindowTree::kAccessPolicyEmbedRoot, nullptr);
+  wt_client3_ =
+      EstablishConnectionViaEmbedWithPolicyBitmask(wt1(), window_1_2, nullptr);
   ASSERT_TRUE(wt_client3_.get() != nullptr);
 
   // window_1_2 is ws3's root, so even though v3 is an embed root it should not
diff --git a/components/mus/ws/window_tree_factory.cc b/components/mus/ws/window_tree_factory.cc
index 56654ce..e805ab6 100644
--- a/components/mus/ws/window_tree_factory.cc
+++ b/components/mus/ws/window_tree_factory.cc
@@ -26,8 +26,7 @@
     mojo::InterfaceRequest<mojom::WindowTree> tree_request,
     mojom::WindowTreeClientPtr client) {
   scoped_ptr<ws::WindowTree> service(
-      new ws::WindowTree(connection_manager_, user_id_, nullptr,
-                         mojom::WindowTree::kAccessPolicyDefault));
+      new ws::WindowTree(connection_manager_, user_id_, nullptr));
   scoped_ptr<ws::DefaultWindowTreeBinding> binding(
       new ws::DefaultWindowTreeBinding(service.get(), connection_manager_,
                                        std::move(tree_request),
diff --git a/components/mus/ws/window_tree_unittest.cc b/components/mus/ws/window_tree_unittest.cc
index ce37fe7..bd55e09 100644
--- a/components/mus/ws/window_tree_unittest.cc
+++ b/components/mus/ws/window_tree_unittest.cc
@@ -106,8 +106,8 @@
   // DisplayBinding:
   WindowTree* CreateWindowTree(ServerWindow* root) override {
     return connection_manager_->EmbedAtWindow(
-        root, mus::mojom::WindowTree::kAccessPolicyEmbedRoot,
-        mojo::shell::mojom::kRootUserID, mus::mojom::WindowTreeClientPtr());
+        root, mojo::shell::mojom::kRootUserID,
+        mus::mojom::WindowTreeClientPtr());
   }
 
   Display* display_;
@@ -224,8 +224,7 @@
   WindowTree* CreateNewTree(const UserId& user_id,
                             TestWindowTreeBinding** binding) {
     WindowTree* tree =
-        new WindowTree(connection_manager_.get(), user_id, nullptr,
-                       mojom::WindowTree::kAccessPolicyDefault);
+        new WindowTree(connection_manager_.get(), user_id, nullptr);
     *binding = new TestWindowTreeBinding;
     connection_manager_->AddTree(make_scoped_ptr(tree),
                                  make_scoped_ptr(*binding), nullptr);
@@ -278,9 +277,7 @@
   mojom::WindowTreeClientPtr client;
   mojom::WindowTreeClientRequest client_request = GetProxy(&client);
   wm_client()->Bind(std::move(client_request));
-  ConnectionSpecificId connection_id = 0;
-  wm_tree()->Embed(embed_window_id, std::move(client),
-                   mojom::WindowTree::kAccessPolicyDefault, &connection_id);
+  wm_tree()->Embed(embed_window_id, std::move(client));
   ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id);
   WindowTree* tree1 = connection_manager()->GetTreeWithRoot(embed_window);
   ASSERT_TRUE(tree1 != nullptr);
@@ -324,9 +321,7 @@
   mojom::WindowTreeClientPtr client;
   mojom::WindowTreeClientRequest client_request = GetProxy(&client);
   wm_client()->Bind(std::move(client_request));
-  ConnectionSpecificId connection_id = 0;
-  wm_tree()->Embed(embed_window_id, std::move(client),
-                   mojom::WindowTree::kAccessPolicyDefault, &connection_id);
+  wm_tree()->Embed(embed_window_id, std::move(client));
   WindowTree* tree1 = connection_manager()->GetTreeWithRoot(embed_window);
   ASSERT_TRUE(tree1 != nullptr);
   ASSERT_NE(tree1, wm_tree());
diff --git a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
index 1625611..20f4d8a8 100644
--- a/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
+++ b/components/page_load_metrics/renderer/metrics_render_frame_observer.cc
@@ -87,9 +87,6 @@
     return false;
 
   const blink::WebURLResponse& url_response = frame->dataSource()->response();
-  // Ignore multipart responses (e.g. MHTML).
-  if (url_response.isMultipartPayload())
-    return false;
 
   // Ignore non-HTML documents (e.g. SVG). Note that images are treated by
   // Blink as HTML documents, so to exclude images, we must perform
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 1403ea6..c9bcdfe7 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -137,7 +137,7 @@
 #   persistent IDs for all fields (but not for groups!) are needed. These are
 #   specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
 #   because doing so would break the deployed wire format!
-#   For your editing convenience: highest ID currently used: 321
+#   For your editing convenience: highest ID currently used: 322
 #
 # Placeholders:
 #   The following placeholder strings are automatically substituted:
@@ -8303,6 +8303,42 @@
 
       If set to SAML_INTERSTITIAL, login will show an interstitial screen offering the user to go forward with authentication via the SAML IdP of the device's enrollment domain, or go back to the normal GAIA login flow.'''
     },
+    {
+      'name': 'UsbDetachableWhitelist',
+      'type': 'list',
+      'schema': {
+        'type': 'array',
+        'items': {
+          'type': 'object',
+          'id': 'UsbDeviceId',
+          'properties': {
+            'vendor_id': { 'type': 'integer' },
+            'product_id': { 'type': 'integer' },
+          },
+        },
+      },
+      'supported_on': ['chrome_os:51-'],
+      'device_only': True,
+      'features': {
+        'dynamic_refresh': True,
+      },
+      'example_value': [
+        {
+          'vendor_id' : 1027,
+          'product_id' : 24577,
+        },
+        {
+          'vendor_id' : 16700,
+          'product_id' : 8453,
+        }
+      ],
+      'id': 322,
+      'caption': '''Whitelist of USB detachable devices''',
+      'tags': ['system-security'],
+      'desc': '''Defines the list of USB devices that are allowed to be detached from their kernel driver in order to be used through the chrome.usb API directly inside a web application. Entries are pairs of USB Vendor Identifier and Product Identifier to identify a specific hardware.
+
+      If this policy is not configured, the list of a detachable USB devices is considered as empty.''',
+    },
   ],
   'messages': {
     # Messages that are not associated to any policies.
diff --git a/components/precache/OWNERS b/components/precache/OWNERS
index 38f02cc1..ced90566f 100644
--- a/components/precache/OWNERS
+++ b/components/precache/OWNERS
@@ -1,2 +1,3 @@
 bengr@chromium.org
 sclittle@chromium.org
+twifkak@chromium.org
diff --git a/components/precache/content/precache_manager.cc b/components/precache/content/precache_manager.cc
index cf0baea..a815b16 100644
--- a/components/precache/content/precache_manager.cc
+++ b/components/precache/content/precache_manager.cc
@@ -59,10 +59,16 @@
   BrowserThread::PostTask(
       BrowserThread::DB, FROM_HERE,
       base::Bind(base::IgnoreResult(&PrecacheDatabase::Init),
-                 precache_database_, db_path));
+                 base::Unretained(precache_database_.get()), db_path));
 }
 
-PrecacheManager::~PrecacheManager() {}
+PrecacheManager::~PrecacheManager() {
+  // DeleteSoon posts a non-nestable task to the task runner, so any previously
+  // posted tasks that rely on an Unretained precache_database_ will finish
+  // before it is deleted.
+  BrowserThread::DeleteSoon(BrowserThread::DB, FROM_HERE,
+                            precache_database_.release());
+}
 
 bool PrecacheManager::IsInExperimentGroup() const {
   // Verify IsPrecachingAllowed() before calling FieldTrialList::FindFullName().
@@ -121,7 +127,8 @@
     BrowserThread::PostTask(
         BrowserThread::DB, FROM_HERE,
         base::Bind(&PrecacheDatabase::DeleteExpiredPrecacheHistory,
-                   precache_database_, base::Time::Now()));
+                   base::Unretained(precache_database_.get()),
+                   base::Time::Now()));
 
     // Request NumTopHosts() top hosts. Note that PrecacheFetcher is further
     // bound by the value of PrecacheConfigurationSettings.top_sites_count, as
@@ -209,8 +216,9 @@
     // by precaching.
     BrowserThread::PostTask(
         BrowserThread::DB, FROM_HERE,
-        base::Bind(&PrecacheDatabase::RecordURLPrefetch, precache_database_,
-                   url, latency, fetch_time, size, was_cached));
+        base::Bind(&PrecacheDatabase::RecordURLPrefetch,
+                   base::Unretained(precache_database_.get()), url, latency,
+                   fetch_time, size, was_cached));
   } else {
     bool is_connection_cellular =
         net::NetworkChangeNotifier::IsConnectionCellular(
@@ -218,8 +226,9 @@
 
     BrowserThread::PostTask(
         BrowserThread::DB, FROM_HERE,
-        base::Bind(&PrecacheDatabase::RecordURLNonPrefetch, precache_database_,
-                   url, latency, fetch_time, size, was_cached, host_rank,
+        base::Bind(&PrecacheDatabase::RecordURLNonPrefetch,
+                   base::Unretained(precache_database_.get()), url, latency,
+                   fetch_time, size, was_cached, host_rank,
                    is_connection_cellular));
   }
 }
@@ -230,7 +239,8 @@
   // base::SequencedTaskRunner for details.
   BrowserThread::PostNonNestableTask(
       BrowserThread::DB, FROM_HERE,
-      base::Bind(&PrecacheDatabase::ClearHistory, precache_database_));
+      base::Bind(&PrecacheDatabase::ClearHistory,
+                 base::Unretained(precache_database_.get())));
 }
 
 void PrecacheManager::Shutdown() {
diff --git a/components/precache/content/precache_manager.h b/components/precache/content/precache_manager.h
index 2735f98..7136713 100644
--- a/components/precache/content/precache_manager.h
+++ b/components/precache/content/precache_manager.h
@@ -16,7 +16,6 @@
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "components/history/core/browser/history_types.h"
@@ -158,7 +157,7 @@
 
   // The PrecacheDatabase for tracking precache metrics. Should only be used on
   // the DB thread.
-  const scoped_refptr<PrecacheDatabase> precache_database_;
+  scoped_ptr<PrecacheDatabase> precache_database_;
 
   // Flag indicating whether or not precaching is currently in progress.
   bool is_precaching_;
diff --git a/components/precache/core/precache_database.cc b/components/precache/core/precache_database.cc
index 42b110e..8cf4dac 100644
--- a/components/precache/core/precache_database.cc
+++ b/components/precache/core/precache_database.cc
@@ -26,16 +26,16 @@
 
 namespace precache {
 
-PrecacheDatabase::PrecacheDatabase() : is_flush_posted_(false) {
+PrecacheDatabase::PrecacheDatabase()
+    : is_flush_posted_(false), weak_factory_(this) {
   // A PrecacheDatabase can be constructed on any thread.
   thread_checker_.DetachFromThread();
 }
 
 PrecacheDatabase::~PrecacheDatabase() {
-  // Since the PrecacheDatabase is refcounted, it will only be deleted if there
-  // are no references remaining to it, meaning that it is not in use. Thus, it
-  // is safe to delete it, regardless of what thread we are on.
-  thread_checker_.DetachFromThread();
+  // The destructor must not run on the UI thread, as it may trigger IO
+  // operations via sql::Connection's destructor.
+  DCHECK(thread_checker_.CalledOnValidThread());
 }
 
 bool PrecacheDatabase::Init(const base::FilePath& db_path) {
@@ -254,7 +254,7 @@
   // transaction.
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::Bind(&PrecacheDatabase::PostedFlush,
-                            scoped_refptr<PrecacheDatabase>(this)),
+                            weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromSeconds(1));
   is_flush_posted_ = true;
 }
diff --git a/components/precache/core/precache_database.h b/components/precache/core/precache_database.h
index 7c74f47..0f567b8 100644
--- a/components/precache/core/precache_database.h
+++ b/components/precache/core/precache_database.h
@@ -13,8 +13,8 @@
 #include "base/callback.h"
 #include "base/containers/hash_tables.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "components/precache/core/precache_url_table.h"
 
@@ -31,14 +31,16 @@
 
 namespace precache {
 
-// Class that tracks information related to precaching. This class can be
-// constructed or destroyed on any threads, but all other methods must be called
-// on the same thread (e.g. the DB thread).
-class PrecacheDatabase : public base::RefCountedThreadSafe<PrecacheDatabase> {
+// Class that tracks information related to precaching. This class may be
+// constructed on any thread, but all calls to, and destruction of this class
+// must be done on the the DB thread.
+class PrecacheDatabase {
  public:
   // A PrecacheDatabase can be constructed on any thread.
   PrecacheDatabase();
 
+  ~PrecacheDatabase();
+
   // Initializes the precache database, using the specified database file path.
   // Init must be called before any other methods.
   bool Init(const base::FilePath& db_path);
@@ -70,11 +72,8 @@
                             bool is_connection_cellular);
 
  private:
-  friend class base::RefCountedThreadSafe<PrecacheDatabase>;
   friend class PrecacheDatabaseTest;
 
-  ~PrecacheDatabase();
-
   bool IsDatabaseAccessible() const;
 
   // Flushes any buffered write operations. |buffered_writes_| will be empty
@@ -113,6 +112,8 @@
   // or destructor are called on the same thread.
   base::ThreadChecker thread_checker_;
 
+  base::WeakPtrFactory<PrecacheDatabase> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(PrecacheDatabase);
 };
 
diff --git a/components/precache/core/precache_database_unittest.cc b/components/precache/core/precache_database_unittest.cc
index 65a4dae..36e2584 100644
--- a/components/precache/core/precache_database_unittest.cc
+++ b/components/precache/core/precache_database_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/containers/hash_tables.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram_base.h"
 #include "base/test/histogram_tester.h"
@@ -50,7 +51,7 @@
 
  protected:
   void SetUp() override {
-    precache_database_ = new PrecacheDatabase();
+    precache_database_.reset(new PrecacheDatabase());
 
     ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
     base::FilePath db_path = scoped_temp_dir_.path().Append(
@@ -107,7 +108,7 @@
   // to be set properly.
   base::MessageLoopForUI loop_;
 
-  scoped_refptr<PrecacheDatabase> precache_database_;
+  scoped_ptr<PrecacheDatabase> precache_database_;
   base::HistogramTester histograms_;
   base::HistogramTester::CountsMap expected_histogram_counts_;
 
diff --git a/components/resource_provider/resource_provider_apptest.cc b/components/resource_provider/resource_provider_apptest.cc
index 1632a2a..a4c84adc 100644
--- a/components/resource_provider/resource_provider_apptest.cc
+++ b/components/resource_provider/resource_provider_apptest.cc
@@ -14,7 +14,6 @@
 #include "mojo/common/common_type_converters.h"
 #include "mojo/platform_handle/platform_handle_functions.h"
 #include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/shell/public/cpp/application_test_base.h"
 
 namespace resource_provider {
diff --git a/components/signin/core/common/profile_management_switches.cc b/components/signin/core/common/profile_management_switches.cc
index 57c99e7..a4977622 100644
--- a/components/signin/core/common/profile_management_switches.cc
+++ b/components/signin/core/common/profile_management_switches.cc
@@ -4,6 +4,8 @@
 
 #include "components/signin/core/common/profile_management_switches.h"
 
+#include <string>
+
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/metrics/field_trial.h"
@@ -134,6 +136,10 @@
       switches::kUsePasswordSeparatedSigninFlow);
 }
 
+bool IsMaterialDesignUserManager() {
+  return base::FeatureList::IsEnabled(switches::kMaterialDesignUserManager);
+}
+
 void EnableNewProfileManagementForTesting(base::CommandLine* command_line) {
   command_line->AppendSwitch(switches::kEnableNewProfileManagement);
   DCHECK(!command_line->HasSwitch(switches::kDisableNewProfileManagement));
diff --git a/components/signin/core/common/profile_management_switches.h b/components/signin/core/common/profile_management_switches.h
index 2b60446..a2f1f1c6 100644
--- a/components/signin/core/common/profile_management_switches.h
+++ b/components/signin/core/common/profile_management_switches.h
@@ -35,6 +35,9 @@
 // Checks whether the new gaia password separated sign in flow is enabled.
 bool UsePasswordSeparatedSigninFlow();
 
+// Whether the new Material Design User Manager should be displayed.
+bool IsMaterialDesignUserManager();
+
 // Called in tests to force enabling different modes.
 void EnableNewProfileManagementForTesting(base::CommandLine* command_line);
 void EnableAccountConsistencyForTesting(base::CommandLine* command_line);
diff --git a/components/signin/core/common/signin_switches.cc b/components/signin/core/common/signin_switches.cc
index 14564c0..504d75c 100644
--- a/components/signin/core/common/signin_switches.cc
+++ b/components/signin/core/common/signin_switches.cc
@@ -35,10 +35,14 @@
 // Enables using GAIA information to populate profile name and icon.
 const char kGoogleProfileInfo[] = "google-profile-info";
 
+const base::Feature kMaterialDesignUserManager {
+  "MaterialDesignUserManager", base::FEATURE_DISABLED_BY_DEFAULT
+};
+
 // Enables or disables the new password separated sign in flow in a tab modal
 // dialog.
 const base::Feature kUsePasswordSeparatedSigninFlow {
- "UsePasswordSeparatedSigninFlow", base::FEATURE_DISABLED_BY_DEFAULT
+  "UsePasswordSeparatedSigninFlow", base::FEATURE_DISABLED_BY_DEFAULT
 };
 
 }  // namespace switches
diff --git a/components/signin/core/common/signin_switches.h b/components/signin/core/common/signin_switches.h
index afc8f18..3407c82 100644
--- a/components/signin/core/common/signin_switches.h
+++ b/components/signin/core/common/signin_switches.h
@@ -25,6 +25,7 @@
 extern const char kExtensionsMultiAccount[];
 extern const char kGoogleProfileInfo[];
 
+extern const base::Feature kMaterialDesignUserManager;
 extern const base::Feature kUsePasswordSeparatedSigninFlow;
 
 }  // namespace switches
diff --git a/components/user_manager/user_image/user_image.cc b/components/user_manager/user_image/user_image.cc
index af37983..10cd4482 100644
--- a/components/user_manager/user_image/user_image.cc
+++ b/components/user_manager/user_image/user_image.cc
@@ -15,30 +15,35 @@
 // Default quality for encoding user images.
 const int kDefaultEncodingQuality = 90;
 
-bool EncodeImageSkia(const gfx::ImageSkia& image,
-                     UserImage::Bytes* output) {
-  TRACE_EVENT2("oobe", "EncodeImageSkia",
-               "width", image.width(), "height", image.height());
-  if (image.isNull())
-    return false;
-  const SkBitmap& bitmap = *image.bitmap();
-  SkAutoLockPixels lock_image(bitmap);
-  return gfx::JPEGCodec::Encode(
-      reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
-      gfx::JPEGCodec::FORMAT_SkBitmap,
-      bitmap.width(),
-      bitmap.height(),
-      bitmap.width() * bitmap.bytesPerPixel(),
-      kDefaultEncodingQuality, output);
-}
-
 }  // namespace
 
 // static
+scoped_ptr<UserImage::Bytes> UserImage::Encode(const SkBitmap& bitmap) {
+  TRACE_EVENT2("oobe", "UserImage::Encode",
+               "width", bitmap.width(), "height", bitmap.height());
+  SkAutoLockPixels lock_bitmap(bitmap);
+  scoped_ptr<Bytes> output(new Bytes);
+  if (gfx::JPEGCodec::Encode(
+          reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
+          gfx::JPEGCodec::FORMAT_SkBitmap,
+          bitmap.width(),
+          bitmap.height(),
+          bitmap.width() * bitmap.bytesPerPixel(),
+          kDefaultEncodingQuality, output.get())) {
+    return output;
+  } else {
+    return nullptr;
+  }
+}
+
+// static
 UserImage UserImage::CreateAndEncode(const gfx::ImageSkia& image) {
-  Bytes image_bytes;
-  if (EncodeImageSkia(image, &image_bytes)) {
-    UserImage result(image, image_bytes);
+  if (image.isNull())
+    return UserImage();
+
+  scoped_ptr<Bytes> image_bytes = Encode(*image.bitmap());
+  if (image_bytes) {
+    UserImage result(image, *image_bytes);
     result.MarkAsSafe();
     return result;
   }
diff --git a/components/user_manager/user_image/user_image.h b/components/user_manager/user_image/user_image.h
index 6397096..d6621be 100644
--- a/components/user_manager/user_image/user_image.h
+++ b/components/user_manager/user_image/user_image.h
@@ -24,6 +24,10 @@
   // TODO(ivankr): replace with RefCountedMemory to prevent copying.
   typedef std::vector<unsigned char> Bytes;
 
+  // Encodes the given bitmap to bytes representation for WebUI. Returns null
+  // on failure.
+  static scoped_ptr<Bytes> Encode(const SkBitmap& bitmap);
+
   // Creates a new instance from a given still frame and tries to encode it
   // to bytes representation for WebUI.
   // TODO(ivankr): remove eventually.
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index ebf3a99..f2d4da7 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -141,6 +141,8 @@
       tree_(new ui::AXSerializableTree()),
       user_is_navigating_away_(false),
       osk_state_(OSK_ALLOWED),
+      last_focused_node_(nullptr),
+      last_focused_manager_(nullptr),
       ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID),
       parent_node_id_from_parent_tree_(0) {
   tree_->SetDelegate(this);
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index e43d778..68e977938 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1089,13 +1089,29 @@
   RunHtmlTest(FILE_PATH_LITERAL("modal-dialog-opened.html"));
 }
 
+// Flaky on Windows: crbug.com/593846
+#if defined(OS_WIN)
+#define MAYBE_AccessibilityModalDialogInIframeClosed \
+    DISABLED_AccessibilityModalDialogInIframeClosed
+#else
+#define MAYBE_AccessibilityModalDialogInIframeClosed \
+    AccessibilityModalDialogInIframeClosed
+#endif
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
-                       AccessibilityModalDialogInIframeClosed) {
+                       MAYBE_AccessibilityModalDialogInIframeClosed) {
   RunHtmlTest(FILE_PATH_LITERAL("modal-dialog-in-iframe-closed.html"));
 }
 
+// Flaky on Windows: crbug.com/593846
+#if defined(OS_WIN)
+#define MAYBE_AccessibilityModalDialogInIframeOpened \
+    DISABLED_AccessibilityModalDialogInIframeOpened
+#else
+#define MAYBE_AccessibilityModalDialogInIframeOpened \
+    AccessibilityModalDialogInIframeOpened
+#endif
 IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
-                       AccessibilityModalDialogInIframeOpened) {
+                       MAYBE_AccessibilityModalDialogInIframeOpened) {
   RunHtmlTest(FILE_PATH_LITERAL("modal-dialog-in-iframe-opened.html"));
 }
 
diff --git a/content/browser/android/composited_touch_handle_drawable.cc b/content/browser/android/composited_touch_handle_drawable.cc
index 235e2eef..bef3819 100644
--- a/content/browser/android/composited_touch_handle_drawable.cc
+++ b/content/browser/android/composited_touch_handle_drawable.cc
@@ -9,6 +9,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/trace_event/trace_event.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "content/public/browser/android/compositor.h"
 #include "jni/HandleViewResources_jni.h"
@@ -96,7 +97,7 @@
     jobject context)
     : dpi_scale_(dpi_scale),
       orientation_(ui::TouchHandleOrientation::UNDEFINED),
-      layer_(cc::UIResourceLayer::Create(Compositor::LayerSettings())) {
+      layer_(cc::UIResourceLayer::Create(cc::LayerSettings())) {
   g_selection_resources.Get().LoadIfNecessary(context);
   drawable_horizontal_padding_ratio_ =
       g_selection_resources.Get().GetDrawableHorizontalPaddingRatio();
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc
index 0606bc21..b588ded 100644
--- a/content/browser/android/content_startup_flags.cc
+++ b/content/browser/android/content_startup_flags.cc
@@ -10,7 +10,6 @@
 #include "base/logging.h"
 #include "base/sys_info.h"
 #include "cc/base/switches.h"
-#include "cc/layers/layer_settings.h"
 #include "content/public/browser/android/compositor.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
@@ -79,12 +78,6 @@
     parsed_command_line->AppendSwitchASCII(
         switches::kProfilerTiming, switches::kProfilerTimingDisabledValue);
   }
-
-  cc::LayerSettings layer_settings;
-  layer_settings.use_compositor_animation_timelines =
-      !parsed_command_line->HasSwitch(
-          switches::kDisableAndroidCompositorAnimationTimelines);
-  Compositor::SetLayerSettings(layer_settings);
 }
 
 }  // namespace content
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 1022d4f..113ccb4 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -17,8 +17,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/output/begin_frame_args.h"
+#include "cc/output/viewport_selection_bound.h"
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/browser/android/gesture_event_type.h"
 #include "content/browser/android/interstitial_page_delegate_android.h"
@@ -213,7 +215,7 @@
     : WebContentsObserver(web_contents),
       java_ref_(env, obj),
       web_contents_(static_cast<WebContentsImpl*>(web_contents)),
-      root_layer_(cc::SolidColorLayer::Create(Compositor::LayerSettings())),
+      root_layer_(cc::SolidColorLayer::Create(cc::LayerSettings())),
       page_scale_(1),
       dpi_scale_(ui::GetScaleFactorForNativeView(this)),
       window_android_(window_android),
@@ -420,7 +422,8 @@
     const gfx::SizeF& viewport_size,
     const gfx::Vector2dF& controls_offset,
     const gfx::Vector2dF& content_offset,
-    bool is_mobile_optimized_hint) {
+    bool is_mobile_optimized_hint,
+    const cc::ViewportSelectionBound& selection_start) {
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
   if (obj.is_null() || !window_android_)
@@ -431,6 +434,18 @@
 
   page_scale_ = page_scale_factor;
 
+  // The CursorAnchorInfo API in Android only supports zero width selection
+  // bounds.
+  const jboolean has_insertion_marker =
+      selection_start.type == cc::SELECTION_BOUND_CENTER;
+  const jboolean is_insertion_marker_visible = selection_start.visible;
+  const jfloat insertion_marker_horizontal =
+      has_insertion_marker ? selection_start.edge_top.x() : 0.0f;
+  const jfloat insertion_marker_top =
+      has_insertion_marker ? selection_start.edge_top.y() : 0.0f;
+  const jfloat insertion_marker_bottom =
+      has_insertion_marker ? selection_start.edge_bottom.y() : 0.0f;
+
   Java_ContentViewCore_updateFrameInfo(
       env, obj.obj(),
       scroll_offset.x(),
@@ -444,7 +459,12 @@
       viewport_size.height(),
       controls_offset.y(),
       content_offset.y(),
-      is_mobile_optimized_hint);
+      is_mobile_optimized_hint,
+      has_insertion_marker,
+      is_insertion_marker_visible,
+      insertion_marker_horizontal,
+      insertion_marker_top,
+      insertion_marker_bottom);
 }
 
 void ContentViewCoreImpl::SetTitle(const base::string16& title) {
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index c756a59..a00cccf 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -28,6 +28,10 @@
 #include "ui/gfx/geometry/rect_f.h"
 #include "url/gurl.h"
 
+namespace cc {
+struct ViewportSelectionBound;
+}
+
 namespace ui {
 class WindowAndroid;
 }
@@ -316,7 +320,8 @@
                        const gfx::SizeF& viewport_size,
                        const gfx::Vector2dF& controls_offset,
                        const gfx::Vector2dF& content_offset,
-                       bool is_mobile_optimized_hint);
+                       bool is_mobile_optimized_hint,
+                       const cc::ViewportSelectionBound& selection_start);
 
   void ForceUpdateImeAdapter(long native_ime_adapter);
   void UpdateImeAdapter(long native_ime_adapter,
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
index 385bb4f..4dba524b 100644
--- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc
@@ -118,6 +118,11 @@
   return synchronous_input_event_filter();
 }
 
+SynchronousInputHandlerProxyClient*
+SynchronousCompositorFactoryImpl::GetSynchronousInputHandlerProxyClient() {
+  return synchronous_input_event_filter();
+}
+
 scoped_ptr<cc::BeginFrameSource>
 SynchronousCompositorFactoryImpl::CreateExternalBeginFrameSource(
     int routing_id) {
diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.h b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
index be0d978..79b2625 100644
--- a/content/browser/android/in_process/synchronous_compositor_factory_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.h
@@ -45,6 +45,8 @@
       const scoped_refptr<cc::ContextProvider>& onscreen_context,
       const scoped_refptr<cc::ContextProvider>& worker_context) override;
   InputHandlerManagerClient* GetInputHandlerManagerClient() override;
+  SynchronousInputHandlerProxyClient* GetSynchronousInputHandlerProxyClient()
+      override;
   scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
       int routing_id) override;
 
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index a10e608..ed99e093 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -279,7 +279,7 @@
   rwhva_->OnSetNeedsBeginFrames(is_active_ && renderer_needs_begin_frames_);
 }
 
-void SynchronousCompositorImpl::DidOverscroll(
+void SynchronousCompositorImpl::DidOverscrollInProcess(
     const DidOverscrollParams& params) {
   if (registered_with_client_) {
     compositor_client_->DidOverscroll(params.accumulated_overscroll,
@@ -303,6 +303,13 @@
       routing_id_, input_event);
 }
 
+void SynchronousCompositorImpl::DidOverscroll(
+    const DidOverscrollParams& params) {
+  // SynchronousCompositorImpl uses synchronous DidOverscrollInProcess for
+  // overscroll instead of this async path.
+  NOTREACHED();
+}
+
 bool SynchronousCompositorImpl::OnMessageReceived(const IPC::Message& message) {
   NOTREACHED();
   return false;
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index b7884058..2c7e5b5 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -79,6 +79,7 @@
   void BeginFrame(const cc::BeginFrameArgs& args) override;
   InputEventAckState HandleInputEvent(
       const blink::WebInputEvent& input_event) override;
+  void DidOverscroll(const DidOverscrollParams& params) override;
   bool OnMessageReceived(const IPC::Message& message) override;
   void DidBecomeCurrent() override;
 
@@ -91,7 +92,7 @@
                             float min_page_scale_factor,
                             float max_page_scale_factor) override;
 
-  void DidOverscroll(const DidOverscrollParams& params);
+  void DidOverscrollInProcess(const DidOverscrollParams& params);
   void DidStopFlinging();
 
  private:
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.cc b/content/browser/android/in_process/synchronous_input_event_filter.cc
index 80f10250..9057da83 100644
--- a/content/browser/android/in_process/synchronous_input_event_filter.cc
+++ b/content/browser/android/in_process/synchronous_input_event_filter.cc
@@ -40,26 +40,15 @@
                  base::Unretained(this), handler));
 }
 
+void SynchronousInputEventFilter::DidAddInputHandler(int routing_id) {}
+void SynchronousInputEventFilter::DidRemoveInputHandler(int routing_id) {}
+
 void SynchronousInputEventFilter::SetBoundHandlerOnUIThread(
     const Handler& handler) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   handler_ = handler;
 }
 
-void SynchronousInputEventFilter::DidAddInputHandler(
-    int routing_id,
-    ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  SynchronousCompositorRegistryInProc::GetInstance()->RegisterInputHandler(
-      routing_id, synchronous_input_handler_proxy);
-}
-
-void SynchronousInputEventFilter::DidRemoveInputHandler(int routing_id) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  SynchronousCompositorRegistryInProc::GetInstance()->UnregisterInputHandler(
-      routing_id);
-}
-
 void SynchronousInputEventFilter::DidOverscroll(
     int routing_id,
     const DidOverscrollParams& params) {
@@ -68,7 +57,7 @@
   SynchronousCompositorImpl* compositor =
       SynchronousCompositorImpl::FromRoutingID(routing_id);
   if (compositor)
-    compositor->DidOverscroll(params);
+    compositor->DidOverscrollInProcess(params);
 }
 
 void SynchronousInputEventFilter::DidStopFlinging(int routing_id) {
@@ -84,4 +73,19 @@
     int routing_id,
     blink::WebInputEvent::Type type) {}
 
+void SynchronousInputEventFilter::DidAddSynchronousHandlerProxy(
+    int routing_id,
+    ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  SynchronousCompositorRegistryInProc::GetInstance()->RegisterInputHandler(
+      routing_id, synchronous_input_handler_proxy);
+}
+
+void SynchronousInputEventFilter::DidRemoveSynchronousHandlerProxy(
+    int routing_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  SynchronousCompositorRegistryInProc::GetInstance()->UnregisterInputHandler(
+      routing_id);
+}
+
 }  // namespace content
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.h b/content/browser/android/in_process/synchronous_input_event_filter.h
index 32b6ecbc..61ba62b 100644
--- a/content/browser/android/in_process/synchronous_input_event_filter.h
+++ b/content/browser/android/in_process/synchronous_input_event_filter.h
@@ -26,7 +26,9 @@
 // The provided |handler| process WebInputEvents synchronously on the merged
 // UI and compositing thread. If the event goes unhandled, that is reflected in
 // the InputEventAckState; no forwarding is performed.
-class SynchronousInputEventFilter : public InputHandlerManagerClient {
+class SynchronousInputEventFilter
+    : public InputHandlerManagerClient,
+      public SynchronousInputHandlerProxyClient {
  public:
   SynchronousInputEventFilter();
   ~SynchronousInputEventFilter() override;
@@ -36,10 +38,7 @@
 
   // InputHandlerManagerClient implementation.
   void SetBoundHandler(const Handler& handler) override;
-  void DidAddInputHandler(
-      int routing_id,
-      ui::SynchronousInputHandlerProxy*
-          synchronous_input_handler_proxy) override;
+  void DidAddInputHandler(int routing_id) override;
   void DidRemoveInputHandler(int routing_id) override;
   void DidOverscroll(int routing_id,
                      const DidOverscrollParams& params) override;
@@ -47,6 +46,13 @@
   void NonBlockingInputEventHandled(int routing_id,
                                     blink::WebInputEvent::Type type) override;
 
+  // SynchronousInputHandlerProxyClient overrides.
+  void DidAddSynchronousHandlerProxy(
+      int routing_id,
+      ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy)
+      override;
+  void DidRemoveSynchronousHandlerProxy(int routing_id) override;
+
  private:
   void SetBoundHandlerOnUIThread(const Handler& handler);
 
diff --git a/content/browser/android/synchronous_compositor_base.cc b/content/browser/android/synchronous_compositor_base.cc
index 39d8b24..0d08509 100644
--- a/content/browser/android/synchronous_compositor_base.cc
+++ b/content/browser/android/synchronous_compositor_base.cc
@@ -66,11 +66,13 @@
 
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   if (command_line->HasSwitch(switches::kIPCSyncCompositing)) {
+    bool async_input =
+        !command_line->HasSwitch(switches::kSyncInputForSyncCompositor);
     bool use_in_proc_software_draw =
         command_line->HasSwitch(switches::kSingleProcess);
     return make_scoped_ptr(new SynchronousCompositorHost(
         rwhva, web_contents_android->synchronous_compositor_client(),
-        use_in_proc_software_draw));
+        async_input, use_in_proc_software_draw));
   }
   return make_scoped_ptr(new SynchronousCompositorImpl(
       rwhva, web_contents_android->synchronous_compositor_client()));
diff --git a/content/browser/android/synchronous_compositor_base.h b/content/browser/android/synchronous_compositor_base.h
index c269ed4e..218e821 100644
--- a/content/browser/android/synchronous_compositor_base.h
+++ b/content/browser/android/synchronous_compositor_base.h
@@ -26,6 +26,7 @@
 class RenderWidgetHostViewAndroid;
 class SynchronousCompositorStreamTextureFactoryImpl;
 class WebContents;
+struct DidOverscrollParams;
 
 class SynchronousCompositorBase : public SynchronousCompositor {
  public:
@@ -38,6 +39,7 @@
   virtual void BeginFrame(const cc::BeginFrameArgs& args) = 0;
   virtual InputEventAckState HandleInputEvent(
       const blink::WebInputEvent& input_event) = 0;
+  virtual void DidOverscroll(const DidOverscrollParams& over_scroll_params) = 0;
   virtual bool OnMessageReceived(const IPC::Message& message) = 0;
 
   virtual void DidBecomeCurrent() = 0;
diff --git a/content/browser/android/synchronous_compositor_host.cc b/content/browser/android/synchronous_compositor_host.cc
index 658c818d..6cb4907 100644
--- a/content/browser/android/synchronous_compositor_host.cc
+++ b/content/browser/android/synchronous_compositor_host.cc
@@ -30,6 +30,7 @@
 SynchronousCompositorHost::SynchronousCompositorHost(
     RenderWidgetHostViewAndroid* rwhva,
     SynchronousCompositorClient* client,
+    bool async_input,
     bool use_in_proc_software_draw)
     : rwhva_(rwhva),
       client_(client),
@@ -37,6 +38,7 @@
           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)),
       routing_id_(rwhva_->GetRenderWidgetHost()->GetRoutingID()),
       sender_(rwhva_->GetRenderWidgetHost()),
+      async_input_(async_input),
       use_in_process_zero_copy_software_draw_(use_in_proc_software_draw),
       is_active_(false),
       bytes_limit_(0u),
@@ -338,6 +340,8 @@
 
 InputEventAckState SynchronousCompositorHost::HandleInputEvent(
     const blink::WebInputEvent& input_event) {
+  if (async_input_)
+    return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
   SyncCompositorCommonBrowserParams common_browser_params;
   PopulateCommonParams(&common_browser_params);
   SyncCompositorCommonRendererParams common_renderer_params;
@@ -351,8 +355,15 @@
   return ack;
 }
 
+void SynchronousCompositorHost::DidOverscroll(
+    const DidOverscrollParams& over_scroll_params) {
+  client_->DidOverscroll(over_scroll_params.accumulated_overscroll,
+                         over_scroll_params.latest_overscroll_delta,
+                         over_scroll_params.current_fling_velocity);
+}
+
 void SynchronousCompositorHost::BeginFrame(const cc::BeginFrameArgs& args) {
-  if (!is_active_ || !need_begin_frame_)
+  if (!is_active_)
     return;
 
   SyncCompositorCommonBrowserParams common_browser_params;
@@ -370,9 +381,7 @@
     const SyncCompositorCommonRendererParams& params,
     const DidOverscrollParams& over_scroll_params) {
   ProcessCommonParams(params);
-  client_->DidOverscroll(over_scroll_params.accumulated_overscroll,
-                         over_scroll_params.latest_overscroll_delta,
-                         over_scroll_params.current_fling_velocity);
+  DidOverscroll(over_scroll_params);
 }
 
 void SynchronousCompositorHost::PopulateCommonParams(
diff --git a/content/browser/android/synchronous_compositor_host.h b/content/browser/android/synchronous_compositor_host.h
index 1d7f58d..90aafe5 100644
--- a/content/browser/android/synchronous_compositor_host.h
+++ b/content/browser/android/synchronous_compositor_host.h
@@ -51,6 +51,7 @@
   // SynchronousCompositorBase overrides.
   InputEventAckState HandleInputEvent(
       const blink::WebInputEvent& input_event) override;
+  void DidOverscroll(const DidOverscrollParams& over_scroll_params) override;
   void BeginFrame(const cc::BeginFrameArgs& args) override;
   bool OnMessageReceived(const IPC::Message& message) override;
   void DidBecomeCurrent() override;
@@ -63,6 +64,7 @@
 
   SynchronousCompositorHost(RenderWidgetHostViewAndroid* rwhva,
                             SynchronousCompositorClient* client,
+                            bool async_input,
                             bool use_in_proc_software_draw);
   void PopulateCommonParams(SyncCompositorCommonBrowserParams* params);
   void ProcessCommonParams(const SyncCompositorCommonRendererParams& params);
@@ -81,6 +83,7 @@
   const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
   const int routing_id_;
   IPC::Sender* const sender_;
+  const bool async_input_;
   const bool use_in_process_zero_copy_software_draw_;
 
   bool is_active_;
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 4df3837..58c0c35 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -135,6 +135,7 @@
   WSH_SEND_FRAME_DURING_BLOB_SEND = 111,
   RFH_UNEXPECTED_LOAD_START = 112,
   NMF_INVALID_ARGUMENT = 113,
+  RFH_INVALID_ORIGIN_ON_COMMIT = 114,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc
index 698ccde0..dd0c174 100644
--- a/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -1196,6 +1196,7 @@
                    FrameHostMsg_DidCommitProvisionalLoad_Params* params) {
   params->was_within_same_page = true;
   params->url = url;
+  params->origin = url::Origin(url);
 }
 }
 
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 705ab3a..cb35604 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/containers/hash_tables.h"
 #include "base/lazy_instance.h"
 #include "base/metrics/histogram.h"
@@ -71,6 +72,7 @@
 #include "content/public/browser/user_metrics.h"
 #include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/content_constants.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/common/isolated_world_ids.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
@@ -992,6 +994,15 @@
     // Kills the process.
     bad_message::ReceivedBadMessage(process,
                                     bad_message::RFH_CAN_COMMIT_URL_BLOCKED);
+    return;
+  }
+
+  // Verify that the origin passed from the renderer process is valid and can
+  // be allowed to commit in this RenderFrameHost.
+  if (!CanCommitOrigin(validated_params.origin, validated_params.url)) {
+    bad_message::ReceivedBadMessage(GetProcess(),
+                                    bad_message::RFH_INVALID_ORIGIN_ON_COMMIT);
+    return;
   }
 
   // Without this check, an evil renderer can trick the browser into creating
@@ -1930,6 +1941,42 @@
   return GetContentClient()->browser()->CanCommitURL(GetProcess(), url);
 }
 
+bool RenderFrameHostImpl::CanCommitOrigin(
+    const url::Origin& origin,
+    const GURL& url) {
+  // If the --disable-web-security flag is specified, all bets are off and the
+  // renderer process can send any origin it wishes.
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kDisableWebSecurity)) {
+    return true;
+  }
+
+  // file: URLs can be allowed to access any other origin, based on settings.
+  if (origin.scheme() == url::kFileScheme) {
+    WebPreferences prefs = render_view_host_->GetWebkitPreferences();
+    if (prefs.allow_universal_access_from_file_urls)
+      return true;
+  }
+
+  // It is safe to commit into a unique origin, regardless of the URL, as it is
+  // restricted from accessing other origins.
+  if (origin.unique())
+    return true;
+
+  // Standard URLs must match the reported origin.
+  if (url.IsStandard() && !origin.IsSameOriginWith(url::Origin(url)))
+    return false;
+
+  // A non-unique origin must be a valid URL, which allows us to safely do a
+  // conversion to GURL.
+  GURL origin_url(origin.Serialize());
+
+  // Verify that the origin is allowed to commit in this process.
+  // Note: This also handles non-standard cases for |url|, such as
+  // about:blank, data, and blob URLs.
+  return CanCommitURL(origin_url);
+}
+
 void RenderFrameHostImpl::Navigate(
     const CommonNavigationParams& common_params,
     const StartNavigationParams& start_params,
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index c8bfa7b..b52ab74 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -682,6 +682,13 @@
   // it will be used to kill processes that commit unauthorized URLs.
   bool CanCommitURL(const GURL& url);
 
+  // Returns whether the given origin is allowed to commit in the current
+  // RenderFrameHost. The |url| is used to ensure it matches the origin in cases
+  // where it is applicable. This is a more conservative check than
+  // RenderProcessHost::FilterURL, since it will be used to kill processes that
+  // commit unauthorized origins.
+  bool CanCommitOrigin(const url::Origin& origin, const GURL& url);
+
   // Asserts that the given RenderFrameHostImpl is part of the same browser
   // context (and crashes if not), then returns whether the given frame is
   // part of the same site instance.
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 0cea5319..b09d9456 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -2972,6 +2972,67 @@
   BaseSimultaneousNavigationWithTwoWebUIs(commit_new_frame_host);
 }
 
+TEST_F(RenderFrameHostManagerTest, CanCommitOrigin) {
+  const GURL kUrl("http://a.com/");
+  const GURL kUrlBar("http://a.com/bar");
+
+  NavigateActiveAndCommit(kUrl);
+
+  controller().LoadURL(
+      kUrlBar, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
+  main_test_rfh()->PrepareForCommit();
+
+  FrameHostMsg_DidCommitProvisionalLoad_Params params;
+  params.page_id = 0;
+  params.nav_entry_id = 0;
+  params.did_create_new_entry = false;
+  params.transition = ui::PAGE_TRANSITION_LINK;
+  params.should_update_history = false;
+  params.gesture = NavigationGestureAuto;
+  params.was_within_same_page = false;
+  params.is_post = false;
+  params.page_state = PageState::CreateFromURL(kUrlBar);
+
+  struct TestCase {
+    const char* const url;
+    const char* const origin;
+    bool mismatch;
+  } cases[] = {
+    // Positive case where the two match.
+    { "http://a.com/foo.html", "http://a.com", false },
+
+    // Host mismatches.
+    { "http://a.com/", "http://b.com", true },
+    { "http://b.com/", "http://a.com", true },
+
+    // Scheme mismatches.
+    { "file://", "http://a.com", true },
+    { "https://a.com/", "http://a.com", true },
+
+    // about:blank URLs inherit the origin of the context that navigated them.
+    { "about:blank", "http://a.com", false },
+
+    // Unique origin.
+    { "http://a.com", "null", false },
+  };
+
+  for (const auto& test_case : cases) {
+    params.url = GURL(test_case.url);
+    params.origin = url::Origin(GURL(test_case.origin));
+
+    int expected_bad_msg_count = process()->bad_msg_count();
+    if (test_case.mismatch)
+      expected_bad_msg_count++;
+
+    main_test_rfh()->SendNavigateWithParams(&params);
+
+    EXPECT_EQ(expected_bad_msg_count, process()->bad_msg_count())
+      << " url:" << test_case.url
+      << " origin:" << test_case.origin
+      << " mismatch:" << test_case.mismatch;
+  }
+}
+
 // RenderFrameHostManagerTest extension for PlzNavigate enabled tests.
 class RenderFrameHostManagerTestWithBrowserSideNavigation
     : public RenderFrameHostManagerTest {
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 9bcbdd2..760a379 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -456,11 +456,6 @@
   if (g_gpu_process_hosts[kind_] == this)
     g_gpu_process_hosts[kind_] = NULL;
 
-  // If there are any remaining offscreen contexts at the point the
-  // GPU process exits, assume something went wrong, and block their
-  // URLs from accessing client 3D APIs without prompting.
-  BlockLiveOffscreenContexts();
-
   UMA_HISTOGRAM_COUNTS_100("GPU.AtExitSurfaceCount",
                            GpuSurfaceTracker::Get()->GetSurfaceCount());
   UMA_HISTOGRAM_BOOLEAN("GPU.AtExitReceivedMemoryStats",
@@ -478,6 +473,7 @@
   }
 
   std::string message;
+  bool block_offscreen_contexts = true;
   if (!in_process_) {
     int exit_code;
     base::TerminationStatus status = process_->GetTerminationStatus(
@@ -495,6 +491,10 @@
 
     switch (status) {
       case base::TERMINATION_STATUS_NORMAL_TERMINATION:
+        // Don't block offscreen contexts (and force page reload for webgl)
+        // if this was an intentional shutdown or the OOM killer on Android
+        // killed us while Chrome was in the background.
+        block_offscreen_contexts = false;
         message = "The GPU process exited normally. Everything is okay.";
         break;
       case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
@@ -521,6 +521,12 @@
     }
   }
 
+  // If there are any remaining offscreen contexts at the point the
+  // GPU process exits, assume something went wrong, and block their
+  // URLs from accessing client 3D APIs without prompting.
+  if (block_offscreen_contexts)
+    BlockLiveOffscreenContexts();
+
   BrowserThread::PostTask(BrowserThread::UI,
                           FROM_HERE,
                           base::Bind(&GpuProcessHostUIShim::Destroy,
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index cfca4f8..71ad4e1c 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -23,6 +23,7 @@
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/indexed_db/indexed_db_blob_info.h"
 #include "content/browser/indexed_db/indexed_db_class_factory.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
 #include "content/browser/indexed_db/indexed_db_database_error.h"
 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
 #include "content/browser/indexed_db/indexed_db_metadata.h"
@@ -89,20 +90,8 @@
   return storage::GetIdentifierFromOrigin(origin_url) + "@1";
 }
 
-static base::FilePath ComputeFileName(const GURL& origin_url) {
-  return base::FilePath()
-      .AppendASCII(storage::GetIdentifierFromOrigin(origin_url))
-      .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb"));
-}
-
-static base::FilePath ComputeBlobPath(const GURL& origin_url) {
-  return base::FilePath()
-      .AppendASCII(storage::GetIdentifierFromOrigin(origin_url))
-      .AddExtension(FILE_PATH_LITERAL(".indexeddb.blob"));
-}
-
-static base::FilePath ComputeCorruptionFileName(const GURL& origin_url) {
-  return ComputeFileName(origin_url)
+static FilePath ComputeCorruptionFileName(const GURL& origin_url) {
+  return IndexedDBContextImpl::GetLevelDBFileName(origin_url)
       .Append(FILE_PATH_LITERAL("corruption_info.json"));
 }
 
@@ -910,7 +899,7 @@
     const base::FilePath& path_base,
     const GURL& origin_url) {
   const base::FilePath file_path =
-      path_base.Append(ComputeFileName(origin_url));
+      path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin_url));
   DefaultLevelDBFactory leveldb_factory;
   return leveldb_factory.DestroyLevelDB(file_path);
 }
@@ -1014,10 +1003,10 @@
     return scoped_refptr<IndexedDBBackingStore>();
   }
 
-  const base::FilePath file_path =
-      path_base.Append(ComputeFileName(origin_url));
-  const base::FilePath blob_path =
-      path_base.Append(ComputeBlobPath(origin_url));
+  const FilePath file_path =
+      path_base.Append(IndexedDBContextImpl::GetLevelDBFileName(origin_url));
+  const FilePath blob_path =
+      path_base.Append(IndexedDBContextImpl::GetBlobStoreFileName(origin_url));
 
   if (IsPathTooLong(file_path)) {
     *status = leveldb::Status::IOError("File path too long");
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index 28843d6..cbe6016 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -281,9 +281,8 @@
 int IndexedDBContextImpl::GetOriginBlobFileCount(const GURL& origin_url) {
   DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
   int count = 0;
-  base::FileEnumerator file_enumerator(
-      GetBlobPath(storage::GetIdentifierFromOrigin(origin_url)), true,
-      base::FileEnumerator::FILES);
+  base::FileEnumerator file_enumerator(GetBlobStorePath(origin_url), true,
+                                       base::FileEnumerator::FILES);
   for (base::FilePath file_path = file_enumerator.Next(); !file_path.empty();
        file_path = file_enumerator.Next()) {
     count++;
@@ -329,8 +328,7 @@
     const bool kNonRecursive = false;
     base::DeleteFile(idb_directory, kNonRecursive);
   }
-  base::DeleteFile(GetBlobPath(storage::GetIdentifierFromOrigin(origin_url)),
-                   true /* recursive */);
+  base::DeleteFile(GetBlobStorePath(origin_url), true /* recursive */);
   QueryDiskAndUpdateQuotaUsage(origin_url);
   if (s.ok()) {
     RemoveFromOriginSet(origin_url);
@@ -349,7 +347,6 @@
       static_cast<IndexedDBContextImpl*>(dest_context);
 
   ForceClose(origin_url, FORCE_CLOSE_COPY_ORIGIN);
-  std::string origin_id = storage::GetIdentifierFromOrigin(origin_url);
 
   // Make sure we're not about to delete our own database.
   CHECK_NE(dest_context_impl->data_path().value(), data_path().value());
@@ -397,24 +394,17 @@
   return factory_->GetConnectionCount(origin_url);
 }
 
-base::FilePath IndexedDBContextImpl::GetLevelDBPath(
-    const GURL& origin_url) const {
-  std::string origin_id = storage::GetIdentifierFromOrigin(origin_url);
-  return GetLevelDBPath(origin_id);
-}
-
 std::vector<base::FilePath> IndexedDBContextImpl::GetStoragePaths(
     const GURL& origin_url) const {
-  std::string origin_id = storage::GetIdentifierFromOrigin(origin_url);
   std::vector<base::FilePath> paths;
-  paths.push_back(GetLevelDBPath(origin_id));
-  paths.push_back(GetBlobPath(origin_id));
+  paths.push_back(GetLevelDBPath(origin_url));
+  paths.push_back(GetBlobStorePath(origin_url));
   return paths;
 }
 
 base::FilePath IndexedDBContextImpl::GetFilePathForTesting(
-    const std::string& origin_id) const {
-  return GetLevelDBPath(origin_id);
+    const GURL& origin_url) const {
+  return GetLevelDBPath(origin_url);
 }
 
 void IndexedDBContextImpl::SetTaskRunnerForTesting(
@@ -484,20 +474,38 @@
           &ClearSessionOnlyOrigins, data_path_, special_storage_policy_));
 }
 
-base::FilePath IndexedDBContextImpl::GetBlobPath(
-    const std::string& origin_id) const {
-  DCHECK(!data_path_.empty());
-  return data_path_.AppendASCII(origin_id).AddExtension(kIndexedDBExtension)
+// static
+base::FilePath IndexedDBContextImpl::GetBlobStoreFileName(
+    const GURL& origin_url) {
+  std::string origin_id = storage::GetIdentifierFromOrigin(origin_url);
+  return base::FilePath()
+      .AppendASCII(origin_id)
+      .AddExtension(kIndexedDBExtension)
       .AddExtension(kBlobExtension);
 }
 
-base::FilePath IndexedDBContextImpl::GetLevelDBPath(
-    const std::string& origin_id) const {
-  DCHECK(!data_path_.empty());
-  return data_path_.AppendASCII(origin_id).AddExtension(kIndexedDBExtension)
+// static
+base::FilePath IndexedDBContextImpl::GetLevelDBFileName(
+    const GURL& origin_url) {
+  std::string origin_id = storage::GetIdentifierFromOrigin(origin_url);
+  return base::FilePath()
+      .AppendASCII(origin_id)
+      .AddExtension(kIndexedDBExtension)
       .AddExtension(kLevelDBExtension);
 }
 
+base::FilePath IndexedDBContextImpl::GetBlobStorePath(
+    const GURL& origin_url) const {
+  DCHECK(!data_path_.empty());
+  return data_path_.Append(GetBlobStoreFileName(origin_url));
+}
+
+base::FilePath IndexedDBContextImpl::GetLevelDBPath(
+    const GURL& origin_url) const {
+  DCHECK(!data_path_.empty());
+  return data_path_.Append(GetLevelDBFileName(origin_url));
+}
+
 int64_t IndexedDBContextImpl::ReadUsageFromDisk(const GURL& origin_url) const {
   if (data_path_.empty())
     return 0;
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index 9967d2c3..608e0f2 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -74,8 +74,7 @@
   void DeleteForOrigin(const GURL& origin_url) override;
   void CopyOriginData(const GURL& origin_url,
                       IndexedDBContext* dest_context) override;
-  base::FilePath GetFilePathForTesting(
-      const std::string& origin_id) const override;
+  base::FilePath GetFilePathForTesting(const GURL& origin_url) const override;
   void SetTaskRunnerForTesting(base::SequencedTaskRunner* task_runner) override;
 
   // Methods called by IndexedDBDispatcherHost for quota support.
@@ -84,6 +83,9 @@
   void TransactionComplete(const GURL& origin_url);
   void DatabaseDeleted(const GURL& origin_url);
 
+  static base::FilePath GetBlobStoreFileName(const GURL& origin_url);
+  static base::FilePath GetLevelDBFileName(const GURL& origin_url);
+
   // Will be null in unit tests.
   storage::QuotaManagerProxy* quota_manager_proxy() const {
     return quota_manager_proxy_.get();
@@ -127,9 +129,9 @@
   typedef std::map<GURL, int64_t> OriginToSizeMap;
   class IndexedDBGetUsageAndQuotaCallback;
 
-  base::FilePath GetBlobPath(const std::string& origin_id) const;
+  base::FilePath GetBlobStorePath(const GURL& origin_url) const;
   base::FilePath GetLevelDBPath(const GURL& origin_url) const;
-  base::FilePath GetLevelDBPath(const std::string& origin_id) const;
+
   int64_t ReadUsageFromDisk(const GURL& origin_url) const;
   void EnsureDiskUsageCacheInitialized(const GURL& origin_url);
   void QueryDiskAndUpdateQuotaUsage(const GURL& origin_url);
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc
index 2261dcc..33db01f 100644
--- a/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -17,7 +17,6 @@
 #include "content/browser/indexed_db/indexed_db_database_error.h"
 #include "content/browser/indexed_db/indexed_db_tracing.h"
 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h"
-#include "storage/common/database/database_identifier.h"
 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h"
 #include "third_party/leveldatabase/env_chromium.h"
 
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc
index 946799a..b61e66c 100644
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -18,7 +18,6 @@
 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h"
 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
 #include "content/browser/quota/mock_quota_manager_proxy.h"
-#include "storage/common/database/database_identifier.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h"
 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h"
diff --git a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
index 31a41369..a626dc0 100644
--- a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -20,7 +20,6 @@
 #include "content/public/browser/storage_partition.h"
 #include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
-#include "storage/common/database/database_identifier.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 // Declared to shorten the line lengths.
@@ -139,8 +138,8 @@
   }
 
   void AddFakeIndexedDB(const GURL& origin, int size) {
-    base::FilePath file_path_origin = idb_context()->GetFilePathForTesting(
-        storage::GetIdentifierFromOrigin(origin));
+    base::FilePath file_path_origin =
+        idb_context()->GetFilePathForTesting(origin);
     if (!base::CreateDirectory(file_path_origin)) {
       LOG(ERROR) << "failed to base::CreateDirectory "
                  << file_path_origin.value();
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc
index 9ed1e738..7b057d5 100644
--- a/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -23,7 +23,6 @@
 #include "content/public/test/test_browser_context.h"
 #include "storage/browser/quota/quota_manager.h"
 #include "storage/browser/quota/special_storage_policy.h"
-#include "storage/common/database/database_identifier.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
@@ -78,10 +77,8 @@
                                  quota_manager_proxy_.get(),
                                  task_runner_.get());
 
-    normal_path = idb_context->GetFilePathForTesting(
-        storage::GetIdentifierFromOrigin(kNormalOrigin));
-    session_only_path = idb_context->GetFilePathForTesting(
-        storage::GetIdentifierFromOrigin(kSessionOnlyOrigin));
+    normal_path = idb_context->GetFilePathForTesting(kNormalOrigin);
+    session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin);
     ASSERT_TRUE(base::CreateDirectory(normal_path));
     ASSERT_TRUE(base::CreateDirectory(session_only_path));
     FlushIndexedDBTaskRunner();
@@ -116,10 +113,8 @@
     // Save session state. This should bypass the destruction-time deletion.
     idb_context->SetForceKeepSessionState();
 
-    normal_path = idb_context->GetFilePathForTesting(
-        storage::GetIdentifierFromOrigin(kNormalOrigin));
-    session_only_path = idb_context->GetFilePathForTesting(
-        storage::GetIdentifierFromOrigin(kSessionOnlyOrigin));
+    normal_path = idb_context->GetFilePathForTesting(kNormalOrigin);
+    session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin);
     ASSERT_TRUE(base::CreateDirectory(normal_path));
     ASSERT_TRUE(base::CreateDirectory(session_only_path));
     message_loop_.RunUntilIdle();
@@ -192,8 +187,7 @@
 
     IndexedDBFactory* factory = idb_context->GetIDBFactory();
 
-    test_path = idb_context->GetFilePathForTesting(
-        storage::GetIdentifierFromOrigin(kTestOrigin));
+    test_path = idb_context->GetFilePathForTesting(kTestOrigin);
 
     IndexedDBPendingConnection open_connection(open_callbacks,
                                                open_db_callbacks,
@@ -243,8 +237,7 @@
       temp_dir.path(), special_storage_policy_.get(),
       quota_manager_proxy_.get(), task_runner_.get());
 
-  base::FilePath test_path = idb_context->GetFilePathForTesting(
-      storage::GetIdentifierFromOrigin(kTestOrigin));
+  base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin);
   ASSERT_TRUE(base::CreateDirectory(test_path));
 
   scoped_ptr<LevelDBLock> lock =
diff --git a/content/browser/mach_broker_mac.h b/content/browser/mach_broker_mac.h
index 32199c6..32ff5d6e 100644
--- a/content/browser/mach_broker_mac.h
+++ b/content/browser/mach_broker_mac.h
@@ -24,7 +24,8 @@
 // access to mach task ports for content child processes.
 class CONTENT_EXPORT MachBroker : public base::PortProvider,
                                   public BrowserChildProcessObserver,
-                                  public NotificationObserver {
+                                  public NotificationObserver,
+                                  public base::PortProvider::Observer {
  public:
   // For use in child processes. This will send the task port of the current
   // process over Mach IPC to the port registered by name (via this class) in
@@ -74,6 +75,9 @@
   MachBroker();
   ~MachBroker() override;
 
+  // Implement |base::PortProvider::Observer|.
+  void OnReceivedTaskPort(base::ProcessHandle process) override;
+
   // Removes all mappings belonging to |child_process_id| from the broker.
   void InvalidateChildProcessId(int child_process_id);
 
diff --git a/content/browser/mach_broker_mac.mm b/content/browser/mach_broker_mac.mm
index 57237aa..dfbf71f 100644
--- a/content/browser/mach_broker_mac.mm
+++ b/content/browser/mach_broker_mac.mm
@@ -99,9 +99,17 @@
   return base::MachPortBroker::GetMachPortName(kBootstrapName, is_child);
 }
 
-MachBroker::MachBroker() : initialized_(false), broker_(kBootstrapName) {}
+MachBroker::MachBroker() : initialized_(false), broker_(kBootstrapName) {
+  broker_.AddObserver(this);
+}
 
-MachBroker::~MachBroker() {}
+MachBroker::~MachBroker() {
+  broker_.RemoveObserver(this);
+}
+
+void MachBroker::OnReceivedTaskPort(base::ProcessHandle process) {
+  NotifyObservers(process);
+}
 
 void MachBroker::InvalidateChildProcessId(int child_process_id) {
   base::AutoLock lock(GetLock());
diff --git a/content/browser/mach_broker_mac_unittest.cc b/content/browser/mach_broker_mac_unittest.cc
index 21a4c4d..65eaa91 100644
--- a/content/browser/mach_broker_mac_unittest.cc
+++ b/content/browser/mach_broker_mac_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
 #include "base/test/multiprocess_test.h"
 #include "base/test/test_timeouts.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -14,8 +15,17 @@
 
 namespace content {
 
-class MachBrokerTest : public testing::Test {
+class MachBrokerTest : public testing::Test,
+                       public base::PortProvider::Observer {
  public:
+  MachBrokerTest()
+      : event_(true, false), received_process_(base::kNullProcessHandle) {
+    broker_.AddObserver(this);
+  }
+  ~MachBrokerTest() override {
+    broker_.RemoveObserver(this);
+  }
+
   // Helper function to acquire/release locks and call |PlaceholderForPid()|.
   void AddPlaceholderForPid(base::ProcessHandle pid, int child_process_id) {
     base::AutoLock lock(broker_.GetLock());
@@ -47,8 +57,20 @@
     EXPECT_EQ(0, rv);
   }
 
+  void WaitForTaskPort() {
+    event_.Wait();
+  }
+
+  // base::PortProvider::Observer:
+  void OnReceivedTaskPort(base::ProcessHandle process) override {
+    received_process_ = process;
+    event_.Signal();
+  }
+
  protected:
   MachBroker broker_;
+  base::WaitableEvent event_;
+  base::ProcessHandle received_process_;
   TestBrowserThreadBundle thread_bundle_;
 };
 
@@ -68,6 +90,8 @@
     broker_.EnsureRunning();
   }
   base::Process child_process = LaunchTestChild("MachBrokerTestChild", 7);
+  WaitForTaskPort();
+  EXPECT_EQ(child_process.Handle(), received_process_);
   WaitForChildExit(child_process);
 
   EXPECT_NE(static_cast<mach_port_t>(MACH_PORT_NULL),
diff --git a/content/browser/media/midi_host.cc b/content/browser/media/midi_host.cc
index d335364..17dcccc 100644
--- a/content/browser/media/midi_host.cc
+++ b/content/browser/media/midi_host.cc
@@ -251,7 +251,7 @@
       if (data[i] == kEndOfSysExByte) {
         in_sysex = false;
         UMA_HISTOGRAM_COUNTS("Media.Midi.SysExMessageSizeUpTo1MB",
-                             sysex_start_offset - i + 1);
+                             i - sysex_start_offset + 1);
       } else if (!IsDataByte(current)) {
         return false;  // Error: |current| should have been data byte.
       }
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 38a6983..840afac 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -29,6 +29,7 @@
 #include "cc/base/switches.h"
 #include "cc/input/input_handler.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/output/compositor_frame.h"
 #include "cc/output/context_provider.h"
 #include "cc/output/output_surface.h"
@@ -221,16 +222,6 @@
 }
 
 // static
-const cc::LayerSettings& Compositor::LayerSettings() {
-  return ui::WindowAndroidCompositor::LayerSettings();
-}
-
-// static
-void Compositor::SetLayerSettings(const cc::LayerSettings& settings) {
-  ui::WindowAndroidCompositor::SetLayerSettings(settings);
-}
-
-// static
 bool CompositorImpl::IsInitialized() {
   return g_initialized;
 }
@@ -252,7 +243,7 @@
 
 CompositorImpl::CompositorImpl(CompositorClient* client,
                                gfx::NativeWindow root_window)
-    : root_layer_(cc::Layer::Create(Compositor::LayerSettings())),
+    : root_layer_(cc::Layer::Create(cc::LayerSettings())),
       resource_manager_(root_window),
       surface_id_allocator_(CreateSurfaceIdAllocator()),
       has_transparent_background_(false),
@@ -355,9 +346,6 @@
       command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
   settings.single_thread_proxy_scheduler = true;
 
-  settings.use_compositor_animation_timelines = !command_line->HasSwitch(
-      switches::kDisableAndroidCompositorAnimationTimelines);
-
   cc::LayerTreeHost::InitParams params;
   params.client = this;
   params.shared_bitmap_manager = HostSharedBitmapManager::current();
diff --git a/content/browser/renderer_host/ime_adapter_android.cc b/content/browser/renderer_host/ime_adapter_android.cc
index c1429755..95c1241 100644
--- a/content/browser/renderer_host/ime_adapter_android.cc
+++ b/content/browser/renderer_host/ime_adapter_android.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/feature_list.h"
@@ -266,6 +267,31 @@
                                                      start, end));
 }
 
+void ImeAdapterAndroid::SetCharacterBounds(
+    const std::vector<gfx::RectF>& character_bounds) {
+  JNIEnv* env = AttachCurrentThread();
+  base::android::ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env);
+  if (obj.is_null())
+    return;
+
+  const size_t coordinates_array_size = character_bounds.size() * 4;
+  scoped_ptr<float[]> coordinates_array(new float[coordinates_array_size]);
+  for (size_t i = 0; i < character_bounds.size(); ++i) {
+    const gfx::RectF& rect = character_bounds[i];
+    const size_t coordinates_array_index = i * 4;
+    coordinates_array[coordinates_array_index + 0] = rect.x();
+    coordinates_array[coordinates_array_index + 1] = rect.y();
+    coordinates_array[coordinates_array_index + 2] = rect.right();
+    coordinates_array[coordinates_array_index + 3] = rect.bottom();
+  }
+  Java_ImeAdapter_setCharacterBounds(
+      env,
+      obj.obj(),
+      base::android::ToJavaFloatArray(env,
+                                      coordinates_array.get(),
+                                      coordinates_array_size).obj());
+}
+
 void ImeAdapterAndroid::SetComposingRegion(JNIEnv*,
                                            const JavaParamRef<jobject>&,
                                            int start,
diff --git a/content/browser/renderer_host/ime_adapter_android.h b/content/browser/renderer_host/ime_adapter_android.h
index 9e60700..1f559c6 100644
--- a/content/browser/renderer_host/ime_adapter_android.h
+++ b/content/browser/renderer_host/ime_adapter_android.h
@@ -7,7 +7,10 @@
 
 #include <jni.h>
 
+#include <vector>
+
 #include "base/android/jni_weak_ref.h"
+#include "ui/gfx/geometry/rect_f.h"
 
 namespace content {
 
@@ -82,6 +85,7 @@
   // Called from native -> java
   void CancelComposition();
   void FocusedNodeChanged(bool is_editable_node);
+  void SetCharacterBounds(const std::vector<gfx::RectF>& rects);
 
  private:
   RenderWidgetHostImpl* GetRenderWidgetHostImpl();
diff --git a/content/browser/renderer_host/input/web_input_event_builders_mac.mm b/content/browser/renderer_host/input/web_input_event_builders_mac.mm
index 82386ed..2e8ea376b 100644
--- a/content/browser/renderer_host/input/web_input_event_builders_mac.mm
+++ b/content/browser/renderer_host/input/web_input_event_builders_mac.mm
@@ -39,6 +39,7 @@
 #include "base/strings/string_util.h"
 #include "content/browser/renderer_host/input/web_input_event_util.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/events/keycodes/keyboard_code_conversion.h"
 #include "ui/events/keycodes/keyboard_code_conversion_mac.h"
 
@@ -516,9 +517,8 @@
 void SetWebEventLocationFromEventInView(blink::WebMouseEvent* result,
                                         NSEvent* event,
                                         NSView* view) {
-  NSPoint window_local = [event locationInWindow];
-
-  NSPoint screen_local = [[view window] convertBaseToScreen:window_local];
+  NSPoint screen_local = ui::ConvertPointFromWindowToScreen(
+      [view window], [event locationInWindow]);
   result->globalX = screen_local.x;
   // Flip y.
   NSScreen* primary_screen = ([[NSScreen screens] count] > 0)
@@ -529,7 +529,8 @@
   else
     result->globalY = screen_local.y;
 
-  NSPoint content_local = [view convertPoint:window_local fromView:nil];
+  NSPoint content_local =
+      [view convertPoint:[event locationInWindow] fromView:nil];
   result->x = content_local.x;
   result->y = [view frame].size.height - content_local.y;  // Flip y.
 
diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
index e92e08c..26cbb00 100644
--- a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
+++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -95,7 +95,7 @@
     DCHECK(!addresses_.empty());
     for (net::AddressList::iterator iter = addresses_.begin();
          iter != addresses_.end(); ++iter) {
-      list.push_back(iter->address().bytes());
+      list.push_back(iter->address());
     }
     done_callback_.Run(list);
   }
diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.h b/content/browser/renderer_host/p2p/socket_dispatcher_host.h
index d783e1f..4615d2e 100644
--- a/content/browser/renderer_host/p2p/socket_dispatcher_host.h
+++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.h
@@ -18,6 +18,7 @@
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_process_host.h"
+#include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/network_change_notifier.h"
 
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 3bab60f..ffa20688 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -170,8 +170,6 @@
 #include "net/url_request/url_request_context_getter.h"
 #include "ppapi/shared_impl/ppapi_switches.h"
 #include "storage/browser/fileapi/sandbox_file_system_backend.h"
-#include "third_party/icu/source/common/unicode/unistr.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/events/event_switches.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index df811e6..ff0a359 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -19,6 +19,7 @@
 #include "base/sys_info.h"
 #include "base/threading/worker_pool.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/surface_layer.h"
 #include "cc/output/compositor_frame.h"
 #include "cc/output/compositor_frame_ack.h"
@@ -445,7 +446,7 @@
   DCHECK(manager);
   // manager must outlive compositors using it.
   scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create(
-      Compositor::LayerSettings(),
+      cc::LayerSettings(),
       base::Bind(&SatisfyCallback, base::Unretained(manager)),
       base::Bind(&RequireCallback, base::Unretained(manager)));
   surface_layer->SetSurfaceId(surface_id_, 1.f, texture_size_in_layer_);
@@ -789,7 +790,11 @@
 void RenderWidgetHostViewAndroid::ImeCompositionRangeChanged(
     const gfx::Range& range,
     const std::vector<gfx::Rect>& character_bounds) {
-  // TODO(yukawa): Implement this.
+  std::vector<gfx::RectF> character_bounds_float;
+  for (const gfx::Rect& rect : character_bounds) {
+    character_bounds_float.emplace_back(rect);
+  }
+  ime_adapter_android_.SetCharacterBounds(character_bounds_float);
 }
 
 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
@@ -1308,7 +1313,8 @@
       frame_metadata.scrollable_viewport_size,
       frame_metadata.location_bar_offset,
       frame_metadata.location_bar_content_translation,
-      is_mobile_optimized);
+      is_mobile_optimized,
+      frame_metadata.selection.start);
 #if defined(VIDEO_HOLE)
   if (host_) {
     WebContents* web_contents =
@@ -1712,6 +1718,9 @@
 
 void RenderWidgetHostViewAndroid::DidOverscroll(
     const DidOverscrollParams& params) {
+  if (sync_compositor_)
+    sync_compositor_->DidOverscroll(params);
+
   if (!content_view_core_ || !layer_.get() || !is_showing_)
     return;
 
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 1675b98..96e472e3 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -71,6 +71,7 @@
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #import "third_party/mozilla/ComplexTextInputPanel.h"
 #include "ui/base/cocoa/animation_utils.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/cocoa/fullscreen_window_manager.h"
 #import "ui/base/cocoa/underlay_opengl_hosting_window.h"
 #include "ui/base/layout.h"
@@ -1001,7 +1002,7 @@
     return gfx::Rect(gfx::Size(NSWidth(bounds), NSHeight(bounds)));
 
   bounds = [cocoa_view_ convertRect:bounds toView:nil];
-  bounds.origin = [enclosing_window convertBaseToScreen:bounds.origin];
+  bounds = [enclosing_window convertRectToScreen:bounds];
   return FlipNSRectToRectScreen(bounds);
 }
 
@@ -1716,7 +1717,7 @@
   origin.y = NSHeight([cocoa_view_ bounds]) - origin.y;
   NSPoint originInWindow = [cocoa_view_ convertPoint:origin toView:nil];
   NSPoint originInScreen =
-      [[cocoa_view_ window] convertBaseToScreen:originInWindow];
+      ui::ConvertPointFromWindowToScreen([cocoa_view_ window], originInWindow);
   originInScreen.y = originInScreen.y - size.height;
   return gfx::Point(originInScreen.x, originInScreen.y);
 }
@@ -2846,7 +2847,8 @@
           ->GetRootBrowserAccessibilityManager();
   if (!manager)
     return self;
-  NSPoint pointInWindow = [[self window] convertScreenToBase:point];
+  NSPoint pointInWindow =
+      ui::ConvertPointFromScreenToWindow([self window], point);
   NSPoint localPoint = [self convertPoint:pointInWindow fromView:nil];
   localPoint.y = NSHeight([self bounds]) - localPoint.y;
   BrowserAccessibilityCocoa* root =
@@ -2970,7 +2972,7 @@
   // |thePoint| is in screen coordinates, but needs to be converted to WebKit
   // coordinates (upper left origin). Scroll offsets will be taken care of in
   // the renderer.
-  thePoint = [[self window] convertScreenToBase:thePoint];
+  thePoint = ui::ConvertPointFromScreenToWindow([self window], thePoint);
   thePoint = [self convertPoint:thePoint fromView:nil];
   thePoint.y = NSHeight([self frame]) - thePoint.y;
 
@@ -3017,7 +3019,7 @@
 
   // Convert into screen coordinates for return.
   rect = [self convertRect:rect toView:nil];
-  rect.origin = [[self window] convertBaseToScreen:rect.origin];
+  rect = [[self window] convertRectToScreen:rect];
   return rect;
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index e7a7ace..74cc69a 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -728,17 +728,22 @@
 // firstRectForCharacterRange:actualRange] are handled in a sane manner if they
 // arrive after the C++ RenderWidgetHostView is destroyed.
 TEST_F(RenderWidgetHostViewMacTest, CompositionEventAfterDestroy) {
-  // The test view isn't in an NSWindow to perform the final coordinate
-  // conversion, so use an origin of 0,0, but verify the size.
   const gfx::Rect composition_bounds(0, 0, 30, 40);
   const gfx::Range range(0, 1);
   rwhv_mac_->ImeCompositionRangeChanged(
       range, std::vector<gfx::Rect>(1, composition_bounds));
 
   NSRange actual_range = NSMakeRange(0, 0);
+
+  base::scoped_nsobject<CocoaTestHelperWindow> window(
+      [[CocoaTestHelperWindow alloc] init]);
+  [[window contentView] addSubview:rwhv_cocoa_];
+  [rwhv_cocoa_ setFrame:NSMakeRect(0, 0, 400, 400)];
+
   NSRect rect = [rwhv_cocoa_ firstRectForCharacterRange:range.ToNSRange()
                                             actualRange:&actual_range];
-  EXPECT_NSEQ(NSMakeRect(0, 0, 30, 40), rect);
+  EXPECT_EQ(30, rect.size.width);
+  EXPECT_EQ(40, rect.size.height);
   EXPECT_EQ(range, gfx::Range(actual_range));
 
   DestroyHostViewRetainCocoaView();
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index a2ca928..6adbafe 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -34,6 +34,7 @@
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
 #include "content/test/test_content_browser_client.h"
 #include "ipc/ipc_security_test_util.h"
 #include "net/dns/mock_host_resolver.h"
@@ -499,4 +500,60 @@
   TryCreateDuplicateRequestIds(shell(), true);
 }
 
+// Test that receiving a commit with incorrect origin properly terminates the
+// renderer process.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MismatchedOriginOnCommit) {
+  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), start_url));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+
+  // Setup an URL which will never commit, allowing this test to send its own,
+  // malformed, commit message.
+  GURL url(embedded_test_server()->GetURL("/title2.html"));
+  NavigationStallDelegate stall_delegate(url);
+  ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+
+  // Use LoadURL, as the test shouldn't wait for navigation commit.
+  NavigationController& controller = shell()->web_contents()->GetController();
+  controller.LoadURL(url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
+  EXPECT_NE(nullptr, controller.GetPendingEntry());
+  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
+
+  RenderProcessHostWatcher exit_observer(
+      root->current_frame_host()->GetProcess(),
+      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+
+  // Create commit params with different origins in params.url and
+  // params.origin.
+  FrameHostMsg_DidCommitProvisionalLoad_Params params;
+  params.page_id = 0;
+  params.nav_entry_id = 0;
+  params.did_create_new_entry = false;
+  params.url = url;
+  params.transition = ui::PAGE_TRANSITION_LINK;
+  params.should_update_history = false;
+  params.gesture = NavigationGestureAuto;
+  params.was_within_same_page = false;
+  params.is_post = false;
+  params.page_state = PageState::CreateFromURL(url);
+  params.origin = url::Origin(GURL("http://bar.com/"));
+
+  FrameHostMsg_DidCommitProvisionalLoad msg(
+      root->current_frame_host()->routing_id(), params);
+  IPC::IpcSecurityTestUtil::PwnMessageReceived(
+      root->current_frame_host()->GetProcess()->GetChannel(), msg);
+
+  // When the IPC message is received and validation fails, the process is
+  // terminated. However, the notification for that should be processed in a
+  // separate task of the message loop, so ensure that the process is still
+  // considered alive.
+  EXPECT_TRUE(root->current_frame_host()->GetProcess()->HasConnection());
+
+  exit_observer.Wait();
+  EXPECT_FALSE(exit_observer.did_exit_normally());
+}
+
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index 7a6c482..6f756817 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -676,7 +676,9 @@
 
 void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
     int handle_id,
+    int provider_id,
     const base::string16& message,
+    const url::Origin& source_origin,
     const std::vector<TransferredMessagePort>& sent_message_ports) {
   TRACE_EVENT0("ServiceWorker",
                "ServiceWorkerDispatcherHost::OnPostMessageToWorker");
@@ -689,8 +691,15 @@
     return;
   }
 
+  ServiceWorkerProviderHost* sender_provider_host =
+      GetContext()->GetProviderHost(render_process_id_, provider_id);
+  if (!sender_provider_host) {
+    bad_message::ReceivedBadMessage(this, bad_message::SWDH_POST_MESSAGE);
+    return;
+  }
+
   handle->version()->DispatchExtendableMessageEvent(
-      message, sent_message_ports,
+      sender_provider_host, message, source_origin, sent_message_ports,
       base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
 }
 
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h
index e44b5ff..b5b1d06d1 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -21,6 +21,10 @@
 class GURL;
 struct EmbeddedWorkerHostMsg_ReportConsoleMessage_Params;
 
+namespace url {
+class Origin;
+}
+
 namespace content {
 
 class MessagePortMessageFilter;
@@ -136,7 +140,9 @@
   void OnDecrementRegistrationRefCount(int registration_handle_id);
   void OnPostMessageToWorker(
       int handle_id,
+      int provider_id,
       const base::string16& message,
+      const url::Origin& source_origin,
       const std::vector<TransferredMessagePort>& sent_message_ports);
 
   // TODO(nhiroki): Remove this after ExtendableMessageEvent is enabled by
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 229a7d3..7369578 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -526,16 +526,46 @@
 }
 
 void ServiceWorkerVersion::DispatchExtendableMessageEvent(
+    ServiceWorkerProviderHost* sender_provider_host,
     const base::string16& message,
+    const url::Origin& source_origin,
     const std::vector<TransferredMessagePort>& sent_message_ports,
     const StatusCallback& callback) {
   for (const TransferredMessagePort& port : sent_message_ports)
     MessagePortService::GetInstance()->HoldMessages(port.id);
-  RunAfterStartWorker(
-      base::Bind(
-          &ServiceWorkerVersion::DispatchExtendableMessageEventAfterStartWorker,
-          weak_factory_.GetWeakPtr(), message, sent_message_ports, callback),
-      base::Bind(&RunErrorMessageCallback, sent_message_ports, callback));
+
+  switch (sender_provider_host->provider_type()) {
+    case SERVICE_WORKER_PROVIDER_FOR_WINDOW:
+    case SERVICE_WORKER_PROVIDER_FOR_WORKER:
+    case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER:
+      service_worker_client_utils::GetClient(
+          sender_provider_host,
+          base::Bind(
+              &ServiceWorkerVersion::DispatchExtendableMessageEventInternal<
+                  ServiceWorkerClientInfo>,
+              weak_factory_.GetWeakPtr(), message, source_origin,
+              sent_message_ports, callback));
+      break;
+    case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
+      // TODO(nhiroki): Decrement a reference to ServiceWorkerHandle if starting
+      // worker fails. Handles are managed by ServiceWorkerDispatcherHost, and
+      // we might need to make a new path to ask the dispatcher host to release
+      // the handle from ServiceWorkerVersion (http://crbug.com/543198).
+      RunSoon(base::Bind(
+          &ServiceWorkerVersion::DispatchExtendableMessageEventInternal<
+              ServiceWorkerObjectInfo>,
+          weak_factory_.GetWeakPtr(), message, source_origin,
+          sent_message_ports, callback,
+          sender_provider_host->GetOrCreateServiceWorkerHandle(
+              sender_provider_host->running_hosted_version())));
+      break;
+    case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME:
+    case SERVICE_WORKER_PROVIDER_UNKNOWN:
+      NOTREACHED() << sender_provider_host->provider_type();
+      RunSoon(base::Bind(&RunErrorMessageCallback, sent_message_ports, callback,
+                         SERVICE_WORKER_ERROR_FAILED));
+      break;
+  }
 }
 
 void ServiceWorkerVersion::DispatchMessageEvent(
@@ -908,9 +938,32 @@
   }
 }
 
+template <typename SourceInfo>
+void ServiceWorkerVersion::DispatchExtendableMessageEventInternal(
+    const base::string16& message,
+    const url::Origin& source_origin,
+    const std::vector<TransferredMessagePort>& sent_message_ports,
+    const StatusCallback& callback,
+    const SourceInfo& source_info) {
+  if (!source_info.IsValid()) {
+    RunErrorMessageCallback(sent_message_ports, callback,
+                            SERVICE_WORKER_ERROR_FAILED);
+    return;
+  }
+  RunAfterStartWorker(
+      base::Bind(
+          &ServiceWorkerVersion::DispatchExtendableMessageEventAfterStartWorker,
+          weak_factory_.GetWeakPtr(), message, source_origin,
+          sent_message_ports, ExtendableMessageEventSource(source_info),
+          callback),
+      base::Bind(&RunErrorMessageCallback, sent_message_ports, callback));
+}
+
 void ServiceWorkerVersion::DispatchExtendableMessageEventAfterStartWorker(
     const base::string16& message,
+    const url::Origin& source_origin,
     const std::vector<TransferredMessagePort>& sent_message_ports,
+    const ExtendableMessageEventSource& source,
     const StatusCallback& callback) {
   int request_id =
       StartRequest(ServiceWorkerMetrics::EventType::MESSAGE, callback);
@@ -920,10 +973,23 @@
   std::vector<int> new_routing_ids;
   filter->UpdateMessagePortsWithNewRoutes(sent_message_ports, &new_routing_ids);
 
+  ServiceWorkerMsg_ExtendableMessageEvent_Params params;
+  params.message = message;
+  params.source_origin = source_origin;
+  params.message_ports = sent_message_ports;
+  params.new_routing_ids = new_routing_ids;
+  params.source = source;
+
+  // Hide the client url if the client has a unique origin.
+  if (source_origin.unique()) {
+    if (params.source.client_info.IsValid())
+      params.source.client_info.url = GURL();
+    else
+      params.source.service_worker_info.url = GURL();
+  }
+
   DispatchSimpleEvent<ServiceWorkerHostMsg_ExtendableMessageEventFinished>(
-      request_id,
-      ServiceWorkerMsg_ExtendableMessageEvent(
-          request_id, message, sent_message_ports, new_routing_ids));
+      request_id, ServiceWorkerMsg_ExtendableMessageEvent(request_id, params));
 }
 
 void ServiceWorkerVersion::OnGetClient(int request_id,
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index cdc829b..e9e3cc96 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -255,7 +255,9 @@
   // of crbug.com/570820 after ExtendableMessageEvent is implemented
   // (crbug.com/543198).
   void DispatchExtendableMessageEvent(
+      ServiceWorkerProviderHost* sender_provider_host,
       const base::string16& message,
+      const url::Origin& source_origin,
       const std::vector<TransferredMessagePort>& sent_message_ports,
       const StatusCallback& callback);
 
@@ -516,9 +518,18 @@
 
   void OnStartSentAndScriptEvaluated(ServiceWorkerStatusCode status);
 
+  template <typename SourceInfo>
+  void DispatchExtendableMessageEventInternal(
+      const base::string16& message,
+      const url::Origin& source_origin,
+      const std::vector<TransferredMessagePort>& sent_message_ports,
+      const StatusCallback& callback,
+      const SourceInfo& source_info);
   void DispatchExtendableMessageEventAfterStartWorker(
       const base::string16& message,
+      const url::Origin& source_origin,
       const std::vector<TransferredMessagePort>& sent_message_ports,
+      const ExtendableMessageEventSource& source,
       const StatusCallback& callback);
 
   void DispatchMessageEventInternal(
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 5d079a5..da31574 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -118,13 +118,15 @@
 }
 
 void WebContentsViewMac::GetContainerBounds(gfx::Rect* out) const {
-  // Convert bounds to window coordinate space.
-  NSRect bounds =
-      [cocoa_view_.get() convertRect:[cocoa_view_.get() bounds] toView:nil];
-
-  // Convert bounds to screen coordinate space.
   NSWindow* window = [cocoa_view_.get() window];
-  bounds.origin = [window convertBaseToScreen:bounds.origin];
+  NSRect bounds = [cocoa_view_.get() bounds];
+  if (window)  {
+    // Convert bounds to window coordinate space.
+    bounds = [cocoa_view_.get() convertRect:bounds toView:nil];
+
+    // Convert bounds to screen coordinate space.
+    bounds = [window convertRectToScreen:bounds];
+  }
 
   // Flip y to account for screen flip.
   NSScreen* screen = [[NSScreen screens] firstObject];
diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm
index ec67412..452bfc8 100644
--- a/content/browser/web_contents/web_drag_dest_mac.mm
+++ b/content/browser/web_contents/web_drag_dest_mac.mm
@@ -15,6 +15,7 @@
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 #import "third_party/mozilla/NSPasteboard+Utils.h"
 #include "ui/base/clipboard/custom_data_helper.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #import "ui/base/dragdrop/cocoa_dnd_util.h"
 #include "ui/base/window_open_disposition.h"
 
@@ -98,7 +99,8 @@
 - (NSPoint)flipWindowPointToScreen:(const NSPoint&)windowPoint
                               view:(NSView*)view {
   DCHECK(view);
-  NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
+  NSPoint screenPoint =
+      ui::ConvertPointFromWindowToScreen([view window], windowPoint);
   NSScreen* screen = [[view window] screen];
   NSRect screenFrame = [screen frame];
   screenPoint.y = screenFrame.size.height - screenPoint.y;
diff --git a/content/browser/web_contents/web_drag_source_mac.mm b/content/browser/web_contents/web_drag_source_mac.mm
index a94f9d3..94ba599 100644
--- a/content/browser/web_contents/web_drag_source_mac.mm
+++ b/content/browser/web_contents/web_drag_source_mac.mm
@@ -30,6 +30,7 @@
 #include "net/base/filename_util.h"
 #include "net/base/mime_util.h"
 #include "ui/base/clipboard/custom_data_helper.h"
+#include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/dragdrop/cocoa_dnd_util.h"
 #include "ui/gfx/image/image.h"
 #include "ui/resources/grit/ui_resources.h"
@@ -222,7 +223,8 @@
 
 - (NSPoint)convertScreenPoint:(NSPoint)screenPoint {
   DCHECK([contentsView_ window]);
-  NSPoint basePoint = [[contentsView_ window] convertScreenToBase:screenPoint];
+  NSPoint basePoint =
+      ui::ConvertPointFromScreenToWindow([contentsView_ window], screenPoint);
   return [contentsView_ convertPoint:basePoint fromView:nil];
 }
 
diff --git a/content/child/browser_font_resource_trusted.cc b/content/child/browser_font_resource_trusted.cc
index 997d8d10..30bae9f 100644
--- a/content/child/browser_font_resource_trusted.cc
+++ b/content/child/browser_font_resource_trusted.cc
@@ -277,7 +277,7 @@
 
   // While converting the other way in PPFontDescToWebFontDesc we validated
   // that the enums can be casted.
-  WebFontDescription web_desc = font_->fontDescription();
+  WebFontDescription web_desc = font_->getFontDescription();
   description->face = StringVar::StringToPPVar(base::UTF16ToUTF8(
       base::StringPiece16(web_desc.family)));
   description->family =
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 5ea6c59..2e0dc0d 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -18,6 +18,7 @@
 #include "base/macros.h"
 #include "base/message_loop/timer_slack.h"
 #include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/process/process.h"
 #include "base/process/process_handle.h"
 #include "base/single_thread_task_runner.h"
@@ -27,6 +28,7 @@
 #include "base/synchronization/lock.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/threading/thread_local.h"
+#include "base/timer/elapsed_timer.h"
 #include "base/tracked_objects.h"
 #include "build/build_config.h"
 #include "components/tracing/child_trace_message_filter.h"
@@ -418,7 +420,10 @@
   if (!pipe_token.empty() && MojoShellConnectionImpl::Get()) {
     mojo::ScopedMessagePipeHandle pipe =
         mojo::edk::CreateChildMessagePipe(pipe_token);
+
+    base::ElapsedTimer timer;
     MojoShellConnectionImpl::Get()->BindToMessagePipe(std::move(pipe));
+    UMA_HISTOGRAM_TIMES("Mojo.Shell.ChildConnectionTime", timer.Elapsed());
   }
 
   mojo_application_.reset(new MojoApplication(GetIOTaskRunner()));
diff --git a/content/child/ftp_directory_listing_response_delegate.cc b/content/child/ftp_directory_listing_response_delegate.cc
index 5bf21a7..cc4df55 100644
--- a/content/child/ftp_directory_listing_response_delegate.cc
+++ b/content/child/ftp_directory_listing_response_delegate.cc
@@ -63,10 +63,10 @@
     const WebURLResponse& response)
     : client_(client),
       loader_(loader) {
-  if (response.extraData()) {
+  if (response.getExtraData()) {
     // extraData can be NULL during tests.
     WebURLResponseExtraDataImpl* extra_data =
-        static_cast<WebURLResponseExtraDataImpl*>(response.extraData());
+        static_cast<WebURLResponseExtraDataImpl*>(response.getExtraData());
     extra_data->set_is_ftp_directory_listing(true);
   }
   Init(response.url());
diff --git a/content/child/multipart_response_delegate.cc b/content/child/multipart_response_delegate.cc
deleted file mode 100644
index 03ffdd3..0000000
--- a/content/child/multipart_response_delegate.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/child/multipart_response_delegate.h"
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_util.h"
-#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebURL.h"
-#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
-
-using blink::WebHTTPHeaderVisitor;
-using blink::WebString;
-using blink::WebURLLoader;
-using blink::WebURLLoaderClient;
-using blink::WebURLResponse;
-
-namespace content {
-
-namespace {
-
-// The list of response headers that we do not copy from the original
-// response when generating a WebURLResponse for a MIME payload.
-const char* kReplaceHeaders[] = {
-  "content-type",
-  "content-length",
-  "content-disposition",
-  "content-range",
-  "range",
-  "set-cookie"
-};
-
-class HeaderCopier : public WebHTTPHeaderVisitor {
- public:
-  HeaderCopier(WebURLResponse* response)
-      : response_(response) {
-  }
-  void visitHeader(const WebString& name, const WebString& value) override {
-    const std::string& name_utf8 = name.utf8();
-    for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) {
-      if (base::LowerCaseEqualsASCII(name_utf8, kReplaceHeaders[i]))
-        return;
-    }
-    response_->setHTTPHeaderField(name, value);
-  }
- private:
-  WebURLResponse* response_;
-};
-
-}  // namespace
-
-MultipartResponseDelegate::MultipartResponseDelegate(
-    WebURLLoaderClient* client,
-    WebURLLoader* loader,
-    const WebURLResponse& response,
-    const std::string& boundary)
-    : client_(client),
-      loader_(loader),
-      original_response_(response),
-      encoded_data_length_(0),
-      boundary_("--"),
-      first_received_data_(true),
-      processing_headers_(false),
-      stop_sending_(false),
-      has_sent_first_response_(false) {
-  // Some servers report a boundary prefixed with "--".  See bug 5786.
-  if (base::StartsWith(boundary, "--", base::CompareCase::SENSITIVE)) {
-    boundary_.assign(boundary);
-  } else {
-    boundary_.append(boundary);
-  }
-}
-
-void MultipartResponseDelegate::OnReceivedData(const char* data,
-                                               int data_len,
-                                               int encoded_data_length) {
-  // stop_sending_ means that we've already received the final boundary token.
-  // The server should stop sending us data at this point, but if it does, we
-  // just throw it away.
-  if (stop_sending_)
-    return;
-
-  data_.append(data, data_len);
-  encoded_data_length_ += encoded_data_length;
-  if (first_received_data_) {
-    // Some servers don't send a boundary token before the first chunk of
-    // data.  We handle this case anyway (Gecko does too).
-    first_received_data_ = false;
-
-    // Eat leading \r\n
-    int pos = PushOverLine(data_, 0);
-    if (pos)
-      data_ = data_.substr(pos);
-
-    if (data_.length() < boundary_.length() + 2) {
-      // We don't have enough data yet to make a boundary token.  Just wait
-      // until the next chunk of data arrives.
-      first_received_data_ = true;
-      return;
-    }
-
-    if (0 != data_.compare(0, boundary_.length(), boundary_)) {
-      data_ = boundary_ + "\n" + data_;
-    }
-  }
-  DCHECK(!first_received_data_);
-
-  // Headers
-  if (processing_headers_) {
-    // Eat leading \r\n
-    int pos = PushOverLine(data_, 0);
-    if (pos)
-      data_ = data_.substr(pos);
-
-    if (ParseHeaders()) {
-      // Successfully parsed headers.
-      processing_headers_ = false;
-    } else {
-      // Get more data before trying again.
-      return;
-    }
-  }
-  DCHECK(!processing_headers_);
-
-  size_t boundary_pos;
-  while ((boundary_pos = FindBoundary()) != std::string::npos) {
-    if (client_) {
-      // Strip out trailing \n\r characters in the buffer preceding the
-      // boundary on the same lines as Firefox.
-      size_t data_length = boundary_pos;
-      if (boundary_pos > 0 && data_[boundary_pos - 1] == '\n') {
-        data_length--;
-        if (boundary_pos > 1 && data_[boundary_pos - 2] == '\r') {
-          data_length--;
-        }
-      }
-      if (data_length > 0) {
-        // Send the last data chunk.
-        client_->didReceiveData(loader_,
-                                data_.data(),
-                                static_cast<int>(data_length),
-                                encoded_data_length_);
-        encoded_data_length_ = 0;
-      }
-    }
-    size_t boundary_end_pos = boundary_pos + boundary_.length();
-    if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) {
-      // This was the last boundary so we can stop processing.
-      stop_sending_ = true;
-      data_.clear();
-      return;
-    }
-
-    // We can now throw out data up through the boundary
-    int offset = PushOverLine(data_, boundary_end_pos);
-    data_ = data_.substr(boundary_end_pos + offset);
-
-    // Ok, back to parsing headers
-    if (!ParseHeaders()) {
-      processing_headers_ = true;
-      break;
-    }
-  }
-
-  // At this point, we should send over any data we have, but keep enough data
-  // buffered to handle a boundary that may have been truncated.
-  if (!processing_headers_ && data_.length() > boundary_.length()) {
-    // If the last character is a new line character, go ahead and just send
-    // everything we have buffered.  This matches an optimization in Gecko.
-    int send_length = data_.length() - boundary_.length();
-    if (data_.back() == '\n')
-      send_length = data_.length();
-    if (client_)
-      client_->didReceiveData(loader_,
-                              data_.data(),
-                              send_length,
-                              encoded_data_length_);
-    data_ = data_.substr(send_length);
-    encoded_data_length_ = 0;
-  }
-}
-
-void MultipartResponseDelegate::OnCompletedRequest() {
-  // If we have any pending data and we're not in a header, go ahead and send
-  // it to WebCore.
-  if (!processing_headers_ && !data_.empty() && !stop_sending_ && client_) {
-    client_->didReceiveData(loader_,
-                            data_.data(),
-                            static_cast<int>(data_.length()),
-                            encoded_data_length_);
-    encoded_data_length_ = 0;
-  }
-}
-
-int MultipartResponseDelegate::PushOverLine(const std::string& data,
-                                            size_t pos) {
-  int offset = 0;
-  if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) {
-    ++offset;
-    if (pos + 1 < data.length() && data[pos + 1] == '\n')
-      ++offset;
-  }
-  return offset;
-}
-
-bool MultipartResponseDelegate::ParseHeaders() {
-  int headers_end_pos = net::HttpUtil::LocateEndOfAdditionalHeaders(
-      data_.c_str(), data_.size(), 0);
-
-  if (headers_end_pos < 0)
-    return false;
-
-  // Eat headers and prepend a status line as is required by
-  // HttpResponseHeaders.
-  std::string headers("HTTP/1.1 200 OK\r\n");
-  headers.append(data_, 0, headers_end_pos);
-  data_ = data_.substr(headers_end_pos);
-
-  scoped_refptr<net::HttpResponseHeaders> response_headers =
-      new net::HttpResponseHeaders(
-          net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
-
-  // Create a WebURLResponse based on the original set of headers + the
-  // replacement headers. We only replace the same few headers that gecko
-  // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp.
-  WebURLResponse response(original_response_.url());
-
-  std::string mime_type;
-  response_headers->GetMimeType(&mime_type);
-  response.setMIMEType(WebString::fromUTF8(mime_type));
-
-  std::string charset;
-  response_headers->GetCharset(&charset);
-  response.setTextEncodingName(WebString::fromUTF8(charset));
-
-  // Copy the response headers from the original response.
-  HeaderCopier copier(&response);
-  original_response_.visitHTTPHeaderFields(&copier);
-
-  // Replace original headers with multipart headers listed in kReplaceHeaders.
-  for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) {
-    std::string name(kReplaceHeaders[i]);
-    std::string value;
-    size_t iterator = 0;
-    while (response_headers->EnumerateHeader(&iterator, name, &value)) {
-      response.addHTTPHeaderField(WebString::fromLatin1(name),
-                                  WebString::fromLatin1(value));
-    }
-  }
-  // To avoid recording every multipart load as a separate visit in
-  // the history database, we want to keep track of whether the response
-  // is part of a multipart payload.  We do want to record the first visit,
-  // so we only set isMultipartPayload to true after the first visit.
-  response.setIsMultipartPayload(has_sent_first_response_);
-  has_sent_first_response_ = true;
-  // Send the response!
-  if (client_)
-    client_->didReceiveResponse(loader_, response);
-
-  return true;
-}
-
-// Boundaries are supposed to be preceeded with --, but it looks like gecko
-// doesn't require the dashes to exist.  See nsMultiMixedConv::FindToken.
-size_t MultipartResponseDelegate::FindBoundary() {
-  size_t boundary_pos = data_.find(boundary_);
-  if (boundary_pos != std::string::npos) {
-    // Back up over -- for backwards compat
-    // TODO(tc): Don't we only want to do this once?  Gecko code doesn't seem
-    // to care.
-    if (boundary_pos >= 2) {
-      if ('-' == data_[boundary_pos - 1] && '-' == data_[boundary_pos - 2]) {
-        boundary_pos -= 2;
-        boundary_ = "--" + boundary_;
-      }
-    }
-  }
-  return boundary_pos;
-}
-
-}  // namespace content
diff --git a/content/child/multipart_response_delegate.h b/content/child/multipart_response_delegate.h
deleted file mode 100644
index 1cf6901..0000000
--- a/content/child/multipart_response_delegate.h
+++ /dev/null
@@ -1,139 +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.
-//
-// A delegate class of WebURLLoaderImpl that handles multipart/x-mixed-replace
-// data.  We special case multipart/x-mixed-replace because WebCore expects a
-// separate didReceiveResponse for each new message part.
-//
-// Most of the logic and edge case handling are based on the Mozilla's
-// implementation in netwerk/streamconv/converters/nsMultiMixedConv.cpp.
-// This seems like a derivative work, so here's the original license:
-
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef CONTENT_CHILD_MULTIPART_RESPONSE_DELEGATE_H_
-#define CONTENT_CHILD_MULTIPART_RESPONSE_DELEGATE_H_
-
-#include <string>
-
-#include <stddef.h>
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "third_party/WebKit/public/platform/WebURLResponse.h"
-
-namespace blink {
-class WebURLLoader;
-class WebURLLoaderClient;
-}
-
-namespace content {
-
-class CONTENT_EXPORT MultipartResponseDelegate {
- public:
-  MultipartResponseDelegate(blink::WebURLLoaderClient* client,
-                            blink::WebURLLoader* loader,
-                            const blink::WebURLResponse& response,
-                            const std::string& boundary);
-
-  // Passed through from ResourceHandleInternal
-  void OnReceivedData(const char* data, int data_len, int encoded_data_length);
-  void OnCompletedRequest();
-
-  // The request has been canceled, so stop making calls to the client.
-  void Cancel() {
-    client_ = NULL;
-    loader_ = NULL;
-  }
-
- private:
-  friend class MultipartResponseDelegateTester;  // For unittests.
-
-  // Pointers to the client and associated loader so we can make callbacks as
-  // we parse pieces of data.
-  blink::WebURLLoaderClient* client_;
-  blink::WebURLLoader* loader_;
-
-  // The original resource response for this request.  We use this as a
-  // starting point for each parts response.
-  blink::WebURLResponse original_response_;
-
-  // Checks to see if data[pos] character is a line break; handles crlf, lflf,
-  // lf, or cr. Returns the number of characters to skip over (0, 1 or 2).
-  int PushOverLine(const std::string& data, size_t pos);
-
-  // Tries to parse http headers from the start of data_.  Returns true if it
-  // succeeds and sends a didReceiveResponse to m_client.  Returns false if
-  // the header is incomplete (in which case we just wait for more data).
-  bool ParseHeaders();
-
-  // Find the next boundary in data_.  Returns std::string::npos if there's no
-  // full token.
-  size_t FindBoundary();
-
-  // Transferred data size accumulated between client callbacks.
-  int encoded_data_length_;
-
-  // A temporary buffer to hold data between reads for multipart data that
-  // gets split in the middle of a header.
-  std::string data_;
-
-  // Multipart boundary token
-  std::string boundary_;
-
-  // true until we get our first on received data call
-  bool first_received_data_;
-
-  // true if we're truncated in the middle of a header
-  bool processing_headers_;
-
-  // true when we're done sending information.  At that point, we stop
-  // processing AddData requests.
-  bool stop_sending_;
-
-  // true after we've sent our first response to the WebURLLoaderClient.
-  bool has_sent_first_response_;
-
-  DISALLOW_COPY_AND_ASSIGN(MultipartResponseDelegate);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_MULTIPART_RESPONSE_DELEGATE_H_
diff --git a/content/child/multipart_response_delegate_unittest.cc b/content/child/multipart_response_delegate_unittest.cc
deleted file mode 100644
index 5683c3d..0000000
--- a/content/child/multipart_response_delegate_unittest.cc
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/child/multipart_response_delegate.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/macros.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebURL.h"
-#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
-#include "third_party/WebKit/public/platform/WebURLResponse.h"
-
-using blink::WebString;
-using blink::WebURL;
-using blink::WebURLError;
-using blink::WebURLLoader;
-using blink::WebURLLoaderClient;
-using blink::WebURLRequest;
-using blink::WebURLResponse;
-using std::string;
-
-namespace content {
-
-class MultipartResponseDelegateTester {
- public:
-  MultipartResponseDelegateTester(MultipartResponseDelegate* delegate)
-      : delegate_(delegate) {
-  }
-
-  int PushOverLine(const std::string& data, size_t pos) {
-    return delegate_->PushOverLine(data, pos);
-  }
-
-  bool ParseHeaders() { return delegate_->ParseHeaders(); }
-  size_t FindBoundary() { return delegate_->FindBoundary(); }
-  std::string& boundary() { return delegate_->boundary_; }
-  std::string& data() { return delegate_->data_; }
-
- private:
-  MultipartResponseDelegate* delegate_;
-};
-
-namespace {
-
-class MultipartResponseTest : public testing::Test {
-};
-
-class MockWebURLLoaderClient : public WebURLLoaderClient {
- public:
-  MockWebURLLoaderClient() { Reset(); }
-
-  void willFollowRedirect(WebURLLoader*,
-                          WebURLRequest&,
-                          const WebURLResponse&) override {}
-  void didSendData(WebURLLoader*,
-                   unsigned long long,
-                   unsigned long long) override {}
-
-  void didReceiveResponse(WebURLLoader* loader,
-                          const WebURLResponse& response) override {
-    ++received_response_;
-    response_ = response;
-    data_.clear();
-  }
-  void didReceiveData(blink::WebURLLoader* loader,
-                      const char* data,
-                      int data_length,
-                      int encoded_data_length) override {
-    ++received_data_;
-    data_.append(data, data_length);
-    total_encoded_data_length_ += encoded_data_length;
-  }
-  void didFinishLoading(WebURLLoader*,
-                        double finishTime,
-                        int64_t total_encoded_data_length) override {}
-  void didFail(WebURLLoader*, const WebURLError&) override {}
-
-  void Reset() {
-    received_response_ = received_data_ = total_encoded_data_length_ = 0;
-    data_.clear();
-    response_.reset();
-  }
-
-  string GetResponseHeader(const char* name) const {
-    return string(response_.httpHeaderField(WebString::fromUTF8(name)).utf8());
-  }
-
-  int received_response_, received_data_, total_encoded_data_length_;
-  string data_;
-  WebURLResponse response_;
-};
-
-// We can't put this in an anonymous function because it's a friend class for
-// access to private members.
-TEST(MultipartResponseTest, Functions) {
-  // PushOverLine tests
-
-  WebURLResponse response;
-  response.initialize();
-  response.setMIMEType("multipart/x-mixed-replace");
-  response.setHTTPHeaderField("Foo", "Bar");
-  response.setHTTPHeaderField("Content-type", "text/plain");
-  MockWebURLLoaderClient client;
-  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
-  MultipartResponseDelegateTester delegate_tester(&delegate);
-
-  struct {
-    const char* input;
-    const int position;
-    const int expected;
-  } line_tests[] = {
-    { "Line", 0, 0 },
-    { "Line", 2, 0 },
-    { "Line", 10, 0 },
-    { "\r\nLine", 0, 2 },
-    { "\nLine", 0, 1 },
-    { "\n\nLine", 0, 2 },
-    { "\rLine", 0, 1 },
-    { "Line\r\nLine", 4, 2 },
-    { "Line\nLine", 4, 1 },
-    { "Line\n\nLine", 4, 2 },
-    { "Line\rLine", 4, 1 },
-    { "Line\r\rLine", 4, 1 },
-  };
-  for (size_t i = 0; i < arraysize(line_tests); ++i) {
-    EXPECT_EQ(line_tests[i].expected,
-              delegate_tester.PushOverLine(line_tests[i].input,
-                                           line_tests[i].position));
-  }
-
-  // ParseHeaders tests
-  struct {
-    const char* data;
-    const bool rv;
-    const int received_response_calls;
-    const char* newdata;
-  } header_tests[] = {
-    { "This is junk", false, 0, "This is junk" },
-    { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" },
-    { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" },
-    { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" },
-    { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" },
-    { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" },
-    { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" },
-    { "\r\n", true, 1, "" },
-  };
-  for (size_t i = 0; i < arraysize(header_tests); ++i) {
-    client.Reset();
-    delegate_tester.data().assign(header_tests[i].data);
-    EXPECT_EQ(header_tests[i].rv,
-              delegate_tester.ParseHeaders());
-    EXPECT_EQ(header_tests[i].received_response_calls,
-              client.received_response_);
-    EXPECT_EQ(string(header_tests[i].newdata),
-              delegate_tester.data());
-  }
-  // Test that the resource response is filled in correctly when parsing
-  // headers.
-  client.Reset();
-  string test_header("content-type: image/png\ncontent-length: 10\n\n");
-  delegate_tester.data().assign(test_header);
-  EXPECT_TRUE(delegate_tester.ParseHeaders());
-  EXPECT_TRUE(delegate_tester.data().length() == 0);
-  EXPECT_EQ(string("image/png"), client.GetResponseHeader("Content-Type"));
-  EXPECT_EQ(string("10"), client.GetResponseHeader("content-length"));
-  // This header is passed from the original request.
-  EXPECT_EQ(string("Bar"), client.GetResponseHeader("foo"));
-
-  // Make sure we parse the right mime-type if a charset is provided.
-  client.Reset();
-  string test_header2("content-type: text/html; charset=utf-8\n\n");
-  delegate_tester.data().assign(test_header2);
-  EXPECT_TRUE(delegate_tester.ParseHeaders());
-  EXPECT_TRUE(delegate_tester.data().length() == 0);
-  EXPECT_EQ(string("text/html; charset=utf-8"),
-            client.GetResponseHeader("Content-Type"));
-  EXPECT_EQ(string("utf-8"),
-            string(client.response_.textEncodingName().utf8()));
-
-  // FindBoundary tests
-  struct {
-    const char* boundary;
-    const char* data;
-    const size_t position;
-  } boundary_tests[] = {
-    { "bound", "bound", 0 },
-    { "bound", "--bound", 0 },
-    { "bound", "junkbound", 4 },
-    { "bound", "junk--bound", 4 },
-    { "foo", "bound", string::npos },
-    { "bound", "--boundbound", 0 },
-  };
-  for (size_t i = 0; i < arraysize(boundary_tests); ++i) {
-    delegate_tester.boundary().assign(boundary_tests[i].boundary);
-    delegate_tester.data().assign(boundary_tests[i].data);
-    EXPECT_EQ(boundary_tests[i].position,
-              delegate_tester.FindBoundary());
-  }
-}
-
-TEST(MultipartResponseTest, MissingBoundaries) {
-  WebURLResponse response;
-  response.initialize();
-  response.setMIMEType("multipart/x-mixed-replace");
-  response.setHTTPHeaderField("Foo", "Bar");
-  response.setHTTPHeaderField("Content-type", "text/plain");
-  MockWebURLLoaderClient client;
-  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
-
-  // No start boundary
-  string no_start_boundary(
-    "Content-type: text/plain\n\n"
-    "This is a sample response\n"
-    "--bound--"
-    "ignore junk after end token --bound\n\nTest2\n");
-  delegate.OnReceivedData(no_start_boundary.c_str(),
-                          static_cast<int>(no_start_boundary.length()),
-                          static_cast<int>(no_start_boundary.length()));
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-  EXPECT_EQ(string("This is a sample response"), client.data_);
-  EXPECT_EQ(static_cast<int>(no_start_boundary.length()),
-            client.total_encoded_data_length_);
-
-  delegate.OnCompletedRequest();
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-
-  // No end boundary
-  client.Reset();
-  MultipartResponseDelegate delegate2(&client, NULL, response, "bound");
-  string no_end_boundary(
-    "bound\nContent-type: text/plain\n\n"
-    "This is a sample response\n");
-  delegate2.OnReceivedData(no_end_boundary.c_str(),
-                          static_cast<int>(no_end_boundary.length()),
-                          static_cast<int>(no_end_boundary.length()));
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-  EXPECT_EQ("This is a sample response\n", client.data_);
-  EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
-            client.total_encoded_data_length_);
-
-  delegate2.OnCompletedRequest();
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-  EXPECT_EQ(string("This is a sample response\n"), client.data_);
-  EXPECT_EQ(static_cast<int>(no_end_boundary.length()),
-            client.total_encoded_data_length_);
-
-  // Neither boundary
-  client.Reset();
-  MultipartResponseDelegate delegate3(&client, NULL, response, "bound");
-  string no_boundaries(
-    "Content-type: text/plain\n\n"
-    "This is a sample response\n");
-  delegate3.OnReceivedData(no_boundaries.c_str(),
-                           static_cast<int>(no_boundaries.length()),
-                           static_cast<int>(no_boundaries.length()));
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-  EXPECT_EQ("This is a sample response\n", client.data_);
-  EXPECT_EQ(static_cast<int>(no_boundaries.length()),
-            client.total_encoded_data_length_);
-
-  delegate3.OnCompletedRequest();
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-  EXPECT_EQ(string("This is a sample response\n"), client.data_);
-  EXPECT_EQ(static_cast<int>(no_boundaries.length()),
-            client.total_encoded_data_length_);
-}
-
-TEST(MultipartResponseTest, MalformedBoundary) {
-  // Some servers send a boundary that is prefixed by "--".  See bug 5786.
-
-  WebURLResponse response;
-  response.initialize();
-  response.setMIMEType("multipart/x-mixed-replace");
-  response.setHTTPHeaderField("Foo", "Bar");
-  response.setHTTPHeaderField("Content-type", "text/plain");
-  MockWebURLLoaderClient client;
-  MultipartResponseDelegate delegate(&client, NULL, response, "--bound");
-
-  string data(
-    "--bound\n"
-    "Content-type: text/plain\n\n"
-    "This is a sample response\n"
-    "--bound--"
-    "ignore junk after end token --bound\n\nTest2\n");
-  delegate.OnReceivedData(data.c_str(),
-                          static_cast<int>(data.length()),
-                          static_cast<int>(data.length()));
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-  EXPECT_EQ(string("This is a sample response"), client.data_);
-  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
-
-  delegate.OnCompletedRequest();
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-}
-
-
-// Used in for tests that break the data in various places.
-struct TestChunk {
-  const int start_pos;  // offset in data
-  const int end_pos;    // end offset in data
-  const int expected_responses;
-  const int expected_received_data;
-  const char* expected_data;
-  const int expected_encoded_data_length;
-};
-
-void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size,
-                           int responses, int received_data,
-                           const char* completed_data,
-                           int completed_encoded_data_length) {
-  const string data(
-    "--bound\n"                    // 0-7
-    "Content-type: image/png\n\n"  // 8-32
-    "datadatadatadatadata"         // 33-52
-    "--bound\n"                    // 53-60
-    "Content-type: image/jpg\n\n"  // 61-85
-    "foofoofoofoofoo"              // 86-100
-    "--bound--");                  // 101-109
-
-  WebURLResponse response;
-  response.initialize();
-  response.setMIMEType("multipart/x-mixed-replace");
-  MockWebURLLoaderClient client;
-  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
-
-  for (int i = 0; i < chunks_size; ++i) {
-    ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos);
-    string chunk = data.substr(chunks[i].start_pos,
-                               chunks[i].end_pos - chunks[i].start_pos);
-    delegate.OnReceivedData(
-        chunk.c_str(),
-        static_cast<int>(chunk.length()),
-        static_cast<int>(chunk.length()));
-    EXPECT_EQ(chunks[i].expected_responses, client.received_response_);
-    EXPECT_EQ(chunks[i].expected_received_data, client.received_data_);
-    EXPECT_EQ(string(chunks[i].expected_data), client.data_);
-    EXPECT_EQ(chunks[i].expected_encoded_data_length,
-              client.total_encoded_data_length_);
-  }
-  // Check final state
-  delegate.OnCompletedRequest();
-  EXPECT_EQ(responses, client.received_response_);
-  EXPECT_EQ(received_data, client.received_data_);
-  string completed_data_string(completed_data);
-  EXPECT_EQ(completed_data_string, client.data_);
-  EXPECT_EQ(completed_encoded_data_length, client.total_encoded_data_length_);
-}
-
-TEST(MultipartResponseTest, BreakInBoundary) {
-  // Break in the first boundary
-  const TestChunk bound1[] = {
-    { 0, 4, 0, 0, "", 0 },
-    { 4, 110, 2, 2, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(bound1, arraysize(bound1),
-                        2, 2, "foofoofoofoofoo", 110);
-
-  // Break in first and second
-  const TestChunk bound2[] = {
-    { 0, 4, 0, 0, "", 0 },
-    { 4, 55, 1, 1, "datadatadatadat", 55 },
-    { 55, 65, 1, 2, "datadatadatadatadata", 65 },
-    { 65, 110, 2, 3, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(bound2, arraysize(bound2),
-                        2, 3, "foofoofoofoofoo", 110);
-
-  // Break in second only
-  const TestChunk bound3[] = {
-    { 0, 55, 1, 1, "datadatadatadat", 55 },
-    { 55, 110, 2, 3, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(bound3, arraysize(bound3),
-                        2, 3, "foofoofoofoofoo", 110);
-}
-
-TEST(MultipartResponseTest, BreakInHeaders) {
-  // Break in first header
-  const TestChunk header1[] = {
-    { 0, 10, 0, 0, "", 0 },
-    { 10, 35, 1, 0, "", 0 },
-    { 35, 110, 2, 2, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(header1, arraysize(header1),
-                        2, 2, "foofoofoofoofoo", 110);
-
-  // Break in both headers
-  const TestChunk header2[] = {
-    { 0, 10, 0, 0, "", 0 },
-    { 10, 65, 1, 1, "datadatadatadatadata", 65 },
-    { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(header2, arraysize(header2),
-                        2, 2, "foofoofoofoofoo", 110);
-
-  // Break at end of a header
-  const TestChunk header3[] = {
-    { 0, 33, 1, 0, "", 0 },
-    { 33, 65, 1, 1, "datadatadatadatadata", 65 },
-    { 65, 110, 2, 2, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(header3, arraysize(header3),
-                        2, 2, "foofoofoofoofoo", 110);
-}
-
-TEST(MultipartResponseTest, BreakInData) {
-  // All data as one chunk
-  const TestChunk data1[] = {
-    { 0, 110, 2, 2, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(data1, arraysize(data1),
-                        2, 2, "foofoofoofoofoo", 110);
-
-  // breaks in data segment
-  const TestChunk data2[] = {
-    { 0, 35, 1, 0, "", 0 },
-    { 35, 65, 1, 1, "datadatadatadatadata", 65 },
-    { 65, 90, 2, 1, "", 65 },
-    { 90, 110, 2, 2, "foofoofoofoofoo", 110 },
-  };
-  VariousChunkSizesTest(data2, arraysize(data2),
-                        2, 2, "foofoofoofoofoo", 110);
-
-  // Incomplete send
-  const TestChunk data3[] = {
-    { 0, 35, 1, 0, "", 0 },
-    { 35, 90, 2, 1, "", 90 },
-  };
-  VariousChunkSizesTest(data3, arraysize(data3),
-                        2, 2, "foof", 90);
-}
-
-TEST(MultipartResponseTest, SmallChunk) {
-  WebURLResponse response;
-  response.initialize();
-  response.setMIMEType("multipart/x-mixed-replace");
-  response.setHTTPHeaderField("Content-type", "text/plain");
-  MockWebURLLoaderClient client;
-  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
-
-  // Test chunks of size 1, 2, and 0.
-  string data(
-    "--boundContent-type: text/plain\n\n"
-    "\n--boundContent-type: text/plain\n\n"
-    "\n\n--boundContent-type: text/plain\n\n"
-    "--boundContent-type: text/plain\n\n"
-    "end--bound--");
-  delegate.OnReceivedData(data.c_str(),
-                          static_cast<int>(data.length()),
-                          static_cast<int>(data.length()));
-  EXPECT_EQ(4, client.received_response_);
-  EXPECT_EQ(2, client.received_data_);
-  EXPECT_EQ(string("end"), client.data_);
-  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
-
-  delegate.OnCompletedRequest();
-  EXPECT_EQ(4, client.received_response_);
-  EXPECT_EQ(2, client.received_data_);
-}
-
-TEST(MultipartResponseTest, MultipleBoundaries) {
-  // Test multiple boundaries back to back
-  WebURLResponse response;
-  response.initialize();
-  response.setMIMEType("multipart/x-mixed-replace");
-  MockWebURLLoaderClient client;
-  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
-
-  string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
-  delegate.OnReceivedData(data.c_str(),
-                          static_cast<int>(data.length()),
-                          static_cast<int>(data.length()));
-  EXPECT_EQ(2, client.received_response_);
-  EXPECT_EQ(1, client.received_data_);
-  EXPECT_EQ(string("foofoo"), client.data_);
-  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
-}
-
-TEST(MultipartResponseTest, MultipartPayloadSet) {
-  WebURLResponse response;
-  response.initialize();
-  response.setMIMEType("multipart/x-mixed-replace");
-  MockWebURLLoaderClient client;
-  MultipartResponseDelegate delegate(&client, NULL, response, "bound");
-
-  string data(
-      "--bound\n"
-      "Content-type: text/plain\n\n"
-      "response data\n"
-      "--bound\n");
-  delegate.OnReceivedData(data.c_str(),
-                          static_cast<int>(data.length()),
-                          static_cast<int>(data.length()));
-  EXPECT_EQ(1, client.received_response_);
-  EXPECT_EQ(string("response data"), client.data_);
-  EXPECT_EQ(static_cast<int>(data.length()), client.total_encoded_data_length_);
-  EXPECT_FALSE(client.response_.isMultipartPayload());
-
-  string data2(
-      "Content-type: text/plain\n\n"
-      "response data2\n"
-      "--bound\n");
-  delegate.OnReceivedData(data2.c_str(),
-                          static_cast<int>(data2.length()),
-                          static_cast<int>(data2.length()));
-  EXPECT_EQ(2, client.received_response_);
-  EXPECT_EQ(string("response data2"), client.data_);
-  EXPECT_EQ(static_cast<int>(data.length()) + static_cast<int>(data2.length()),
-            client.total_encoded_data_length_);
-  EXPECT_TRUE(client.response_.isMultipartPayload());
-}
-
-}  // namespace
-
-}  // namespace content
diff --git a/content/child/service_worker/web_service_worker_impl.cc b/content/child/service_worker/web_service_worker_impl.cc
index f926872..7c5a5101 100644
--- a/content/child/service_worker/web_service_worker_impl.cc
+++ b/content/child/service_worker/web_service_worker_impl.cc
@@ -9,9 +9,11 @@
 #include "base/macros.h"
 #include "content/child/service_worker/service_worker_dispatcher.h"
 #include "content/child/service_worker/service_worker_handle_reference.h"
+#include "content/child/service_worker/web_service_worker_provider_impl.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/child/webmessageportchannel_impl.h"
 #include "content/common/service_worker/service_worker_messages.h"
+#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProxy.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
@@ -20,6 +22,7 @@
 using blink::WebMessagePortChannelArray;
 using blink::WebMessagePortChannelClient;
 using blink::WebRuntimeFeatures;
+using blink::WebSecurityOrigin;
 using blink::WebString;
 
 namespace content {
@@ -43,11 +46,13 @@
 void SendPostMessageToWorkerOnMainThread(
     ThreadSafeSender* thread_safe_sender,
     int handle_id,
+    int provider_id,
     const base::string16& message,
+    const url::Origin& source_origin,
     scoped_ptr<WebMessagePortChannelArray> channels) {
   if (WebRuntimeFeatures::isServiceWorkerExtendableMessageEventEnabled()) {
     thread_safe_sender->Send(new ServiceWorkerHostMsg_PostMessageToWorker(
-        handle_id, message,
+        handle_id, provider_id, message, source_origin,
         WebMessagePortChannelImpl::ExtractMessagePortIDs(std::move(channels))));
   } else {
     thread_safe_sender->Send(
@@ -100,8 +105,13 @@
   return state_;
 }
 
-void WebServiceWorkerImpl::postMessage(const WebString& message,
-                                       WebMessagePortChannelArray* channels) {
+void WebServiceWorkerImpl::postMessage(
+    blink::WebServiceWorkerProvider* provider,
+    const WebString& message,
+    const WebSecurityOrigin& source_origin,
+    WebMessagePortChannelArray* channels) {
+  WebServiceWorkerProviderImpl* provider_impl =
+      static_cast<WebServiceWorkerProviderImpl*>(provider);
   ServiceWorkerDispatcher* dispatcher =
       ServiceWorkerDispatcher::GetThreadSpecificInstance();
   DCHECK(dispatcher);
@@ -111,12 +121,14 @@
   // (with thread hopping), so we need to do the same thread hopping here not
   // to overtake those messages.
   dispatcher->main_thread_task_runner()->PostTask(
-      FROM_HERE, base::Bind(&SendPostMessageToWorkerOnMainThread,
-                            thread_safe_sender_, handle_ref_->handle_id(),
-                            // We cast WebString to string16 before crossing
-                            // threads for thread-safety.
-                            static_cast<base::string16>(message),
-                            base::Passed(make_scoped_ptr(channels))));
+      FROM_HERE,
+      base::Bind(&SendPostMessageToWorkerOnMainThread, thread_safe_sender_,
+                 handle_ref_->handle_id(), provider_impl->provider_id(),
+                 // We cast WebString to string16 before crossing
+                 // threads for thread-safety.
+                 static_cast<base::string16>(message),
+                 url::Origin(source_origin),
+                 base::Passed(make_scoped_ptr(channels))));
 }
 
 void WebServiceWorkerImpl::terminate() {
diff --git a/content/child/service_worker/web_service_worker_impl.h b/content/child/service_worker/web_service_worker_impl.h
index 02347f2..5bcf9d3 100644
--- a/content/child/service_worker/web_service_worker_impl.h
+++ b/content/child/service_worker/web_service_worker_impl.h
@@ -48,7 +48,9 @@
   blink::WebServiceWorkerProxy* proxy() override;
   blink::WebURL url() const override;
   blink::WebServiceWorkerState state() const override;
-  void postMessage(const blink::WebString& message,
+  void postMessage(blink::WebServiceWorkerProvider* provider,
+                   const blink::WebString& message,
+                   const blink::WebSecurityOrigin& source_origin,
                    blink::WebMessagePortChannelArray* channels) override;
   void terminate() override;
 
diff --git a/content/child/v8_value_converter_impl_unittest.cc b/content/child/v8_value_converter_impl_unittest.cc
index 311fa7f4..435ea30 100644
--- a/content/child/v8_value_converter_impl_unittest.cc
+++ b/content/child/v8_value_converter_impl_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/values.h"
 #include "content/child/v8_value_converter_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 namespace content {
@@ -287,6 +288,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   // Set up objects to throw when reading or writing 'foo'.
   const char* source =
@@ -329,6 +331,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "var arr = [];"
@@ -405,6 +408,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "Object.prototype.foo = 'foo';"
@@ -429,6 +433,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "return { foo: undefined, bar: null };"
@@ -487,6 +492,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "return {"
@@ -525,6 +531,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   const char* source = "(function() {"
       "var a = [0];"
@@ -549,6 +556,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   v8::Local<v8::Object> object;
   {
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index b4c4f69..2b9d783d 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -22,7 +22,6 @@
 #include "components/scheduler/child/web_task_runner_impl.h"
 #include "content/child/child_thread_impl.h"
 #include "content/child/ftp_directory_listing_response_delegate.h"
-#include "content/child/multipart_response_delegate.h"
 #include "content/child/request_extra_data.h"
 #include "content/child/request_info.h"
 #include "content/child/resource_dispatcher.h"
@@ -356,7 +355,6 @@
   scoped_ptr<blink::WebTaskRunner> web_task_runner_;
   WebReferrerPolicy referrer_policy_;
   scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_;
-  scoped_ptr<MultipartResponseDelegate> multipart_delegate_;
   scoped_ptr<StreamOverrideParameters> stream_override_;
   scoped_ptr<SharedMemoryDataConsumerHandle::Writer> body_stream_writer_;
   enum DeferState {NOT_DEFERRING, SHOULD_DEFER, DEFERRED_DATA};
@@ -415,11 +413,8 @@
   if (body_stream_writer_)
     body_stream_writer_->Fail();
 
-  // Ensure that we do not notify the multipart delegate anymore as it has
+  // Ensure that we do not notify the delegate anymore as it has
   // its own pointer to the client.
-  if (multipart_delegate_)
-    multipart_delegate_->Cancel();
-  // Ditto for the ftp delegate.
   if (ftp_listing_delegate_)
     ftp_listing_delegate_->Cancel();
 
@@ -459,9 +454,9 @@
                                       SyncLoadResponse* sync_load_response) {
   DCHECK(request_id_ == -1);
   request_ = request;  // Save the request.
-  if (request.extraData()) {
+  if (request.getExtraData()) {
     RequestExtraData* extra_data =
-        static_cast<RequestExtraData*>(request.extraData());
+        static_cast<RequestExtraData*>(request.getExtraData());
     stream_override_ = extra_data->TakeStreamOverrideOwnership();
   }
 
@@ -540,7 +535,7 @@
       GetRequestContextTypeForWebURLRequest(request);
   request_info.fetch_frame_type =
       GetRequestContextFrameTypeForWebURLRequest(request);
-  request_info.extra_data = request.extraData();
+  request_info.extra_data = request.getExtraData();
   request_info.report_raw_headers = request.reportRawHeaders();
   request_info.loading_web_task_runner.reset(web_task_runner_->clone());
 
@@ -645,6 +640,19 @@
       response.setMIMEType("text/html");
     }
   }
+  if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") {
+    std::string content_type;
+    info.headers->EnumerateHeader(NULL, "content-type", &content_type);
+
+    std::string mime_type;
+    std::string charset;
+    bool had_charset = false;
+    std::string boundary;
+    net::HttpUtil::ParseContentType(content_type, &mime_type, &charset,
+                                    &had_charset, &boundary);
+    base::TrimString(boundary, " \"", &boundary);
+    response.setMultipartBoundary(boundary.data(), boundary.size());
+  }
 
   if (request_.useStreamOnResponse()) {
     SharedMemoryDataConsumerHandle::BackpressureMode mode =
@@ -678,27 +686,7 @@
     return;
 
   DCHECK(!ftp_listing_delegate_.get());
-  DCHECK(!multipart_delegate_.get());
-  if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") {
-    std::string content_type;
-    info.headers->EnumerateHeader(NULL, "content-type", &content_type);
-
-    std::string mime_type;
-    std::string charset;
-    bool had_charset = false;
-    std::string boundary;
-    net::HttpUtil::ParseContentType(content_type, &mime_type, &charset,
-                                    &had_charset, &boundary);
-    base::TrimString(boundary, " \"", &boundary);
-
-    // If there's no boundary, just handle the request normally.  In the gecko
-    // code, nsMultiMixedConv::OnStartRequest throws an exception.
-    if (!boundary.empty()) {
-      multipart_delegate_.reset(
-          new MultipartResponseDelegate(client_, loader_, response, boundary));
-    }
-  } else if (info.mime_type == "text/vnd.chromium.ftp-dir" &&
-             !show_raw_listing) {
+  if (info.mime_type == "text/vnd.chromium.ftp-dir" && !show_raw_listing) {
     ftp_listing_delegate_.reset(
         new FtpDirectoryListingResponseDelegate(client_, loader_, response));
   }
@@ -721,20 +709,14 @@
     // The FTP listing delegate will make the appropriate calls to
     // client_->didReceiveData and client_->didReceiveResponse.
     ftp_listing_delegate_->OnReceivedData(payload, data_length);
-  } else if (multipart_delegate_) {
-    // The multipart delegate will make the appropriate calls to
-    // client_->didReceiveData and client_->didReceiveResponse.
-    multipart_delegate_->OnReceivedData(payload, data_length,
-                                        encoded_data_length);
   } else {
     // We dispatch the data even when |useStreamOnResponse()| is set, in order
     // to make Devtools work.
     client_->didReceiveData(loader_, payload, data_length, encoded_data_length);
 
     if (request_.useStreamOnResponse()) {
-      // We don't support ftp_listening_delegate_ and multipart_delegate_ for
-      // now.
-      // TODO(yhirano): Support ftp listening and multipart.
+      // We don't support ftp_listening_delegate_ for now.
+      // TODO(yhirano): Support ftp listening.
       body_stream_writer_->AddData(std::move(data));
     }
   }
@@ -756,9 +738,6 @@
   if (ftp_listing_delegate_) {
     ftp_listing_delegate_->OnCompletedRequest();
     ftp_listing_delegate_.reset(NULL);
-  } else if (multipart_delegate_) {
-    multipart_delegate_->OnCompletedRequest();
-    multipart_delegate_.reset(NULL);
   }
 
   if (body_stream_writer_ && error_code != net::OK)
@@ -791,9 +770,6 @@
   if (ftp_listing_delegate_) {
     ftp_listing_delegate_->OnCompletedRequest();
     ftp_listing_delegate_.reset(NULL);
-  } else if (multipart_delegate_) {
-    multipart_delegate_->OnCompletedRequest();
-    multipart_delegate_.reset(NULL);
   }
 
   if (body_stream_writer_) {
diff --git a/content/child/web_url_loader_impl_unittest.cc b/content/child/web_url_loader_impl_unittest.cc
index b8bc240..a85dd04 100644
--- a/content/child/web_url_loader_impl_unittest.cc
+++ b/content/child/web_url_loader_impl_unittest.cc
@@ -53,21 +53,6 @@
     "drwxr-xr-x    3 ftp      ftp          4096 May 15 18:11 goat\n"
     "drwxr-xr-x    3 ftp      ftp          4096 May 15 18:11 hat";
 
-const char kMultipartResponseMimeType[] = "multipart/x-mixed-replace";
-const char kMultipartResponseHeaders[] =
-    "HTTP/1.0 200 Peachy\r\n"
-    "Content-Type: multipart/x-mixed-replace; boundary=boundary\r\n\r\n";
-// Simple multipart response.  Imporant details for the tests are that it
-// contains multiple chunks, and that it doesn't end with a boundary, so will
-// send data in OnResponseComplete.  Also, it will resolve to kTestData.
-const char kMultipartResponse[] =
-    "--boundary\n"
-    "Content-type: text/html\n\n"
-    "bl"
-    "--boundary\n"
-    "Content-type: text/html\n\n"
-    "ah!";
-
 class TestResourceDispatcher : public ResourceDispatcher {
  public:
   TestResourceDispatcher() :
@@ -117,7 +102,6 @@
       : loader_(new WebURLLoaderImpl(
             dispatcher,
             make_scoped_ptr(new scheduler::WebTaskRunnerImpl(task_runner)))),
-        expect_multipart_response_(false),
         delete_on_receive_redirect_(false),
         delete_on_receive_response_(false),
         delete_on_receive_data_(false),
@@ -156,9 +140,7 @@
       const blink::WebURLResponse& response) override {
     EXPECT_TRUE(loader_);
     EXPECT_EQ(loader_.get(), loader);
-
-    // Only multipart requests may receive multiple response headers.
-    EXPECT_TRUE(expect_multipart_response_ || !did_receive_response_);
+    EXPECT_FALSE(did_receive_response_);
 
     did_receive_response_ = true;
     response_ = response;
@@ -226,8 +208,6 @@
     loader_.reset();
   }
 
-  void set_expect_multipart_response() { expect_multipart_response_ = true; }
-
   void set_delete_on_receive_redirect() { delete_on_receive_redirect_ = true; }
   void set_delete_on_receive_response() { delete_on_receive_response_ = true; }
   void set_delete_on_receive_data() { delete_on_receive_data_ = true; }
@@ -244,8 +224,6 @@
  private:
   scoped_ptr<WebURLLoaderImpl> loader_;
 
-  bool expect_multipart_response_;
-
   bool delete_on_receive_redirect_;
   bool delete_on_receive_response_;
   bool delete_on_receive_data_;
@@ -344,25 +322,6 @@
     EXPECT_NE(kFtpDirListing, client()->received_data());
   }
 
-  void DoReceiveResponseMultipart() {
-    EXPECT_FALSE(client()->did_receive_response());
-    content::ResourceResponseInfo response_info;
-    response_info.headers = new net::HttpResponseHeaders(
-        net::HttpUtil::AssembleRawHeaders(kMultipartResponseHeaders,
-                                          strlen(kMultipartResponseHeaders)));
-    response_info.mime_type = kMultipartResponseMimeType;
-    peer()->OnReceivedResponse(response_info);
-    EXPECT_TRUE(client()->did_receive_response());
-  }
-
-  void DoReceiveDataMultipart() {
-    peer()->OnReceivedData(make_scoped_ptr(
-        new FixedReceivedData(kMultipartResponse, strlen(kMultipartResponse),
-                              strlen(kMultipartResponse))));
-    // Multipart delegate should modify the data the client sees.
-    EXPECT_NE(kMultipartResponse, client()->received_data());
-  }
-
   TestWebURLLoaderClient* client() { return client_.get(); }
   TestResourceDispatcher* dispatcher() { return &dispatcher_; }
   RequestPeer* peer() { return dispatcher()->peer(); }
@@ -596,78 +555,6 @@
   DoFailRequest();
 }
 
-// Multipart integration tests.  These are focused more on safe deletion than
-// correct parsing of Multipart responses.
-
-TEST_F(WebURLLoaderImplTest, Multipart) {
-  client()->set_expect_multipart_response();
-  DoStartAsyncRequest();
-  DoReceiveResponseMultipart();
-  DoReceiveDataMultipart();
-  DoCompleteRequest();
-  EXPECT_EQ(kTestData, client()->received_data());
-  EXPECT_FALSE(dispatcher()->canceled());
-}
-
-TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstResponse) {
-  client()->set_expect_multipart_response();
-  client()->set_delete_on_receive_response();
-  DoStartAsyncRequest();
-  DoReceiveResponseMultipart();
-  EXPECT_EQ("", client()->received_data());
-}
-
-TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveSecondResponse) {
-  client()->set_expect_multipart_response();
-  DoStartAsyncRequest();
-  DoReceiveResponseMultipart();
-  client()->set_delete_on_receive_response();
-  DoReceiveDataMultipart();
-  EXPECT_EQ("", client()->received_data());
-}
-
-TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstData) {
-  client()->set_expect_multipart_response();
-  client()->set_delete_on_receive_data();
-  DoStartAsyncRequest();
-  DoReceiveResponseMultipart();
-  DoReceiveDataMultipart();
-  EXPECT_EQ("bl", client()->received_data());
-}
-
-TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveMoreData) {
-  client()->set_expect_multipart_response();
-  DoStartAsyncRequest();
-  DoReceiveResponseMultipart();
-  DoReceiveDataMultipart();
-  // For multipart responses, the delegate may send some data when notified
-  // of a request completing.
-  client()->set_delete_on_receive_data();
-  peer()->OnCompletedRequest(net::OK, false, false, "", base::TimeTicks(),
-                              strlen(kTestData));
-  EXPECT_FALSE(client()->did_finish());
-  EXPECT_EQ(kTestData, client()->received_data());
-}
-
-TEST_F(WebURLLoaderImplTest, MultipartDeleteFinish) {
-  client()->set_expect_multipart_response();
-  client()->set_delete_on_finish();
-  DoStartAsyncRequest();
-  DoReceiveResponseMultipart();
-  DoReceiveDataMultipart();
-  DoCompleteRequest();
-  EXPECT_EQ(kTestData, client()->received_data());
-}
-
-TEST_F(WebURLLoaderImplTest, MultipartDeleteFail) {
-  client()->set_expect_multipart_response();
-  client()->set_delete_on_fail();
-  DoStartAsyncRequest();
-  DoReceiveResponseMultipart();
-  DoReceiveDataMultipart();
-  DoFailRequest();
-}
-
 // PlzNavigate: checks that the stream override parameters provided on
 // navigation commit are properly applied.
 TEST_F(WebURLLoaderImplTest, BrowserSideNavigationCommit) {
diff --git a/content/common/content_param_traits_macros.h b/content/common/content_param_traits_macros.h
index 36df5fb..94cde2f 100644
--- a/content/common/content_param_traits_macros.h
+++ b/content/common/content_param_traits_macros.h
@@ -34,7 +34,7 @@
                           content::REQUEST_CONTEXT_FRAME_TYPE_LAST)
 IPC_ENUM_TRAITS_MAX_VALUE(blink::WebContentSecurityPolicyType,
                           blink::WebContentSecurityPolicyTypeLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebAddressSpace, blink::WebAddressSpaceLast);
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebAddressSpace, blink::WebAddressSpaceLast)
 IPC_ENUM_TRAITS_MAX_VALUE(blink::WebSharedWorkerCreationContextType,
                           blink::WebSharedWorkerCreationContextTypeLast)
 IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebInputEvent::Type,
diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc
index 7f4a132..12ceaf7 100644
--- a/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc
+++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface_unittest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
-#include "content/test/gpu_memory_buffer_factory_test_template.h"
+#include "content/common/gpu/gpu_memory_buffer_factory_test_template.h"
 
 namespace content {
 namespace {
diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc
index bdb9747..904f93e 100644
--- a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc
+++ b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap_unittest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h"
-#include "content/test/gpu_memory_buffer_factory_test_template.h"
+#include "content/common/gpu/gpu_memory_buffer_factory_test_template.h"
 
 namespace content {
 namespace {
diff --git a/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc b/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc
index 683860fe..85c4d036 100644
--- a/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc
+++ b/content/common/gpu/gpu_memory_buffer_factory_surface_texture_unittest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h"
-#include "content/test/gpu_memory_buffer_factory_test_template.h"
+#include "content/common/gpu/gpu_memory_buffer_factory_test_template.h"
 
 namespace content {
 namespace {
diff --git a/content/test/gpu_memory_buffer_factory_test_template.h b/content/common/gpu/gpu_memory_buffer_factory_test_template.h
similarity index 93%
rename from content/test/gpu_memory_buffer_factory_test_template.h
rename to content/common/gpu/gpu_memory_buffer_factory_test_template.h
index f0d90558..9f88384 100644
--- a/content/test/gpu_memory_buffer_factory_test_template.h
+++ b/content/common/gpu/gpu_memory_buffer_factory_test_template.h
@@ -5,8 +5,8 @@
 // This file defines tests that implementations of GpuMemoryBufferFactory should
 // pass in order to be conformant.
 
-#ifndef CONTENT_TEST_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_
-#define CONTENT_TEST_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_
+#ifndef CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_
+#define CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_
 
 #include "content/common/gpu/gpu_memory_buffer_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -95,4 +95,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_TEST_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_
+#endif  // CONTENT_COMMON_GPU_GPU_MEMORY_BUFFER_FACTORY_TEST_TEMPLATE_H_
diff --git a/content/common/p2p_messages.h b/content/common/p2p_messages.h
index 24daee5..c0ae470 100644
--- a/content/common/p2p_messages.h
+++ b/content/common/p2p_messages.h
@@ -11,6 +11,7 @@
 #include "content/common/content_export.h"
 #include "content/common/p2p_socket_type.h"
 #include "ipc/ipc_message_macros.h"
+#include "net/base/ip_address.h"
 #include "net/base/network_interfaces.h"
 #include "third_party/webrtc/base/asyncpacketsocket.h"
 
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h
index c6ccfefb..d2f1e64 100644
--- a/content/common/service_worker/service_worker_messages.h
+++ b/content/common/service_worker/service_worker_messages.h
@@ -55,6 +55,11 @@
 IPC_ENUM_TRAITS_MAX_VALUE(content::ServiceWorkerFetchType,
                           content::ServiceWorkerFetchType::LAST)
 
+IPC_STRUCT_TRAITS_BEGIN(content::ExtendableMessageEventSource)
+  IPC_STRUCT_TRAITS_MEMBER(client_info)
+  IPC_STRUCT_TRAITS_MEMBER(service_worker_info)
+IPC_STRUCT_TRAITS_END()
+
 IPC_STRUCT_TRAITS_BEGIN(content::ServiceWorkerFetchRequest)
   IPC_STRUCT_TRAITS_MEMBER(mode)
   IPC_STRUCT_TRAITS_MEMBER(is_main_resource_load)
@@ -122,6 +127,14 @@
   IPC_STRUCT_TRAITS_MEMBER(include_uncontrolled)
 IPC_STRUCT_TRAITS_END()
 
+IPC_STRUCT_BEGIN(ServiceWorkerMsg_ExtendableMessageEvent_Params)
+  IPC_STRUCT_MEMBER(base::string16, message)
+  IPC_STRUCT_MEMBER(url::Origin, source_origin)
+  IPC_STRUCT_MEMBER(std::vector<content::TransferredMessagePort>, message_ports)
+  IPC_STRUCT_MEMBER(std::vector<int>, new_routing_ids)
+  IPC_STRUCT_MEMBER(content::ExtendableMessageEventSource, source)
+IPC_STRUCT_END()
+
 IPC_STRUCT_BEGIN(ServiceWorkerMsg_MessageToDocument_Params)
   IPC_STRUCT_MEMBER(int, thread_id)
   IPC_STRUCT_MEMBER(int, provider_id)
@@ -184,10 +197,12 @@
                      int /* provider_id */)
 
 // Sends ExtendableMessageEvent to a service worker (renderer->browser).
-IPC_MESSAGE_CONTROL3(
+IPC_MESSAGE_CONTROL5(
     ServiceWorkerHostMsg_PostMessageToWorker,
     int /* handle_id */,
+    int /* provider_id */,
     base::string16 /* message */,
+    url::Origin /* source_origin */,
     std::vector<content::TransferredMessagePort> /* sent_message_ports */)
 
 // Sends MessageEvent to a service worker (renderer->browser).
@@ -468,12 +483,9 @@
                      int /* request_id */)
 IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_ActivateEvent,
                      int /* request_id */)
-IPC_MESSAGE_CONTROL4(
-    ServiceWorkerMsg_ExtendableMessageEvent,
-    int /* request_id */,
-    base::string16 /* message */,
-    std::vector<content::TransferredMessagePort> /* sent_message_ports */,
-    std::vector<int> /* new_routing_ids */)
+IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_ExtendableMessageEvent,
+                     int /* request_id */,
+                     ServiceWorkerMsg_ExtendableMessageEvent_Params)
 IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_FetchEvent,
                      int /* request_id */,
                      content::ServiceWorkerFetchRequest)
diff --git a/content/common/service_worker/service_worker_types.cc b/content/common/service_worker/service_worker_types.cc
index 93af174..c3f9ec6d 100644
--- a/content/common/service_worker/service_worker_types.cc
+++ b/content/common/service_worker/service_worker_types.cc
@@ -94,6 +94,11 @@
       state(blink::WebServiceWorkerStateUnknown),
       version_id(kInvalidServiceWorkerVersionId) {}
 
+bool ServiceWorkerObjectInfo::IsValid() const {
+  return handle_id != kInvalidServiceWorkerHandleId &&
+         version_id != kInvalidServiceWorkerVersionId;
+}
+
 ServiceWorkerRegistrationObjectInfo::ServiceWorkerRegistrationObjectInfo()
     : handle_id(kInvalidServiceWorkerRegistrationHandleId),
       registration_id(kInvalidServiceWorkerRegistrationId) {
@@ -104,4 +109,14 @@
       include_uncontrolled(false) {
 }
 
+ExtendableMessageEventSource::ExtendableMessageEventSource() {}
+
+ExtendableMessageEventSource::ExtendableMessageEventSource(
+    const ServiceWorkerClientInfo& client_info)
+    : client_info(client_info) {}
+
+ExtendableMessageEventSource::ExtendableMessageEventSource(
+    const ServiceWorkerObjectInfo& service_worker_info)
+    : service_worker_info(service_worker_info) {}
+
 }  // namespace content
diff --git a/content/common/service_worker/service_worker_types.h b/content/common/service_worker/service_worker_types.h
index b4d49b23..52d1e42 100644
--- a/content/common/service_worker/service_worker_types.h
+++ b/content/common/service_worker/service_worker_types.h
@@ -13,6 +13,7 @@
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "content/common/content_export.h"
+#include "content/common/service_worker/service_worker_client_info.h"
 #include "content/public/common/referrer.h"
 #include "content/public/common/request_context_frame_type.h"
 #include "content/public/common/request_context_type.h"
@@ -181,6 +182,11 @@
 // Represents initialization info for a WebServiceWorker object.
 struct CONTENT_EXPORT ServiceWorkerObjectInfo {
   ServiceWorkerObjectInfo();
+
+  // Returns whether the instance is valid. A valid instance has valid
+  // |handle_id| and |version_id|.
+  bool IsValid() const;
+
   int handle_id;
   GURL url;
   blink::WebServiceWorkerState state;
@@ -230,6 +236,18 @@
   bool include_uncontrolled;
 };
 
+struct ExtendableMessageEventSource {
+  ExtendableMessageEventSource();
+  explicit ExtendableMessageEventSource(
+      const ServiceWorkerClientInfo& client_info);
+  explicit ExtendableMessageEventSource(
+      const ServiceWorkerObjectInfo& service_worker_info);
+
+  // Exactly one of these infos should be valid.
+  ServiceWorkerClientInfo client_info;
+  ServiceWorkerObjectInfo service_worker_info;
+};
+
 }  // namespace content
 
 #endif  // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_H_
diff --git a/content/content_child.gypi b/content/content_child.gypi
index 9fb7380..566a539 100644
--- a/content/content_child.gypi
+++ b/content/content_child.gypi
@@ -134,8 +134,6 @@
       'child/mojo/mojo_application.cc',
       'child/mojo/mojo_application.h',
       'child/mojo/type_converters.h',
-      'child/multipart_response_delegate.cc',
-      'child/multipart_response_delegate.h',
       'child/navigator_connect/service_port_dispatcher_impl.cc',
       'child/navigator_connect/service_port_dispatcher_impl.h',
       'child/navigator_connect/service_port_provider.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index a6c21b5c..3f2ff07 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -22,6 +22,7 @@
       'browser/geolocation/mock_location_arbitrator.h',
       'browser/geolocation/mock_location_provider.cc',
       'browser/geolocation/mock_location_provider.h',
+      'common/gpu/gpu_memory_buffer_factory_test_template.h',
       'public/test/async_file_test_helper.cc',
       'public/test/async_file_test_helper.h',
       'public/test/background_sync_test_util.cc',
@@ -117,7 +118,6 @@
       'test/fake_plugin_service.h',
       'test/fake_renderer_scheduler.cc',
       'test/fake_renderer_scheduler.h',
-      'test/gpu_memory_buffer_factory_test_template.h',
       'test/mock_background_sync_controller.cc',
       'test/mock_background_sync_controller.h',
       'test/mock_google_streaming_server.cc',
@@ -637,7 +637,6 @@
       'child/indexed_db/mock_webidbcallbacks.cc',
       'child/indexed_db/mock_webidbcallbacks.h',
       'child/indexed_db/webidbcursor_impl_unittest.cc',
-      'child/multipart_response_delegate_unittest.cc',
       'child/notifications/notification_data_conversions_unittest.cc',
       'child/notifications/pending_notifications_tracker_unittest.cc',
       'child/power_monitor_broadcast_source_unittest.cc',
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index e74e49d..4a50997 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -37,6 +37,7 @@
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
 import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.animation.AnimationUtils;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
@@ -57,11 +58,13 @@
 import org.chromium.content.browser.accessibility.captioning.CaptioningBridgeFactory;
 import org.chromium.content.browser.accessibility.captioning.SystemCaptioningBridge;
 import org.chromium.content.browser.accessibility.captioning.TextTrackSettings;
+import org.chromium.content.browser.input.AnimationIntervalProvider;
 import org.chromium.content.browser.input.FloatingPastePopupMenu;
 import org.chromium.content.browser.input.GamepadList;
 import org.chromium.content.browser.input.ImeAdapter;
 import org.chromium.content.browser.input.InputMethodManagerWrapper;
 import org.chromium.content.browser.input.JoystickScrollProvider;
+import org.chromium.content.browser.input.JoystickZoomProvider;
 import org.chromium.content.browser.input.LegacyPastePopupMenu;
 import org.chromium.content.browser.input.PastePopupMenu;
 import org.chromium.content.browser.input.PastePopupMenu.PastePopupMenuDelegate;
@@ -349,6 +352,16 @@
     }
 
     /**
+     * Returns interval between consecutive animation frames.
+     */
+    private static class SystemAnimationIntervalProvider implements AnimationIntervalProvider {
+        @Override
+        public long getLastAnimationFrameInterval() {
+            return AnimationUtils.currentAnimationTimeMillis();
+        }
+    }
+
+    /**
      * Interface that consumers of {@link ContentViewCore} must implement to allow the proper
      * dispatching of view methods through the containing view.
      *
@@ -472,6 +485,9 @@
     // Provides smooth gamepad joystick-driven scrolling.
     private final JoystickScrollProvider mJoystickScrollProvider;
 
+    // Provides smooth gamepad joystick-driven zooming.
+    private JoystickZoomProvider mJoystickZoomProvider;
+
     private boolean mIsMobileOptimizedHint;
 
     // Tracks whether a selection is currently active.  When applied to selected text, indicates
@@ -1720,6 +1736,11 @@
             }
         } else if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
             if (mJoystickScrollProvider.onMotion(event)) return true;
+            if (mJoystickZoomProvider == null) {
+                mJoystickZoomProvider =
+                        new JoystickZoomProvider(this, new SystemAnimationIntervalProvider());
+            }
+            if (mJoystickZoomProvider.onMotion(event)) return true;
         }
         return mContainerViewInternals.super_onGenericMotionEvent(event);
     }
@@ -2317,7 +2338,10 @@
             float contentWidth, float contentHeight,
             float viewportWidth, float viewportHeight,
             float controlsOffsetYCss, float contentOffsetYCss,
-            boolean isMobileOptimizedHint) {
+            boolean isMobileOptimizedHint,
+            boolean hasInsertionMarker, boolean isInsertionMarkerVisible,
+            float insertionMarkerHorizontal, float insertionMarkerTop,
+            float insertionMarkerBottom) {
         TraceEvent.begin("ContentViewCore:updateFrameInfo");
         mIsMobileOptimizedHint = isMobileOptimizedHint;
         // Adjust contentWidth/Height to be always at least as big as
@@ -2384,6 +2408,11 @@
         if (mBrowserAccessibilityManager != null) {
             mBrowserAccessibilityManager.notifyFrameInfoInitialized();
         }
+
+        mImeAdapter.onUpdateFrameInfo(mRenderCoordinates, hasInsertionMarker,
+                isInsertionMarkerVisible, insertionMarkerHorizontal, insertionMarkerTop,
+                insertionMarkerBottom);
+
         TraceEvent.end("ContentViewCore:updateFrameInfo");
     }
 
@@ -2729,6 +2758,44 @@
     }
 
     /**
+     * Send start of pinch zoom gesture.
+     *
+     * @param xPix X-coordinate of location from which pinch zoom would start.
+     * @param yPix Y-coordinate of location from which pinch zoom would start.
+     * @return whether the pinch zoom start gesture was sent.
+     */
+    public boolean pinchBegin(int xPix, int yPix) {
+        if (mNativeContentViewCore == 0) return false;
+        nativePinchBegin(mNativeContentViewCore, SystemClock.uptimeMillis(), xPix, yPix);
+        return true;
+    }
+
+    /**
+     * Send pinch zoom gesture.
+     *
+     * @param xPix X-coordinate of pinch zoom location.
+     * @param yPix Y-coordinate of pinch zoom location.
+     * @param delta the factor by which the current page scale should be multiplied by.
+     * @return whether the pinchby gesture was sent.
+     */
+    public boolean pinchBy(int xPix, int yPix, float delta) {
+        if (mNativeContentViewCore == 0) return false;
+        nativePinchBy(mNativeContentViewCore, SystemClock.uptimeMillis(), xPix, yPix, delta);
+        return true;
+    }
+
+    /**
+     * Stop pinch zoom gesture.
+     *
+     * @return whether the pinch stop gesture was sent.
+     */
+    public boolean pinchEnd() {
+        if (mNativeContentViewCore == 0) return false;
+        nativePinchEnd(mNativeContentViewCore, SystemClock.uptimeMillis());
+        return true;
+    }
+
+    /**
      * Invokes the graphical zoom picker widget for this ContentView.
      */
     public void invokeZoomPicker() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
index 89faf91..c56660c 100644
--- a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
+++ b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
@@ -4,6 +4,8 @@
 
 package org.chromium.content.browser;
 
+import org.chromium.base.VisibleForTesting;
+
 /**
  * Cached copy of all positions and scales (CSS-to-DIP-to-physical pixels)
  * reported from the renderer.
@@ -75,6 +77,18 @@
     }
 
     /**
+     * Sets several fields for unit test. (used by {@link CursorAnchorInfoControllerTest}).
+     * @param deviceScaleFactor Device scale factor (maps DIP pixels to physical pixels).
+     * @param contentOffsetYPix Physical on-screen Y offset amount below the top controls.
+     */
+    @VisibleForTesting
+    public void setFrameInfoForTest(float deviceScaleFactor, float contentOffsetYPix) {
+        reset();
+        mDeviceScaleFactor = deviceScaleFactor;
+        mContentOffsetYPix = contentOffsetYPix;
+    }
+
+    /**
      * Handles conversion of a point from window-relative-local-dip or screen-pix
      * to document-absolute-CSS space and vice versa.
      */
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/AnimationIntervalProvider.java b/content/public/android/java/src/org/chromium/content/browser/input/AnimationIntervalProvider.java
new file mode 100644
index 0000000..df9a692
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/AnimationIntervalProvider.java
@@ -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.
+
+package org.chromium.content.browser.input;
+
+/**
+ * This is an interface which provides last animation interval.
+ */
+public interface AnimationIntervalProvider {
+    /**
+     * Returns last animation interval.
+     */
+    public long getLastAnimationFrameInterval();
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java b/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java
new file mode 100644
index 0000000..443e7d2
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java
@@ -0,0 +1,280 @@
+// 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.content.browser.input;
+
+import android.annotation.TargetApi;
+import android.graphics.Matrix;
+import android.os.Build;
+import android.view.View;
+import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.InputConnection;
+
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.content.browser.RenderCoordinates;
+
+import java.util.Arrays;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * A state machine interface which receives Chromium internal events to determines when to call
+ * {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)}. This interface is
+ * also used in unit tests to mock out {@link CursorAnchorInfo}, which is available only in
+ * Android 5.0 (Lollipop) and later.
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+final class CursorAnchorInfoController {
+    /**
+     * An interface to mock out {@link View#getLocationOnScreen(int[])} for testing.
+     */
+    public interface ViewDelegate {
+        void getLocationOnScreen(View view, int[] location);
+    }
+
+    /**
+     * An interface to mock out composing text retrieval from ImeAdapter.
+     */
+    public interface ComposingTextDelegate {
+        CharSequence getText();
+        int getSelectionStart();
+        int getSelectionEnd();
+        int getComposingTextStart();
+        int getComposingTextEnd();
+    }
+
+    // Current focus and monitoring states.
+    private boolean mIsEditable;
+    private boolean mHasPendingImmediateRequest;
+    private boolean mMonitorModeEnabled;
+
+    // Parmeter for CursorAnchorInfo, updated by setCompositionCharacterBounds.
+    @Nullable
+    private float[] mCompositionCharacterBounds;
+    // Paremeters for CursorAnchorInfo, updated by onUpdateFrameInfo.
+    private boolean mHasCoordinateInfo;
+    private float mScale;
+    private float mTranslationX;
+    private float mTranslationY;
+    private boolean mHasInsertionMarker;
+    private boolean mIsInsertionMarkerVisible;
+    private float mInsertionMarkerHorizontal;
+    private float mInsertionMarkerTop;
+    private float mInsertionMarkerBottom;
+
+    @Nullable
+    private CursorAnchorInfo mLastCursorAnchorInfo;
+
+    @Nonnull
+    private final Matrix mMatrix = new Matrix();
+    @Nonnull
+    private final int[] mViewOrigin = new int[2];
+    @Nonnull
+    private final CursorAnchorInfo.Builder mCursorAnchorInfoBuilder =
+            new CursorAnchorInfo.Builder();
+
+    @Nullable
+    private InputMethodManagerWrapper mInputMethodManagerWrapper;
+    @Nullable
+    private final ComposingTextDelegate mComposingTextDelegate;
+    @Nonnull
+    private final ViewDelegate mViewDelegate;
+
+    private CursorAnchorInfoController(InputMethodManagerWrapper inputMethodManagerWrapper,
+            ComposingTextDelegate composingTextDelegate, ViewDelegate viewDelegate) {
+        mInputMethodManagerWrapper = inputMethodManagerWrapper;
+        mComposingTextDelegate = composingTextDelegate;
+        mViewDelegate = viewDelegate;
+    }
+
+    public static CursorAnchorInfoController create(
+            InputMethodManagerWrapper inputMethodManagerWrapper,
+            ComposingTextDelegate composingTextDelegate) {
+        return new CursorAnchorInfoController(inputMethodManagerWrapper,
+                composingTextDelegate, new ViewDelegate() {
+                    @Override
+                    public void getLocationOnScreen(View view, int[] location) {
+                        view.getLocationOnScreen(location);
+                    }
+                });
+    }
+
+    @VisibleForTesting
+    public void setInputMethodManagerWrapperForTest(
+            InputMethodManagerWrapper inputMethodManagerWrapper) {
+        mInputMethodManagerWrapper = inputMethodManagerWrapper;
+    }
+
+    @VisibleForTesting
+    public static CursorAnchorInfoController createForTest(
+            InputMethodManagerWrapper inputMethodManagerWrapper,
+            ComposingTextDelegate composingTextDelegate,
+            ViewDelegate viewDelegate) {
+        return new CursorAnchorInfoController(inputMethodManagerWrapper, composingTextDelegate,
+                viewDelegate);
+    }
+
+    /**
+     * Called by ImeAdapter when a IME related web content state is changed.
+     */
+    public void invalidateLastCursorAnchorInfo() {
+        if (!mIsEditable) return;
+
+        mLastCursorAnchorInfo = null;
+    }
+
+    /**
+     * Sets positional information of composing text as an array of character bounds.
+     * @param compositionCharacterBounds Array of character bounds in local coordinates.
+     */
+    public void setCompositionCharacterBounds(float[] compositionCharacterBounds) {
+        if (!mIsEditable) return;
+
+        if (!Arrays.equals(compositionCharacterBounds, mCompositionCharacterBounds)) {
+            mLastCursorAnchorInfo = null;
+            mCompositionCharacterBounds = compositionCharacterBounds;
+        }
+    }
+
+    /**
+     * Sets coordinates system parameters and selection marker information.
+     * @param hasInsertionMarker {@code true} if the insertion marker exists.
+     * @param isInsertionMarkerVisible {@code true} if the insertion insertion marker is visible.
+     * @param insertionMarkerHorizontal X coordinate of the top of the first selection marker.
+     * @param insertionMarkerTop Y coordinate of the top of the first selection marker.
+     * @param insertionMarkerBottom Y coordinate of the bottom of the first selection marker.
+     * @param view The attached view.
+     */
+    @SuppressFBWarnings("FE_FLOATING_POINT_EQUALITY")
+    public void onUpdateFrameInfo(@Nonnull RenderCoordinates renderCoordinates,
+            boolean hasInsertionMarker, boolean isInsertionMarkerVisible,
+            float insertionMarkerHorizontal, float insertionMarkerTop,
+            float insertionMarkerBottom, @Nonnull View view) {
+        if (!mIsEditable) return;
+
+        // Reuse {@param #mViewOrigin} to avoid object creation, as this method is supposed to be
+        // called at relatively high rate.
+        mViewDelegate.getLocationOnScreen(view, mViewOrigin);
+
+        // Character bounds and insertion marker locations come in device independent pixels
+        // relative from the top-left corner of the web view content area. (In other words, the
+        // effects of various kinds of zooming and scrolling are already taken into account.)
+        //
+        // We need to prepare parameters that convert such values to physical pixels, in the
+        // screen coordinate. Hence the following values are derived.
+        float scale = renderCoordinates.getDeviceScaleFactor();
+        float translationX = mViewOrigin[0];
+        float translationY = mViewOrigin[1] + renderCoordinates.getContentOffsetYPix();
+
+        if (!mHasCoordinateInfo
+                || scale != mScale
+                || translationX != mTranslationX
+                || translationY != mTranslationY
+                || hasInsertionMarker != mHasInsertionMarker
+                || isInsertionMarkerVisible != mIsInsertionMarkerVisible
+                || insertionMarkerHorizontal != mInsertionMarkerHorizontal
+                || insertionMarkerTop != mInsertionMarkerTop
+                || insertionMarkerBottom != mInsertionMarkerBottom) {
+            mLastCursorAnchorInfo = null;
+            mHasCoordinateInfo = true;
+            mScale = scale;
+            mTranslationX = translationX;
+            mTranslationY = translationY;
+            mHasInsertionMarker = hasInsertionMarker;
+            mIsInsertionMarkerVisible = isInsertionMarkerVisible;
+            mInsertionMarkerHorizontal = insertionMarkerHorizontal;
+            mInsertionMarkerTop = insertionMarkerTop;
+            mInsertionMarkerBottom = insertionMarkerBottom;
+        }
+
+        // Notify to IME if there is a pending request, or if it is in monitor mode and we have
+        // some change in the state.
+        if (mHasPendingImmediateRequest
+                || (mMonitorModeEnabled && mLastCursorAnchorInfo == null)) {
+            updateCursorAnchorInfo(view);
+        }
+    }
+
+    /**
+     * Resets the current state on update monitoring mode to the default (= do nothing.)
+     */
+    public void resetMonitoringState() {
+        mMonitorModeEnabled = false;
+        mHasPendingImmediateRequest = false;
+    }
+
+    public void focusedNodeChanged(boolean isEditable) {
+        mIsEditable = isEditable;
+        mCompositionCharacterBounds = null;
+        mHasCoordinateInfo = false;
+        mLastCursorAnchorInfo = null;
+    }
+
+    public boolean onRequestCursorUpdates(int cursorUpdateMode, View view) {
+        if (!mIsEditable) return false;
+
+        mMonitorModeEnabled = (cursorUpdateMode & InputConnection.CURSOR_UPDATE_MONITOR) != 0;
+        if ((cursorUpdateMode & InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0) {
+            mHasPendingImmediateRequest = true;
+            updateCursorAnchorInfo(view);
+        }
+        return true;
+    }
+
+    /**
+     * Computes the CursorAnchorInfo instance and notify to InputMethodManager if needed.
+     */
+    private void updateCursorAnchorInfo(View view) {
+        if (!mHasCoordinateInfo) return;
+
+        if (mLastCursorAnchorInfo == null) {
+            // Reuse the builder object.
+            mCursorAnchorInfoBuilder.reset();
+
+            CharSequence text = mComposingTextDelegate.getText();
+            int selectionStart = mComposingTextDelegate.getSelectionStart();
+            int selectionEnd = mComposingTextDelegate.getSelectionEnd();
+            int composingTextStart = mComposingTextDelegate.getComposingTextStart();
+            int composingTextEnd = mComposingTextDelegate.getComposingTextEnd();
+            if (text != null && 0 <= composingTextStart && composingTextEnd <= text.length()) {
+                mCursorAnchorInfoBuilder.setComposingText(composingTextStart,
+                        text.subSequence(composingTextStart, composingTextEnd));
+                float[] compositionCharacterBounds = mCompositionCharacterBounds;
+                if (compositionCharacterBounds != null) {
+                    int numCharacter = compositionCharacterBounds.length / 4;
+                    for (int i = 0; i < numCharacter; ++i) {
+                        float left = compositionCharacterBounds[i * 4];
+                        float top = compositionCharacterBounds[i * 4 + 1];
+                        float right = compositionCharacterBounds[i * 4 + 2];
+                        float bottom = compositionCharacterBounds[i * 4 + 3];
+                        int charIndex = composingTextStart + i;
+                        mCursorAnchorInfoBuilder.addCharacterBounds(charIndex, left, top, right,
+                                bottom, CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION);
+                    }
+                }
+            }
+            mCursorAnchorInfoBuilder.setSelectionRange(selectionStart, selectionEnd);
+            mMatrix.setScale(mScale, mScale);
+            mMatrix.postTranslate(mTranslationX, mTranslationY);
+            mCursorAnchorInfoBuilder.setMatrix(mMatrix);
+            if (mHasInsertionMarker) {
+                mCursorAnchorInfoBuilder.setInsertionMarkerLocation(
+                        mInsertionMarkerHorizontal,
+                        mInsertionMarkerTop,
+                        mInsertionMarkerBottom,
+                        mInsertionMarkerBottom,
+                        mIsInsertionMarkerVisible ? CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION :
+                                CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION);
+            }
+            mLastCursorAnchorInfo = mCursorAnchorInfoBuilder.build();
+        }
+
+        if (mInputMethodManagerWrapper != null) {
+            mInputMethodManagerWrapper.updateCursorAnchorInfo(view, mLastCursorAnchorInfo);
+        }
+        mHasPendingImmediateRequest = false;
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
index a1bf5125..f00e7708 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
@@ -5,6 +5,7 @@
 package org.chromium.content.browser.input;
 
 import android.content.res.Configuration;
+import android.os.Build;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.text.SpannableString;
@@ -24,6 +25,7 @@
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.blink_public.web.WebInputEventModifier;
 import org.chromium.blink_public.web.WebInputEventType;
+import org.chromium.content.browser.RenderCoordinates;
 import org.chromium.ui.base.ime.TextInputType;
 import org.chromium.ui.picker.InputDialogContainer;
 
@@ -94,6 +96,11 @@
     private ChromiumBaseInputConnection.Factory mInputConnectionFactory;
 
     private final ImeAdapterDelegate mViewEmbedder;
+    // This holds the information necessary for constructing CursorAnchorInfo, and notifies to
+    // InputMethodManager on appropriate timing, depending on how IME requested the information
+    // via InputConnection. The update request is per InputConnection, hence for each time it is
+    // re-created, the monitoring status will be reset.
+    private final CursorAnchorInfoController mCursorAnchorInfoController;
 
     private int mTextInputType = TextInputType.NONE;
     private int mTextInputFlags;
@@ -103,6 +110,9 @@
 
     private int mLastSelectionStart;
     private int mLastSelectionEnd;
+    private String mLastText;
+    private int mLastCompositionStart;
+    private int mLastCompositionEnd;
 
     /**
      * @param wrapper InputMethodManagerWrapper that should receive all the call directed to
@@ -116,6 +126,34 @@
         // Deep copy newConfig so that we can notice the difference.
         mCurrentConfig = new Configuration(
                 mViewEmbedder.getAttachedView().getResources().getConfiguration());
+        // CursorAnchroInfo is supported only after L.
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            mCursorAnchorInfoController = CursorAnchorInfoController.create(wrapper,
+                    new CursorAnchorInfoController.ComposingTextDelegate() {
+                        @Override
+                        public CharSequence getText() {
+                            return mLastText;
+                        }
+                        @Override
+                        public int getSelectionStart() {
+                            return mLastSelectionStart;
+                        }
+                        @Override
+                        public int getSelectionEnd() {
+                            return mLastSelectionEnd;
+                        }
+                        @Override
+                        public int getComposingTextStart() {
+                            return mLastCompositionStart;
+                        }
+                        @Override
+                        public int getComposingTextEnd() {
+                            return mLastCompositionEnd;
+                        }
+                    });
+        } else {
+            mCursorAnchorInfoController = null;
+        }
     }
 
     private boolean isImeThreadEnabled() {
@@ -155,6 +193,9 @@
                 mViewEmbedder.getAttachedView(), this, mTextInputType, mTextInputFlags,
                 mLastSelectionStart, mLastSelectionEnd, outAttrs);
         if (DEBUG_LOGS) Log.w(TAG, "onCreateInputConnection: " + mInputConnection);
+        if (mCursorAnchorInfoController != null) {
+            mCursorAnchorInfoController.resetMonitoringState();
+        }
         return mInputConnection;
     }
 
@@ -166,6 +207,9 @@
     @VisibleForTesting
     public void setInputMethodManagerWrapperForTest(InputMethodManagerWrapper immw) {
         mInputMethodManagerWrapper = immw;
+        if (mCursorAnchorInfoController != null) {
+            mCursorAnchorInfoController.setInputMethodManagerWrapperForTest(immw);
+        }
     }
 
     @VisibleForTesting
@@ -251,8 +295,18 @@
      */
     public void updateState(String text, int selectionStart, int selectionEnd, int compositionStart,
             int compositionEnd, boolean isNonImeChange) {
+        if (mCursorAnchorInfoController != null && (!TextUtils.equals(mLastText, text)
+                || mLastSelectionStart != selectionStart || mLastSelectionEnd != selectionEnd
+                || mLastCompositionStart != compositionStart
+                || mLastCompositionEnd != compositionEnd)) {
+            mCursorAnchorInfoController.invalidateLastCursorAnchorInfo();
+        }
+        mLastText = text;
         mLastSelectionStart = selectionStart;
         mLastSelectionEnd = selectionEnd;
+        mLastCompositionStart = compositionStart;
+        mLastCompositionEnd = compositionEnd;
+
         if (mInputConnection == null) return;
         boolean singleLine = mTextInputType != TextInputType.TEXT_AREA
                 && mTextInputType != TextInputType.CONTENT_EDITABLE;
@@ -549,6 +603,12 @@
     @CalledByNative
     private void focusedNodeChanged(boolean isEditable) {
         if (DEBUG_LOGS) Log.w(TAG, "focusedNodeChanged: isEditable [%b]", isEditable);
+
+        // Update controller before the connection is restarted.
+        if (mCursorAnchorInfoController != null) {
+            mCursorAnchorInfoController.focusedNodeChanged(isEditable);
+        }
+
         if (mTextInputType != TextInputType.NONE && mInputConnection != null && isEditable) {
             restartInput();
         }
@@ -564,6 +624,36 @@
         return nativeRequestTextInputStateUpdate(mNativeImeAdapterAndroid);
     }
 
+    /**
+     * Notified when IME requested Chrome to change the cursor update mode.
+     */
+    public boolean onRequestCursorUpdates(int cursorUpdateMode) {
+        if (mCursorAnchorInfoController == null) return false;
+        return mCursorAnchorInfoController.onRequestCursorUpdates(cursorUpdateMode,
+                mViewEmbedder.getAttachedView());
+    }
+
+    /**
+     * Notified when a frame has been produced by the renderer and all the associated metadata.
+     * @param renderCoordinates coordinate information to convert CSS (document) coordinates to
+     *                          View-local Physical (screen) coordinates
+     * @param hasInsertionMarker Whether the insertion marker is visible or not.
+     * @param insertionMarkerHorizontal X coordinates (in view-local DIP pixels) of the insertion
+     *                                  marker if it exists. Will be ignored otherwise.
+     * @param insertionMarkerTop Y coordinates (in view-local DIP pixels) of the top of the
+     *                           insertion marker if it exists. Will be ignored otherwise.
+     * @param insertionMarkerBottom Y coordinates (in view-local DIP pixels) of the bottom of
+     *                              the insertion marker if it exists. Will be ignored otherwise.
+     */
+    public void onUpdateFrameInfo(RenderCoordinates renderCoordinates, boolean hasInsertionMarker,
+            boolean isInsertionMarkerVisible, float insertionMarkerHorizontal,
+            float insertionMarkerTop, float insertionMarkerBottom) {
+        if (mCursorAnchorInfoController == null) return;
+        mCursorAnchorInfoController.onUpdateFrameInfo(renderCoordinates, hasInsertionMarker,
+                isInsertionMarkerVisible, insertionMarkerHorizontal, insertionMarkerTop,
+                insertionMarkerBottom, mViewEmbedder.getAttachedView());
+    }
+
     @CalledByNative
     private void populateUnderlinesFromSpans(CharSequence text, long underlines) {
         if (DEBUG_LOGS) {
@@ -593,9 +683,18 @@
     }
 
     @CalledByNative
+    private void setCharacterBounds(float[] characterBounds) {
+        if (mCursorAnchorInfoController == null) return;
+        mCursorAnchorInfoController.setCompositionCharacterBounds(characterBounds);
+    }
+
+    @CalledByNative
     private void detach() {
         if (DEBUG_LOGS) Log.w(TAG, "detach");
         mNativeImeAdapterAndroid = 0;
+        if (mCursorAnchorInfoController != null) {
+            mCursorAnchorInfoController.focusedNodeChanged(false);
+        }
     }
 
     private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndroid,
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/JoystickZoomProvider.java b/content/public/android/java/src/org/chromium/content/browser/input/JoystickZoomProvider.java
new file mode 100644
index 0000000..489eb245
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/JoystickZoomProvider.java
@@ -0,0 +1,131 @@
+// 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.content.browser.input;
+
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import org.chromium.content.browser.ContentViewCore;
+
+/**
+ * This class controls page zoomin/out using trigger joystick events.
+ * Page Zoomin is proportional to RTRIGGER axis movement.
+ * Page Zoomout is proportional to LTRIGGER axis movement.
+ */
+public class JoystickZoomProvider {
+    private static final String TAG = "JoystickZoomProvider";
+
+    private static final float JOYSTICK_NOISE_THRESHOLD = 0.2f;
+
+    private static final float ZOOM_SPEED = 1.65f;
+
+    private long mLastAnimateTimeMillis;
+
+    private float mZoomInVelocity;
+
+    private float mZoomOutVelocity;
+
+    protected final ContentViewCore mContentViewCore;
+
+    protected float mDeviceScaleFactor;
+
+    private int mZoomXcoord;
+
+    private int mZoomYcoord;
+
+    protected Runnable mZoomRunnable;
+
+    private AnimationIntervalProvider mSystemAnimationIntervalProvider;
+
+    /**
+     * Constructs a new JoystickZoomProvider.
+     *
+     * @param cvc The ContentViewCore used to create this.
+     */
+    public JoystickZoomProvider(
+            ContentViewCore cvc, AnimationIntervalProvider animationTimeProvider) {
+        mContentViewCore = cvc;
+        mDeviceScaleFactor = mContentViewCore.getRenderCoordinates().getDeviceScaleFactor();
+        mZoomXcoord = mContentViewCore.getViewportWidthPix() / 2;
+        mZoomYcoord = mContentViewCore.getViewportHeightPix() / 2;
+        mSystemAnimationIntervalProvider = animationTimeProvider;
+    }
+
+    /**
+     * This function processes motion event and computes new
+     * page scale factor which is proportional to *_TRIGGER axes movement.
+     * It also starts runnable to update current page scale to new page scale.
+     *
+     * @param event Motion event to be processed for zooming.
+     * @return Whether zooming using *_TRIGGER axes is performed or not.
+     */
+    public boolean onMotion(MotionEvent event) {
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0) return false;
+
+        computeNewZoomVelocity(event);
+        if (mZoomInVelocity == 0 && mZoomOutVelocity == 0) {
+            stop();
+            return false;
+        }
+        if (mZoomRunnable == null) {
+            mZoomRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    animateZoom();
+                }
+            };
+        }
+        if (mLastAnimateTimeMillis == 0) {
+            mLastAnimateTimeMillis =
+                    mSystemAnimationIntervalProvider.getLastAnimationFrameInterval();
+            mContentViewCore.getContainerView().postOnAnimation(mZoomRunnable);
+            mContentViewCore.pinchBegin(mZoomXcoord, mZoomYcoord);
+        }
+        return true;
+    }
+
+    protected void stop() {
+        if (mLastAnimateTimeMillis != 0) {
+            mContentViewCore.pinchEnd();
+            mLastAnimateTimeMillis = 0;
+        }
+    }
+
+    private void computeNewZoomVelocity(MotionEvent event) {
+        mZoomInVelocity = getFilteredAxisValue(event, MotionEvent.AXIS_RTRIGGER);
+        mZoomOutVelocity = getFilteredAxisValue(event, MotionEvent.AXIS_LTRIGGER);
+    }
+
+    protected void animateZoom() {
+        if (!mContentViewCore.getContainerView().hasFocus()) {
+            stop();
+            return;
+        }
+        if (mLastAnimateTimeMillis == 0) return;
+
+        final long timeMillis = mSystemAnimationIntervalProvider.getLastAnimationFrameInterval();
+        final long dt = timeMillis - mLastAnimateTimeMillis;
+        final float zoomFactor = (float) Math.pow(
+                ZOOM_SPEED, mDeviceScaleFactor * (mZoomInVelocity - mZoomOutVelocity) * dt / 1000f);
+        mContentViewCore.pinchBy(mZoomXcoord, mZoomYcoord, zoomFactor);
+        mLastAnimateTimeMillis = timeMillis;
+        mContentViewCore.getContainerView().postOnAnimation(mZoomRunnable);
+    }
+
+    /**
+     * This function removes noise from motion events.
+     * Joystick is very senstitive, it produces value (noise) along X/Y directions
+     * even if gamepad button is pressed which is not acceptable.
+     * Returns non-zero value only if event value is above noise threshold.
+     *
+     * @param event Motion event which needs noise processing.
+     * @param axis Joystick axis (whether X_AXIS of Y_AXIS)
+     * @return Processed joystick value.
+     */
+    private float getFilteredAxisValue(MotionEvent event, int axis) {
+        float axisValWithNoise = event.getAxisValue(axis);
+        return (axisValWithNoise > JOYSTICK_NOISE_THRESHOLD) ? axisValWithNoise : 0f;
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ReplicaInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/ReplicaInputConnection.java
index c9804b5c..d62ccc6 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ReplicaInputConnection.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ReplicaInputConnection.java
@@ -4,6 +4,8 @@
 
 package org.chromium.content.browser.input;
 
+import android.annotation.TargetApi;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.text.Editable;
@@ -466,6 +468,15 @@
         return mHandler;
     }
 
+    /**
+     * @see BaseInputConnection#requestCursorUpdates(int)
+     */
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    @Override
+    public boolean requestCursorUpdates(int cursorUpdateMode) {
+        return mImeAdapter.onRequestCursorUpdates(cursorUpdateMode);
+    }
+
     @VisibleForTesting
     static class ImeState {
         public final String text;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java
index bebd6f09d..3728bf3b 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java
@@ -601,9 +601,15 @@
      * @see InputConnection#requestCursorUpdates(int)
      */
     @Override
-    public boolean requestCursorUpdates(int cursorUpdateMode) {
+    public boolean requestCursorUpdates(final int cursorUpdateMode) {
         if (DEBUG_LOGS) Log.w(TAG, "requestCursorUpdates [%x]", cursorUpdateMode);
         assertOnImeThread();
-        return false;
+        ThreadUtils.postOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mImeAdapter.onRequestCursorUpdates(cursorUpdateMode);
+            }
+        });
+        return true;
     }
-}
\ No newline at end of file
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java
new file mode 100644
index 0000000..4e7b2405
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java
@@ -0,0 +1,143 @@
+// 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.content.browser;
+
+import android.os.SystemClock;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content.browser.input.AnimationIntervalProvider;
+import org.chromium.content.browser.input.JoystickZoomProvider;
+import org.chromium.content_shell_apk.ContentShellTestBase;
+
+/**
+ * Tests that ContentView running inside ContentShell can be zoomed using gamepad joystick.
+ */
+public class ContentViewZoomingTest extends ContentShellTestBase {
+    private static final String LARGE_PAGE = UrlUtils.encodeHtmlDataUri("<html><head>"
+            + "<meta name=\"viewport\" content=\"width=device-width, "
+            + "initial-scale=2.0, minimum-scale=2.0, maximum-scale=5.0\" />"
+            + "<style>body { width: 5000px; height: 5000px; }</style></head>"
+            + "<body>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</body>"
+            + "</html>");
+
+    private class TestAnimationIntervalProvider implements AnimationIntervalProvider {
+        private long mAnimationTime;
+        @Override
+        public long getLastAnimationFrameInterval() {
+            mAnimationTime += 16;
+            return mAnimationTime;
+        }
+    }
+
+    private class TestJoystickZoomProvider extends JoystickZoomProvider {
+        TestJoystickZoomProvider(ContentViewCore cvc, AnimationIntervalProvider intervalProvider) {
+            super(cvc, intervalProvider);
+            mDeviceScaleFactor = 2.0f;
+
+            mZoomRunnable = new Runnable() {
+                @Override
+                public void run() {}
+            };
+        }
+
+        public void animateZoomTest(final MotionEvent joystickZoomEvent, final long animationTicks)
+                throws Throwable {
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    onMotion(joystickZoomEvent);
+                    for (int index = 0; index < animationTicks; index++) {
+                        animateZoom();
+                    }
+                    stop();
+                }
+            });
+        }
+    }
+
+    private MotionEvent simulateJoystickEvent(final float delta, final boolean isZoomInRequest) {
+        // Synthesize joystick motion event and send to ContentViewCore.
+        final int axisVal =
+                (isZoomInRequest) ? MotionEvent.AXIS_RTRIGGER : MotionEvent.AXIS_LTRIGGER;
+        MotionEvent.PointerCoords[] cords = new MotionEvent.PointerCoords[1];
+        MotionEvent.PointerProperties[] pPts = new MotionEvent.PointerProperties[1];
+        cords[0] = new MotionEvent.PointerCoords();
+        pPts[0] = new MotionEvent.PointerProperties();
+        cords[0].setAxisValue(axisVal, delta);
+        pPts[0].id = 0;
+        MotionEvent joystickMotionEvent = MotionEvent.obtain((long) 0, SystemClock.uptimeMillis(),
+                MotionEvent.ACTION_MOVE, 1, pPts, cords, 0, 0, 0.01f, 0.01f, 3, 0,
+                InputDevice.SOURCE_CLASS_JOYSTICK, 0);
+        return joystickMotionEvent;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        launchContentShellWithUrl(LARGE_PAGE);
+        waitForActiveShellToBeDoneLoading();
+        assertWaitForPageScaleFactorMatch(2.0f);
+    }
+
+    @SmallTest
+    @Feature({"JoystickZoom"})
+    public void testJoystickZoomIn() throws Throwable {
+        MotionEvent rTriggerEvent;
+        AnimationIntervalProvider intervalProvider = new TestAnimationIntervalProvider();
+        TestJoystickZoomProvider rtJoystickZoomProvider =
+                new TestJoystickZoomProvider(getContentViewCore(), intervalProvider);
+        // Verify page does not zoom-in if trigger motion falls in deadzone.
+        rTriggerEvent = simulateJoystickEvent(0.1f, true);
+        rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 20);
+        assertWaitForPageScaleFactorMatch(2.0f);
+
+        rTriggerEvent = simulateJoystickEvent(0.3f, true);
+        rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 20);
+        assertWaitForPageScaleFactorMatch(2.2018466f);
+
+        rTriggerEvent = simulateJoystickEvent(0.5f, true);
+        rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 40);
+        assertWaitForPageScaleFactorMatch(3.033731f);
+
+        rTriggerEvent = simulateJoystickEvent(0.75f, true);
+        rtJoystickZoomProvider.animateZoomTest(rTriggerEvent, 50);
+        assertWaitForPageScaleFactorMatch(5.0f);
+    }
+
+    @SmallTest
+    @Feature({"JoystickZoom"})
+    public void testJoystickZoomOut() throws Throwable {
+        MotionEvent lTriggerEvent;
+        AnimationIntervalProvider intervalProvider = new TestAnimationIntervalProvider();
+        TestJoystickZoomProvider ltJoystickZoomProvider =
+                new TestJoystickZoomProvider(getContentViewCore(), intervalProvider);
+
+        // Zoom page to max size.
+        lTriggerEvent = simulateJoystickEvent(1.0f, true);
+        ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 60);
+        assertWaitForPageScaleFactorMatch(5.0f);
+
+        // Verify page does not zoom-out if trigger motion falls in deadzone.
+        lTriggerEvent = simulateJoystickEvent(0.1f, false);
+        ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 20);
+        assertWaitForPageScaleFactorMatch(5.0f);
+
+        lTriggerEvent = simulateJoystickEvent(0.3f, false);
+        ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 40);
+        assertWaitForPageScaleFactorMatch(4.125306f);
+
+        lTriggerEvent = simulateJoystickEvent(0.5f, false);
+        ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 50);
+        assertWaitForPageScaleFactorMatch(2.7635581f);
+
+        lTriggerEvent = simulateJoystickEvent(0.75f, false);
+        ltJoystickZoomProvider.animateZoomTest(lTriggerEvent, 60);
+        assertWaitForPageScaleFactorMatch(2.0f);
+    }
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java
new file mode 100644
index 0000000..768b6bbf
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/CursorAnchorInfoControllerTest.java
@@ -0,0 +1,589 @@
+// 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.content.browser.input;
+
+import android.annotation.TargetApi;
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.os.Build;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.InputConnection;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.content.browser.RenderCoordinates;
+import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper;
+
+/**
+ * Test for {@link CursorAnchorInfoController}.
+ */
+@MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class CursorAnchorInfoControllerTest extends InstrumentationTestCase {
+    private static RenderCoordinates createRenderCoordinates(float deviceScaleFactor,
+            float contentOffsetYPix) {
+        RenderCoordinates renderCoordinates = new RenderCoordinates();
+        renderCoordinates.setFrameInfoForTest(deviceScaleFactor, contentOffsetYPix);
+        return renderCoordinates;
+    }
+
+    private static final class TestViewDelegate implements CursorAnchorInfoController.ViewDelegate {
+        public int locationX;
+        public int locationY;
+        @Override
+        public void getLocationOnScreen(View view, int[] location) {
+            location[0] = locationX;
+            location[1] = locationY;
+        }
+    }
+
+    private static final class TestComposingTextDelegate
+            implements CursorAnchorInfoController.ComposingTextDelegate {
+        private String mText;
+        private int mSelectionStart = -1;
+        private int mSelectionEnd = -1;
+        private int mComposingTextStart = -1;
+        private int mComposingTextEnd = -1;
+
+        @Override
+        public CharSequence getText() {
+            return mText;
+        }
+        @Override
+        public int getSelectionStart() {
+            return mSelectionStart;
+        }
+        @Override
+        public int getSelectionEnd() {
+            return mSelectionEnd;
+        }
+        @Override
+        public int getComposingTextStart() {
+            return mComposingTextStart;
+        }
+        @Override
+        public int getComposingTextEnd() {
+            return mComposingTextEnd;
+        }
+
+        public void updateTextAndSelection(CursorAnchorInfoController controller,
+                String text, int compositionStart, int compositionEnd, int selectionStart,
+                int selectionEnd) {
+            mText = text;
+            mSelectionStart = selectionStart;
+            mSelectionEnd = selectionEnd;
+            mComposingTextStart = compositionStart;
+            mComposingTextEnd = compositionEnd;
+            controller.invalidateLastCursorAnchorInfo();
+        }
+
+        public void clearTextAndSelection(CursorAnchorInfoController controller) {
+            updateTextAndSelection(controller, null, -1, -1, -1, -1);
+        }
+    }
+
+    private void assertScaleAndTranslate(float expectedScale, float expectedTranslateX,
+            float expectedTranslateY, CursorAnchorInfo actual) {
+        Matrix expectedMatrix = new Matrix();
+        expectedMatrix.setScale(expectedScale, expectedScale);
+        expectedMatrix.postTranslate(expectedTranslateX, expectedTranslateY);
+        assertEquals(expectedMatrix, actual.getMatrix());
+    }
+
+    private void assertHasInsertionMarker(int expectedFlags, float expectedHorizontal,
+            float expectedTop, float expectedBaseline, float expectedBottom,
+            CursorAnchorInfo actual) {
+        assertEquals(expectedFlags, actual.getInsertionMarkerFlags());
+        assertEquals(expectedHorizontal, actual.getInsertionMarkerHorizontal());
+        assertEquals(expectedTop, actual.getInsertionMarkerTop());
+        assertEquals(expectedBaseline, actual.getInsertionMarkerBaseline());
+        assertEquals(expectedBottom, actual.getInsertionMarkerBottom());
+    }
+
+    private void assertHasNoInsertionMarker(CursorAnchorInfo actual) {
+        assertEquals(0, actual.getInsertionMarkerFlags());
+        assertTrue(Float.isNaN(actual.getInsertionMarkerHorizontal()));
+        assertTrue(Float.isNaN(actual.getInsertionMarkerTop()));
+        assertTrue(Float.isNaN(actual.getInsertionMarkerBaseline()));
+        assertTrue(Float.isNaN(actual.getInsertionMarkerBottom()));
+    }
+
+    private void assertComposingText(CharSequence expectedComposingText,
+            int expectedComposingTextStart, CursorAnchorInfo actual) {
+        assertTrue(TextUtils.equals(expectedComposingText, actual.getComposingText()));
+        assertEquals(expectedComposingTextStart, actual.getComposingTextStart());
+    }
+
+    private void assertSelection(int expecteSelectionStart, int expecteSelectionEnd,
+            CursorAnchorInfo actual) {
+        assertEquals(expecteSelectionStart, actual.getSelectionStart());
+        assertEquals(expecteSelectionEnd, actual.getSelectionEnd());
+    }
+
+    @SmallTest
+    @Feature({"Input-Text-IME"})
+    public void testFocusedNodeChanged() {
+        TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(null);
+        TestViewDelegate viewDelegate = new TestViewDelegate();
+        TestComposingTextDelegate composingTextDelegate = new TestComposingTextDelegate();
+        CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+                immw, composingTextDelegate, viewDelegate);
+        View view = null;
+
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+
+        assertFalse(
+                "IC#onRequestCursorUpdates() must be rejected if the focused node is not editable.",
+                controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+
+        // Make sure that the focused node is considered to be non-editable by default.
+        controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f});
+        composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1);
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+
+        controller.focusedNodeChanged(false);
+        composingTextDelegate.clearTextAndSelection(controller);
+
+        // Make sure that the controller does not crash even if it is called while the focused node
+        // is not editable.
+        controller.setCompositionCharacterBounds(new float[] {30.0f, 1.0f, 32.0f, 3.0f});
+        composingTextDelegate.updateTextAndSelection(controller, "1", 0, 1, 0, 1);
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 100.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+    }
+
+    @SmallTest
+    @Feature({"Input-Text-IME"})
+    public void testImmediateMode() {
+        TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(null);
+        TestViewDelegate viewDelegate = new TestViewDelegate();
+        TestComposingTextDelegate composingTextDelegate = new TestComposingTextDelegate();
+        CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+                immw, composingTextDelegate, viewDelegate);
+        View view = null;
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+
+        // Make sure that #updateCursorAnchorInfo() is not be called until the matrix info becomes
+        // available with #onUpdateFrameInfo().
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE,
+                view));
+        controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f});
+        composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1);
+        assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("0", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that 2nd call of #onUpdateFrameInfo() is ignored.
+        controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+
+        // Make sure that #onUpdateFrameInfo() is immediately called because the matrix info is
+        // already available.
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE,
+                view));
+        assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("0", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that CURSOR_UPDATE_IMMEDIATE and CURSOR_UPDATE_MONITOR can be specified at
+        // the same time.
+        assertTrue(controller.onRequestCursorUpdates(
+                InputConnection.CURSOR_UPDATE_IMMEDIATE | InputConnection.CURSOR_UPDATE_MONITOR,
+                view));
+        assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("0", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that CURSOR_UPDATE_IMMEDIATE is cleared if the focused node becomes
+        // non-editable.
+        controller.focusedNodeChanged(false);
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE,
+                view));
+        controller.focusedNodeChanged(false);
+        composingTextDelegate.clearTextAndSelection(controller);
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 100.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+
+        // Make sure that CURSOR_UPDATE_IMMEDIATE can be enabled again.
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE,
+                view));
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText(null, -1, immw.getLastCursorAnchorInfo());
+        assertSelection(-1, -1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+    }
+
+    @SmallTest
+    @Feature({"Input-Text-IME"})
+    public void testMonitorMode() {
+        TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(null);
+        TestViewDelegate viewDelegate = new TestViewDelegate();
+        TestComposingTextDelegate composingTextDelegate = new TestComposingTextDelegate();
+        CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+                immw, composingTextDelegate, viewDelegate);
+        View view = null;
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+
+        // Make sure that #updateCursorAnchorInfo() is not be called until the matrix info becomes
+        // available with #onUpdateFrameInfo().
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+        controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f});
+        composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1);
+        assertEquals(0, immw.getUpdateCursorAnchorInfoCounter());
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("0", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that #updateCursorAnchorInfo() is not be called if any coordinate parameter is
+        // changed for better performance.
+        controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f});
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+
+        // Make sure that #updateCursorAnchorInfo() is called if #setCompositionCharacterBounds()
+        // is called with a different parameter.
+        controller.setCompositionCharacterBounds(new float[] {30.0f, 1.0f, 32.0f, 3.0f});
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("0", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that #updateCursorAnchorInfo() is called if #updateTextAndSelection()
+        // is called with a different parameter.
+        composingTextDelegate.updateTextAndSelection(controller, "1", 0, 1, 0, 1);
+        assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("1", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that #updateCursorAnchorInfo() is called if #onUpdateFrameInfo()
+        // is called with a different parameter.
+        controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("1", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that #updateCursorAnchorInfo() is called when the view origin is changed.
+        viewDelegate.locationX = 7;
+        viewDelegate.locationY = 9;
+        controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(2.0f, 7.0f, 9.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(30.0f, 1.0f, 32.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("1", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Make sure that CURSOR_UPDATE_IMMEDIATE is cleared if the focused node becomes
+        // non-editable.
+        controller.focusedNodeChanged(false);
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+        controller.focusedNodeChanged(false);
+        composingTextDelegate.clearTextAndSelection(controller);
+        controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f});
+        composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1);
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+
+        // Make sure that CURSOR_UPDATE_MONITOR can be enabled again.
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+        controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f});
+        composingTextDelegate.updateTextAndSelection(controller, "0", 0, 1, 0, 1);
+        assertEquals(5, immw.getUpdateCursorAnchorInfoCounter());
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 2.0f, 0.0f, 3.0f, view);
+        assertEquals(6, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION, 2.0f, 0.0f, 3.0f,
+                3.0f, immw.getLastCursorAnchorInfo());
+        assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertComposingText("0", 0, immw.getLastCursorAnchorInfo());
+        assertSelection(0, 1, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+    }
+
+    @SmallTest
+    @Feature({"Input-Text-IME"})
+    public void testSetCompositionCharacterBounds() {
+        TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(null);
+        TestViewDelegate viewDelegate = new TestViewDelegate();
+        TestComposingTextDelegate composingTextDelegate = new TestComposingTextDelegate();
+        CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+                immw, composingTextDelegate, viewDelegate);
+        View view = null;
+
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+
+        composingTextDelegate.updateTextAndSelection(controller, "01234", 1, 3, 1, 1);
+        controller.setCompositionCharacterBounds(new float[] {0.0f, 1.0f, 2.0f, 3.0f,
+                4.0f, 1.1f, 6.0f, 2.9f});
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                false, false, Float.NaN, Float.NaN, Float.NaN, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertEquals(new RectF(0.0f, 1.0f, 2.0f, 3.0f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(1));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(1));
+        assertEquals(new RectF(4.0f, 1.1f, 6.0f, 2.9f),
+                immw.getLastCursorAnchorInfo().getCharacterBounds(2));
+        assertEquals(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(2));
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(3));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(3));
+        assertComposingText("12", 1, immw.getLastCursorAnchorInfo());
+        assertSelection(1, 1, immw.getLastCursorAnchorInfo());
+    }
+
+    @SmallTest
+    @Feature({"Input-Text-IME"})
+    public void testUpdateTextAndSelection() {
+        TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(null);
+        TestViewDelegate viewDelegate = new TestViewDelegate();
+        TestComposingTextDelegate composingTextDelegate = new TestComposingTextDelegate();
+        CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+                immw, composingTextDelegate, viewDelegate);
+        View view = null;
+
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+
+        composingTextDelegate.updateTextAndSelection(controller, "01234", 3, 3, 1, 1);
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                false, false, Float.NaN, Float.NaN, Float.NaN, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(0));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(0));
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(1));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(1));
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(2));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(2));
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(3));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(3));
+        assertEquals(null, immw.getLastCursorAnchorInfo().getCharacterBounds(4));
+        assertEquals(0, immw.getLastCursorAnchorInfo().getCharacterBoundsFlags(4));
+        assertComposingText("", 3, immw.getLastCursorAnchorInfo());
+        assertSelection(1, 1, immw.getLastCursorAnchorInfo());
+    }
+
+    @SmallTest
+    @Feature({"Input-Text-IME"})
+    public void testInsertionMarker() {
+        TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(null);
+        TestViewDelegate viewDelegate = new TestViewDelegate();
+        TestComposingTextDelegate composingTextDelegate = new TestComposingTextDelegate();
+        CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+                immw, composingTextDelegate, viewDelegate);
+        View view = null;
+
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+
+        // Test no insertion marker.
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                false, false, Float.NaN, Float.NaN, Float.NaN, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+        assertHasNoInsertionMarker(immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Test a visible insertion marker.
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, true, 10.0f, 23.0f, 29.0f, view);
+        assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION,
+                10.0f, 23.0f, 29.0f, 29.0f, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // Test a invisible insertion marker.
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                true, false, 10.0f, 23.0f, 29.0f, view);
+        assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+        assertHasInsertionMarker(CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION,
+                10.0f, 23.0f, 29.0f, 29.0f, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+    }
+
+    @SmallTest
+    @Feature({"Input-Text-IME"})
+    public void testMatrix() {
+        TestInputMethodManagerWrapper immw = new TestInputMethodManagerWrapper(null);
+        TestViewDelegate viewDelegate = new TestViewDelegate();
+        TestComposingTextDelegate composingTextDelegate = new TestComposingTextDelegate();
+        CursorAnchorInfoController controller = CursorAnchorInfoController.createForTest(
+                immw, composingTextDelegate, viewDelegate);
+        View view = null;
+
+        controller.focusedNodeChanged(true);
+        composingTextDelegate.clearTextAndSelection(controller);
+        assertTrue(controller.onRequestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR, view));
+
+        // Test no transformation
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+        controller.onUpdateFrameInfo(createRenderCoordinates(1.0f, 0.0f),
+                false, false, Float.NaN, Float.NaN, Float.NaN, view);
+        assertEquals(1, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(1.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // device scale factor == 2.0
+        viewDelegate.locationX = 0;
+        viewDelegate.locationY = 0;
+        controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f),
+                false, false, Float.NaN, Float.NaN, Float.NaN, view);
+        assertEquals(2, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(2.0f, 0.0f, 0.0f, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // device scale factor == 2.0
+        // view origin == (10, 141)
+        viewDelegate.locationX = 10;
+        viewDelegate.locationY = 141;
+        controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 0.0f),
+                false, false, Float.NaN, Float.NaN, Float.NaN, view);
+        assertEquals(3, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(2.0f, 10.0f, 141.0f, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+
+        // device scale factor == 2.0
+        // content offset Y = 40.0f
+        // view origin == (10, 141)
+        viewDelegate.locationX = 10;
+        viewDelegate.locationY = 141;
+        controller.onUpdateFrameInfo(createRenderCoordinates(2.0f, 40.0f),
+                false, false, Float.NaN, Float.NaN, Float.NaN, view);
+        assertEquals(4, immw.getUpdateCursorAnchorInfoCounter());
+        assertScaleAndTranslate(2.0f, 10.0f, 181.0f, immw.getLastCursorAnchorInfo());
+        immw.clearLastCursorAnchorInfo();
+    }
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java
new file mode 100644
index 0000000..1226ba1
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeLollipopTest.java
@@ -0,0 +1,97 @@
+// 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.content.browser.input;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.InputConnection;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.MinAndroidSdkLevel;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+
+/**
+ * Integration tests for text input for Android L (or above) features.
+ */
+@MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP)
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class ImeLollipopTest extends ImeTest {
+    @MediumTest
+    @Feature({"TextInput"})
+    public void testUpdateCursorAnchorInfo() throws Throwable {
+        requestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR);
+
+        // In "MONITOR" mode, the change should be notified.
+        setComposingText("ab", 1);
+        waitForUpdateCursorAnchorInfoComposingText("ab");
+
+        CursorAnchorInfo info = mInputMethodManagerWrapper.getLastCursorAnchorInfo();
+        assertEquals(0, info.getComposingTextStart());
+        assertNotNull(info.getCharacterBounds(0));
+        assertNotNull(info.getCharacterBounds(1));
+        assertNull(info.getCharacterBounds(2));
+
+        // Should be notified not only once. Further change should be sent, too.
+        setComposingText("abcd", 1);
+        waitForUpdateCursorAnchorInfoComposingText("abcd");
+
+        info = mInputMethodManagerWrapper.getLastCursorAnchorInfo();
+        assertEquals(0, info.getComposingTextStart());
+        assertNotNull(info.getCharacterBounds(0));
+        assertNotNull(info.getCharacterBounds(1));
+        assertNotNull(info.getCharacterBounds(2));
+        assertNotNull(info.getCharacterBounds(3));
+        assertNull(info.getCharacterBounds(4));
+
+        // In "IMMEDIATE" mode, even when there's no change, we should be notified at least once.
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                mInputMethodManagerWrapper.clearLastCursorAnchorInfo();
+            }
+        });
+        requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE);
+        waitForUpdateCursorAnchorInfoComposingText("abcd");
+    }
+
+    private void requestCursorUpdates(final int cursorUpdateMode) {
+        final InputConnection connection = mConnection;
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                connection.requestCursorUpdates(cursorUpdateMode);
+            }
+        });
+    }
+
+    private void waitForUpdateCursorAnchorInfoCallCount(final int expected)
+            throws InterruptedException {
+        CriteriaHelper.pollForUIThreadCriteria(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                int actual =  mInputMethodManagerWrapper.getUpdateCursorAnchorInfoCounter();
+                updateFailureReason("Expected: {" + expected + "}, Actual: {" + actual + "}");
+                return expected == actual;
+            }
+        });
+    }
+
+    private void waitForUpdateCursorAnchorInfoComposingText(final String expected)
+            throws InterruptedException {
+        CriteriaHelper.pollForUIThreadCriteria(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                CursorAnchorInfo info = mInputMethodManagerWrapper.getLastCursorAnchorInfo();
+                String actual = (info == null ? "" : info.getComposingText().toString());
+                updateFailureReason("Expected: {" + expected + "}, Actual: {" + actual + "}");
+                return expected.equals(actual);
+            }
+        });
+    }
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
index 220003fb..905e24c 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
@@ -58,14 +58,14 @@
             + "<br/><p><span id=\"plain_text\">This is Plain Text One</span></p>"
             + "</form></body></html>");
 
-    private ChromiumBaseInputConnection mConnection;
+    protected ChromiumBaseInputConnection mConnection;
     private TestInputConnectionFactory mConnectionFactory;
     private ImeAdapter mImeAdapter;
 
     private ContentViewCore mContentViewCore;
     private WebContents mWebContents;
     private TestCallbackHelperContainer mCallbackContainer;
-    private TestInputMethodManagerWrapper mInputMethodManagerWrapper;
+    protected TestInputMethodManagerWrapper mInputMethodManagerWrapper;
 
     @Override
     public void setUp() throws Exception {
@@ -1261,7 +1261,7 @@
         });
     }
 
-    private boolean setComposingText(final CharSequence text, final int newCursorPosition)
+    protected boolean setComposingText(final CharSequence text, final int newCursorPosition)
             throws Exception {
         final ChromiumBaseInputConnection connection = mConnection;
         return runBlockingOnImeThread(new Callable<Boolean>() {
diff --git a/content/public/browser/android/compositor.h b/content/public/browser/android/compositor.h
index 6ce49e9..1a96ee6 100644
--- a/content/public/browser/android/compositor.h
+++ b/content/public/browser/android/compositor.h
@@ -17,7 +17,6 @@
 
 namespace cc {
 class Layer;
-class LayerSettings;
 }
 
 namespace gfx {
@@ -46,9 +45,6 @@
   static Compositor* Create(CompositorClient* client,
                             gfx::NativeWindow root_window);
 
-  static const cc::LayerSettings& LayerSettings();
-  static void SetLayerSettings(const cc::LayerSettings& settings);
-
   // Attaches the layer tree.
   virtual void SetRootLayer(scoped_refptr<cc::Layer> root) = 0;
 
diff --git a/content/public/browser/desktop_media_id.h b/content/public/browser/desktop_media_id.h
index 5db272a..7b6cd1f 100644
--- a/content/public/browser/desktop_media_id.h
+++ b/content/public/browser/desktop_media_id.h
@@ -46,6 +46,9 @@
   DesktopMediaID(Type type, Id id, WebContentsMediaCaptureId web_contents_id)
       : type(type), id(id), web_contents_id(web_contents_id) {}
 
+  DesktopMediaID(Type type, Id id, bool audio_share)
+      : type(type), id(id), audio_share(audio_share) {}
+
   // Operators so that DesktopMediaID can be used with STL containers.
   bool operator<(const DesktopMediaID& other) const;
   bool operator==(const DesktopMediaID& other) const;
diff --git a/content/public/browser/indexed_db_context.h b/content/public/browser/indexed_db_context.h
index 2bd0112..ef9d61f4 100644
--- a/content/public/browser/indexed_db_context.h
+++ b/content/public/browser/indexed_db_context.h
@@ -42,7 +42,8 @@
 
   // Get the file name of the local storage file for the given origin.
   virtual base::FilePath GetFilePathForTesting(
-      const std::string& origin_id) const = 0;
+      const GURL& origin_url) const = 0;
+
   // Set the task runner for tests if browser main loop is not initialized.
   virtual void SetTaskRunnerForTesting(
       base::SequencedTaskRunner* task_runner) = 0;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 4a84e56..6037c18 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -916,11 +916,6 @@
 #endif
 
 #if defined(OS_ANDROID)
-// Disable external animation system for Android compositor.
-// See also kDisableCompositorAnimationTimelines for renderer compositors.
-const char kDisableAndroidCompositorAnimationTimelines[] =
-    "disable-android-compositor-animation-timelines";
-
 // Disable overscroll edge effects like those found in Android views.
 const char kDisableOverscrollEdgeEffect[]   = "disable-overscroll-edge-effect";
 
@@ -950,6 +945,12 @@
 // Block ChildProcessMain thread of the renderer's ChildProcessService until a
 // Java debugger is attached.
 const char kRendererWaitForJavaDebugger[] = "renderer-wait-for-java-debugger";
+
+// Use synchronous input code path for IPC-synchronous compositing. This is the
+// legacy input code path used by the in-process synchronous compositor.
+// Maintaining this code path in case there are compatibility bugs with the
+// standard async input path. Remove tracked as part of crbug.com/545628.
+const char kSyncInputForSyncCompositor[]    = "sync-input-for-sync-compositor";
 #endif
 
 // Enable the aggressive flushing of DOM Storage to minimize data loss.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index bf8979c..e4a1ef00 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -263,7 +263,6 @@
 #endif
 
 #if defined(OS_ANDROID)
-CONTENT_EXPORT extern const char kDisableAndroidCompositorAnimationTimelines[];
 CONTENT_EXPORT extern const char kDisableOverscrollEdgeEffect[];
 CONTENT_EXPORT extern const char kDisablePullToRefreshEffect[];
 CONTENT_EXPORT extern const char kDisableScreenOrientationLock[];
@@ -274,6 +273,7 @@
 extern const char kNetworkCountryIso[];
 CONTENT_EXPORT extern const char kRemoteDebuggingSocketName[];
 CONTENT_EXPORT extern const char kRendererWaitForJavaDebugger[];
+CONTENT_EXPORT extern const char kSyncInputForSyncCompositor[];
 #endif
 
 #if defined(OS_CHROMEOS)
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc
index d44642f..c0563f5 100644
--- a/content/public/common/web_preferences.cc
+++ b/content/public/common/web_preferences.cc
@@ -8,7 +8,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "third_party/WebKit/public/web/WebSettings.h"
-#include "third_party/icu/source/common/unicode/uchar.h"
 
 using blink::WebSettings;
 
diff --git a/content/public/renderer/document_state.h b/content/public/renderer/document_state.h
index edb66bd..99beb471 100644
--- a/content/public/renderer/document_state.h
+++ b/content/public/renderer/document_state.h
@@ -45,7 +45,7 @@
   ~DocumentState() override;
 
   static DocumentState* FromDataSource(blink::WebDataSource* ds) {
-    return static_cast<DocumentState*>(ds->extraData());
+    return static_cast<DocumentState*>(ds->getExtraData());
   }
 
   // The time that this navigation was requested.
diff --git a/content/public/renderer/media_stream_video_sink.cc b/content/public/renderer/media_stream_video_sink.cc
index 716c8df..118d732c 100644
--- a/content/public/renderer/media_stream_video_sink.cc
+++ b/content/public/renderer/media_stream_video_sink.cc
@@ -16,7 +16,7 @@
     const blink::WebMediaStreamTrack& track) {
   DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, track.source().getType());
   MediaStreamVideoTrack* const video_track =
-      static_cast<MediaStreamVideoTrack*>(track.extraData());
+      static_cast<MediaStreamVideoTrack*>(track.getExtraData());
   video_track->AddSink(sink, callback);
 }
 
@@ -25,7 +25,7 @@
     const blink::WebMediaStreamTrack& track) {
   DCHECK_EQ(blink::WebMediaStreamSource::TypeVideo, track.source().getType());
   MediaStreamVideoTrack* const video_track =
-      static_cast<MediaStreamVideoTrack*>(track.extraData());
+      static_cast<MediaStreamVideoTrack*>(track.getExtraData());
   video_track->RemoveSink(sink);
 }
 
diff --git a/content/public/renderer/render_view.h b/content/public/renderer/render_view.h
index 2a7f85a..8c036d5 100644
--- a/content/public/renderer/render_view.h
+++ b/content/public/renderer/render_view.h
@@ -140,7 +140,7 @@
 
   // Converts the |rect| from Viewport coordinates to Window coordinates.
   // See blink::WebWidgetClient::convertViewportToWindow for more details.
-  virtual void convertViewportToWindow(blink::WebRect* rect) = 0;
+  virtual void ConvertViewportToWindowViaWidget(blink::WebRect* rect) = 0;
 
   // Returns the bounds of |element| in Window coordinates. The bounds have been
   // adjusted to include any transformations, including page scale.
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java
index 6c944f3..7cc86b7 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java
@@ -8,6 +8,7 @@
 import android.os.ResultReceiver;
 import android.util.Pair;
 import android.view.View;
+import android.view.inputmethod.CursorAnchorInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 
@@ -34,6 +35,8 @@
     private final Range mComposition = new Range(-1, -1);
     private boolean mIsShowWithoutHideOutstanding;
     private final List<Pair<Range, Range>> mUpdateSelectionList;
+    private int mUpdateCursorAnchorInfoCounter;
+    private CursorAnchorInfo mLastCursorAnchorInfo;
 
     public TestInputMethodManagerWrapper(ContentViewCore contentViewCore) {
         super(null);
@@ -107,6 +110,12 @@
         return mRestartInputCounter;
     }
 
+    @Override
+    public void updateCursorAnchorInfo(View view, CursorAnchorInfo cursorAnchorInfo) {
+        mUpdateCursorAnchorInfoCounter++;
+        mLastCursorAnchorInfo = cursorAnchorInfo;
+    }
+
     public int getShowSoftInputCounter() {
         Log.d(TAG, "getShowSoftInputCounter: %d", mShowSoftInputCounter);
         return mShowSoftInputCounter;
@@ -139,4 +148,16 @@
     public boolean isShowWithoutHideOutstanding() {
         return mIsShowWithoutHideOutstanding;
     }
-}
\ No newline at end of file
+
+    public int getUpdateCursorAnchorInfoCounter() {
+        return mUpdateCursorAnchorInfoCounter;
+    }
+
+    public void clearLastCursorAnchorInfo() {
+        mLastCursorAnchorInfo = null;
+    }
+
+    public CursorAnchorInfo getLastCursorAnchorInfo() {
+        return mLastCursorAnchorInfo;
+    }
+}
diff --git a/content/renderer/android/synchronous_compositor_factory.h b/content/renderer/android/synchronous_compositor_factory.h
index c8fece9..18ada90 100644
--- a/content/renderer/android/synchronous_compositor_factory.h
+++ b/content/renderer/android/synchronous_compositor_factory.h
@@ -31,6 +31,7 @@
 namespace content {
 
 class InputHandlerManagerClient;
+class SynchronousInputHandlerProxyClient;
 class StreamTextureFactory;
 class FrameSwapMessageQueue;
 
@@ -55,6 +56,8 @@
 
   // The factory maintains ownership of the returned interface.
   virtual InputHandlerManagerClient* GetInputHandlerManagerClient() = 0;
+  virtual SynchronousInputHandlerProxyClient*
+  GetSynchronousInputHandlerProxyClient() = 0;
 
   virtual scoped_ptr<cc::BeginFrameSource> CreateExternalBeginFrameSource(
       int routing_id) = 0;
diff --git a/content/renderer/android/synchronous_compositor_filter.cc b/content/renderer/android/synchronous_compositor_filter.cc
index 54dfed3..aadedb2 100644
--- a/content/renderer/android/synchronous_compositor_filter.cc
+++ b/content/renderer/android/synchronous_compositor_filter.cc
@@ -210,34 +210,15 @@
           handler));
 }
 
+void SynchronousCompositorFilter::DidAddInputHandler(int routing_id) {}
+void SynchronousCompositorFilter::DidRemoveInputHandler(int routing_id) {}
+
 void SynchronousCompositorFilter::SetBoundHandlerOnCompositorThread(
     const Handler& handler) {
   DCHECK(compositor_task_runner_->BelongsToCurrentThread());
   input_handler_ = handler;
 }
 
-void SynchronousCompositorFilter::DidAddInputHandler(
-    int routing_id,
-    ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
-  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
-  DCHECK(synchronous_input_handler_proxy);
-  Entry& entry = entry_map_[routing_id];
-  DCHECK(!entry.synchronous_input_handler_proxy);
-  entry.synchronous_input_handler_proxy = synchronous_input_handler_proxy;
-  CheckIsReady(routing_id);
-}
-
-void SynchronousCompositorFilter::DidRemoveInputHandler(int routing_id) {
-  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
-  DCHECK(ContainsKey(entry_map_, routing_id));
-  Entry& entry = entry_map_[routing_id];
-
-  if (entry.IsReady())
-    UnregisterObjects(routing_id);
-  entry.synchronous_input_handler_proxy = nullptr;
-  RemoveEntryIfNeeded(routing_id);
-}
-
 void SynchronousCompositorFilter::DidOverscroll(
     int routing_id,
     const DidOverscrollParams& params) {
@@ -259,6 +240,29 @@
     int routing_id,
     blink::WebInputEvent::Type type) {}
 
+void SynchronousCompositorFilter::DidAddSynchronousHandlerProxy(
+    int routing_id,
+    ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(synchronous_input_handler_proxy);
+  Entry& entry = entry_map_[routing_id];
+  DCHECK(!entry.synchronous_input_handler_proxy);
+  entry.synchronous_input_handler_proxy = synchronous_input_handler_proxy;
+  CheckIsReady(routing_id);
+}
+
+void SynchronousCompositorFilter::DidRemoveSynchronousHandlerProxy(
+    int routing_id) {
+  DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+  DCHECK(ContainsKey(entry_map_, routing_id));
+  Entry& entry = entry_map_[routing_id];
+
+  if (entry.IsReady())
+    UnregisterObjects(routing_id);
+  entry.synchronous_input_handler_proxy = nullptr;
+  RemoveEntryIfNeeded(routing_id);
+}
+
 SynchronousCompositorFilter::Entry::Entry()
     : begin_frame_source(nullptr),
       output_surface(nullptr),
diff --git a/content/renderer/android/synchronous_compositor_filter.h b/content/renderer/android/synchronous_compositor_filter.h
index bfab1f6..7310c0a 100644
--- a/content/renderer/android/synchronous_compositor_filter.h
+++ b/content/renderer/android/synchronous_compositor_filter.h
@@ -23,10 +23,12 @@
 
 class SynchronousCompositorProxy;
 
-class SynchronousCompositorFilter : public IPC::MessageFilter,
-                                    public IPC::Sender,
-                                    public SynchronousCompositorRegistry,
-                                    public InputHandlerManagerClient {
+class SynchronousCompositorFilter
+    : public IPC::MessageFilter,
+      public IPC::Sender,
+      public SynchronousCompositorRegistry,
+      public InputHandlerManagerClient,
+      public SynchronousInputHandlerProxyClient {
  public:
   SynchronousCompositorFilter(const scoped_refptr<base::SingleThreadTaskRunner>&
                                   compositor_task_runner);
@@ -58,10 +60,7 @@
 
   // InputHandlerManagerClient overrides.
   void SetBoundHandler(const Handler& handler) override;
-  void DidAddInputHandler(
-      int routing_id,
-      ui::SynchronousInputHandlerProxy*
-          synchronous_input_handler_proxy) override;
+  void DidAddInputHandler(int routing_id) override;
   void DidRemoveInputHandler(int routing_id) override;
   void DidOverscroll(int routing_id,
                      const DidOverscrollParams& params) override;
@@ -69,6 +68,13 @@
   void NonBlockingInputEventHandled(int routing_id,
                                     blink::WebInputEvent::Type type) override;
 
+  // SynchronousInputHandlerProxyClient overrides.
+  void DidAddSynchronousHandlerProxy(
+      int routing_id,
+      ui::SynchronousInputHandlerProxy* synchronous_input_handler_proxy)
+      override;
+  void DidRemoveSynchronousHandlerProxy(int routing_id) override;
+
  private:
   ~SynchronousCompositorFilter() override;
 
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc
index ac91ef3..9a74b59 100644
--- a/content/renderer/browser_plugin/browser_plugin.cc
+++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -416,7 +416,8 @@
   // Convert the plugin_rect_in_viewport to window coordinates, which is css.
   WebRect rect_in_css(plugin_rect_in_viewport);
   blink::WebView* webview = container()->element().document().frame()->view();
-  RenderView::FromWebView(webview)->convertViewportToWindow(&rect_in_css);
+  RenderView::FromWebView(webview)->GetWidget()->convertViewportToWindow(
+      &rect_in_css);
   view_rect_ = rect_in_css;
 
   if (!ready_) {
diff --git a/content/renderer/input/input_event_filter.cc b/content/renderer/input/input_event_filter.cc
index 9a90141..eede217 100644
--- a/content/renderer/input/input_event_filter.cc
+++ b/content/renderer/input/input_event_filter.cc
@@ -19,7 +19,6 @@
 #include "content/public/common/content_switches.h"
 #include "ipc/ipc_listener.h"
 #include "ipc/ipc_sender.h"
-#include "ui/events/blink/synchronous_input_handler_proxy.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 
 using blink::WebInputEvent;
@@ -59,10 +58,7 @@
   handler_ = handler;
 }
 
-void InputEventFilter::DidAddInputHandler(
-    int routing_id,
-    ui::SynchronousInputHandlerProxy*
-        synchronous_input_handler_proxy) {
+void InputEventFilter::DidAddInputHandler(int routing_id) {
   base::AutoLock locked(routes_lock_);
   routes_.insert(routing_id);
   route_queues_[routing_id].reset(new NonBlockingEventQueue(routing_id, this));
diff --git a/content/renderer/input/input_event_filter.h b/content/renderer/input/input_event_filter.h
index 71d22f76..b1e888d 100644
--- a/content/renderer/input/input_event_filter.h
+++ b/content/renderer/input/input_event_filter.h
@@ -61,10 +61,7 @@
   // InputHostMsg_HandleInputEvent_ACK.
   //
   void SetBoundHandler(const Handler& handler) override;
-  void DidAddInputHandler(
-      int routing_id,
-      ui::SynchronousInputHandlerProxy*
-          synchronous_input_handler_proxy) override;
+  void DidAddInputHandler(int routing_id) override;
   void DidRemoveInputHandler(int routing_id) override;
   void DidOverscroll(int routing_id,
                      const DidOverscrollParams& params) override;
diff --git a/content/renderer/input/input_event_filter_unittest.cc b/content/renderer/input/input_event_filter_unittest.cc
index 8027752a..4520228 100644
--- a/content/renderer/input/input_event_filter_unittest.cc
+++ b/content/renderer/input/input_event_filter_unittest.cc
@@ -178,7 +178,7 @@
   EXPECT_EQ(0U, event_recorder_.record_count());
   EXPECT_EQ(0U, message_recorder_.message_count());
 
-  filter_->DidAddInputHandler(kTestRoutingID, nullptr);
+  filter_->DidAddInputHandler(kTestRoutingID);
 
   AddEventsToFilter(filter_.get(), kEvents, arraysize(kEvents));
   ASSERT_EQ(arraysize(kEvents), ipc_sink_.message_count());
@@ -254,7 +254,7 @@
 }
 
 TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
-  filter_->DidAddInputHandler(kTestRoutingID, nullptr);
+  filter_->DidAddInputHandler(kTestRoutingID);
   event_recorder_.set_send_to_widget(true);
 
 
@@ -313,7 +313,7 @@
       SyntheticWebMouseWheelEventBuilder::Build(30, 30, 0, 53, 1, false),
   };
 
-  filter_->DidAddInputHandler(kTestRoutingID, nullptr);
+  filter_->DidAddInputHandler(kTestRoutingID);
   event_recorder_.set_send_to_widget(true);
   event_recorder_.set_passive(true);
 
@@ -390,7 +390,7 @@
   kEvents[3].PressPoint(10, 10);
   kEvents[3].MovePoint(0, 35, 35);
 
-  filter_->DidAddInputHandler(kTestRoutingID, nullptr);
+  filter_->DidAddInputHandler(kTestRoutingID);
   event_recorder_.set_send_to_widget(true);
   event_recorder_.set_passive(true);
 
diff --git a/content/renderer/input/input_handler_manager.cc b/content/renderer/input/input_handler_manager.cc
index 58fd95f..5f1bfe04 100644
--- a/content/renderer/input/input_handler_manager.cc
+++ b/content/renderer/input/input_handler_manager.cc
@@ -48,9 +48,11 @@
 InputHandlerManager::InputHandlerManager(
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     InputHandlerManagerClient* client,
+    SynchronousInputHandlerProxyClient* sync_handler_client,
     scheduler::RendererScheduler* renderer_scheduler)
     : task_runner_(task_runner),
       client_(client),
+      synchronous_handler_proxy_client_(sync_handler_client),
       renderer_scheduler_(renderer_scheduler) {
   DCHECK(client_);
   client_->SetBoundHandler(base::Bind(&InputHandlerManager::HandleInputEvent,
@@ -105,7 +107,11 @@
   scoped_ptr<InputHandlerWrapper> wrapper(new InputHandlerWrapper(
       this, routing_id, main_task_runner, input_handler, render_view_impl,
       enable_smooth_scrolling, enable_wheel_gestures));
-  client_->DidAddInputHandler(routing_id, wrapper->input_handler_proxy());
+  client_->DidAddInputHandler(routing_id);
+  if (synchronous_handler_proxy_client_) {
+    synchronous_handler_proxy_client_->DidAddSynchronousHandlerProxy(
+        routing_id, wrapper->input_handler_proxy());
+  }
   input_handlers_.add(routing_id, std::move(wrapper));
 }
 
@@ -116,6 +122,10 @@
   TRACE_EVENT0("input", "InputHandlerManager::RemoveInputHandler");
 
   client_->DidRemoveInputHandler(routing_id);
+  if (synchronous_handler_proxy_client_) {
+    synchronous_handler_proxy_client_->DidRemoveSynchronousHandlerProxy(
+        routing_id);
+  }
   input_handlers_.erase(routing_id);
 }
 
diff --git a/content/renderer/input/input_handler_manager.h b/content/renderer/input/input_handler_manager.h
index c8bfb752..3211a1f 100644
--- a/content/renderer/input/input_handler_manager.h
+++ b/content/renderer/input/input_handler_manager.h
@@ -8,6 +8,7 @@
 #include "base/containers/scoped_ptr_hash_map.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
 #include "content/common/input/input_event_ack_state.h"
 #include "content/renderer/render_view_impl.h"
 
@@ -32,12 +33,13 @@
 namespace content {
 
 class InputHandlerWrapper;
+class SynchronousInputHandlerProxyClient;
 class InputHandlerManagerClient;
 struct DidOverscrollParams;
 
 // InputHandlerManager class manages InputHandlerProxy instances for
 // the WebViews in this renderer.
-class InputHandlerManager {
+class CONTENT_EXPORT InputHandlerManager {
  public:
   // |task_runner| is the SingleThreadTaskRunner of the compositor thread. The
   // underlying MessageLoop and supplied |client| and the |renderer_scheduler|
@@ -46,6 +48,7 @@
   InputHandlerManager(
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
       InputHandlerManagerClient* client,
+      SynchronousInputHandlerProxyClient* sync_handler_client,
       scheduler::RendererScheduler* renderer_scheduler);
   ~InputHandlerManager();
 
@@ -105,9 +108,11 @@
       InputHandlerMap;
   InputHandlerMap input_handlers_;
 
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  InputHandlerManagerClient* client_;
-  scheduler::RendererScheduler* renderer_scheduler_;  // Not owned.
+  const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  InputHandlerManagerClient* const client_;
+  // May be null.
+  SynchronousInputHandlerProxyClient* const synchronous_handler_proxy_client_;
+  scheduler::RendererScheduler* const renderer_scheduler_;  // Not owned.
 };
 
 }  // namespace content
diff --git a/content/renderer/input/input_handler_manager_client.h b/content/renderer/input/input_handler_manager_client.h
index c794bd2..71dc3e9e 100644
--- a/content/renderer/input/input_handler_manager_client.h
+++ b/content/renderer/input/input_handler_manager_client.h
@@ -44,9 +44,7 @@
   virtual void SetBoundHandler(const Handler& handler) = 0;
 
   // Called from the compositor thread.
-  virtual void DidAddInputHandler(
-      int routing_id,
-      ui::SynchronousInputHandlerProxy* synchronous_handler) = 0;
+  virtual void DidAddInputHandler(int routing_id) = 0;
   virtual void DidRemoveInputHandler(int routing_id) = 0;
   virtual void DidOverscroll(int routing_id,
                              const DidOverscrollParams& params) = 0;
@@ -62,6 +60,22 @@
   DISALLOW_COPY_AND_ASSIGN(InputHandlerManagerClient);
 };
 
+class CONTENT_EXPORT SynchronousInputHandlerProxyClient {
+ public:
+  virtual ~SynchronousInputHandlerProxyClient() {}
+
+  virtual void DidAddSynchronousHandlerProxy(
+      int routing_id,
+      ui::SynchronousInputHandlerProxy* synchronous_handler) = 0;
+  virtual void DidRemoveSynchronousHandlerProxy(int routing_id) = 0;
+
+ protected:
+  SynchronousInputHandlerProxyClient() {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SynchronousInputHandlerProxyClient);
+};
+
 }  // namespace content
 
 #endif  // CONTENT_RENDERER_INPUT_INPUT_HANDLER_MANAGER_CLIENT_H_
diff --git a/content/renderer/internal_document_state_data.cc b/content/renderer/internal_document_state_data.cc
index d250853..b37db86f 100644
--- a/content/renderer/internal_document_state_data.cc
+++ b/content/renderer/internal_document_state_data.cc
@@ -27,7 +27,7 @@
 // static
 InternalDocumentStateData* InternalDocumentStateData::FromDataSource(
     blink::WebDataSource* ds) {
-  return FromDocumentState(static_cast<DocumentState*>(ds->extraData()));
+  return FromDocumentState(static_cast<DocumentState*>(ds->getExtraData()));
 }
 
 // static
diff --git a/content/renderer/java/gin_java_bridge_value_converter_unittest.cc b/content/renderer/java/gin_java_bridge_value_converter_unittest.cc
index 2de3e12..2178fca 100644
--- a/content/renderer/java/gin_java_bridge_value_converter_unittest.cc
+++ b/content/renderer/java/gin_java_bridge_value_converter_unittest.cc
@@ -12,6 +12,7 @@
 #include "content/common/android/gin_java_bridge_value.h"
 #include "content/renderer/java/gin_java_bridge_value_converter.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 namespace content {
@@ -99,6 +100,7 @@
   v8::Local<v8::Context> context =
       v8::Local<v8::Context>::New(isolate_, context_);
   v8::Context::Scope context_scope(context);
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
 
   scoped_ptr<GinJavaBridgeValueConverter> converter(
       new GinJavaBridgeValueConverter());
diff --git a/content/renderer/media/media_stream.cc b/content/renderer/media/media_stream.cc
index 27e61b9..d95de28 100644
--- a/content/renderer/media/media_stream.cc
+++ b/content/renderer/media/media_stream.cc
@@ -14,7 +14,7 @@
 // static
 MediaStream* MediaStream::GetMediaStream(
     const blink::WebMediaStream& stream) {
-  return static_cast<MediaStream*>(stream.extraData());
+  return static_cast<MediaStream*>(stream.getExtraData());
 }
 
 MediaStream::MediaStream() {
diff --git a/content/renderer/media/media_stream_audio_track.cc b/content/renderer/media/media_stream_audio_track.cc
index 31c12a0..9eee57d 100644
--- a/content/renderer/media/media_stream_audio_track.cc
+++ b/content/renderer/media/media_stream_audio_track.cc
@@ -31,7 +31,7 @@
       track.source().getType() != blink::WebMediaStreamSource::TypeAudio) {
     return nullptr;
   }
-  return static_cast<MediaStreamAudioTrack*>(track.extraData());
+  return static_cast<MediaStreamAudioTrack*>(track.getExtraData());
 }
 
 void MediaStreamAudioTrack::Start(const base::Closure& stop_callback) {
diff --git a/content/renderer/media/media_stream_center.cc b/content/renderer/media/media_stream_center.cc
index 32d55a6..2f84bd8 100644
--- a/content/renderer/media/media_stream_center.cc
+++ b/content/renderer/media/media_stream_center.cc
@@ -53,7 +53,7 @@
 
 void CreateNativeVideoMediaStreamTrack(
     const blink::WebMediaStreamTrack& track) {
-  DCHECK(track.extraData() == NULL);
+  DCHECK(track.getExtraData() == NULL);
   blink::WebMediaStreamSource source = track.source();
   DCHECK_EQ(source.getType(), blink::WebMediaStreamSource::TypeVideo);
   MediaStreamVideoSource* native_source =
@@ -76,7 +76,7 @@
 
 void CreateNativeMediaStreamTrack(const blink::WebMediaStreamTrack& track,
                                   PeerConnectionDependencyFactory* factory) {
-  DCHECK(!track.isNull() && !track.extraData());
+  DCHECK(!track.isNull() && !track.getExtraData());
   DCHECK(!track.source().isNull());
 
   switch (track.source().getType()) {
@@ -132,7 +132,7 @@
     const blink::WebMediaStreamTrack& track) {
   DVLOG(1) << "MediaStreamCenter::createWebAudioSourceFromMediaStreamTrack";
   MediaStreamTrack* media_stream_track =
-      static_cast<MediaStreamTrack*>(track.extraData());
+      static_cast<MediaStreamTrack*>(track.getExtraData());
   if (!media_stream_track) {
     DLOG(ERROR) << "Native track missing for webaudio source.";
     return nullptr;
diff --git a/content/renderer/media/media_stream_track.cc b/content/renderer/media/media_stream_track.cc
index 7992e23..fa0cb90 100644
--- a/content/renderer/media/media_stream_track.cc
+++ b/content/renderer/media/media_stream_track.cc
@@ -9,8 +9,8 @@
 // static
 MediaStreamTrack* MediaStreamTrack::GetTrack(
     const blink::WebMediaStreamTrack& track) {
-  return track.isNull() ?
-      nullptr : static_cast<MediaStreamTrack*>(track.extraData());
+  return track.isNull() ? nullptr
+                        : static_cast<MediaStreamTrack*>(track.getExtraData());
 }
 
 MediaStreamTrack::MediaStreamTrack(bool is_local_track)
diff --git a/content/renderer/media/media_stream_video_track.cc b/content/renderer/media/media_stream_video_track.cc
index e9cc8e0..cae744b 100644
--- a/content/renderer/media/media_stream_video_track.cc
+++ b/content/renderer/media/media_stream_video_track.cc
@@ -212,7 +212,7 @@
 // static
 MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack(
      const blink::WebMediaStreamTrack& track) {
-  return static_cast<MediaStreamVideoTrack*>(track.extraData());
+  return static_cast<MediaStreamVideoTrack*>(track.getExtraData());
 }
 
 MediaStreamVideoTrack::MediaStreamVideoTrack(
diff --git a/content/renderer/media/media_stream_video_track.h b/content/renderer/media/media_stream_video_track.h
index bfcf419f..c6550926 100644
--- a/content/renderer/media/media_stream_video_track.h
+++ b/content/renderer/media/media_stream_video_track.h
@@ -21,7 +21,7 @@
 // MediaStreamVideoTrack is a video specific representation of a
 // blink::WebMediaStreamTrack in content. It is owned by the blink object
 // and can be retrieved from a blink object using
-// WebMediaStreamTrack::extraData() or MediaStreamVideoTrack::GetVideoTrack.
+// WebMediaStreamTrack::getExtraData() or MediaStreamVideoTrack::GetVideoTrack.
 class CONTENT_EXPORT MediaStreamVideoTrack : public MediaStreamTrack {
  public:
   // Help method to create a blink::WebMediaStreamTrack and a
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
index 10c6c047f1..3b315d2 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -768,7 +768,7 @@
   }
 
   void OnAddStreamImpl(scoped_ptr<RemoteMediaStreamImpl> stream) {
-    DCHECK(stream->webkit_stream().extraData()) << "Initialization not done";
+    DCHECK(stream->webkit_stream().getExtraData()) << "Initialization not done";
     if (handler_)
       handler_->OnAddStream(std::move(stream));
   }
@@ -1498,7 +1498,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(remote_streams_.find(stream->webrtc_stream().get()) ==
          remote_streams_.end());
-  DCHECK(stream->webkit_stream().extraData()) << "Initialization not done";
+  DCHECK(stream->webkit_stream().getExtraData()) << "Initialization not done";
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddStreamImpl");
 
   // Ownership is with remote_streams_ now.
diff --git a/content/renderer/media/speech_recognition_audio_sink_unittest.cc b/content/renderer/media/speech_recognition_audio_sink_unittest.cc
index 26256b4..67454d4 100644
--- a/content/renderer/media/speech_recognition_audio_sink_unittest.cc
+++ b/content/renderer/media/speech_recognition_audio_sink_unittest.cc
@@ -243,7 +243,7 @@
 
     // Get the native track from the blink track and initialize.
     native_track_ =
-        static_cast<WebRtcLocalAudioTrack*>(blink_track.extraData());
+        static_cast<WebRtcLocalAudioTrack*>(blink_track.getExtraData());
     native_track_->OnSetFormat(source_params_);
 
     // Create and initialize the consumer.
diff --git a/content/renderer/media/video_track_recorder.cc b/content/renderer/media/video_track_recorder.cc
index 390a0ff6..295209a0 100644
--- a/content/renderer/media/video_track_recorder.cc
+++ b/content/renderer/media/video_track_recorder.cc
@@ -386,7 +386,7 @@
           new VpxEncoder(use_vp9, on_encoded_video_callback, bits_per_second)) {
   DCHECK(main_render_thread_checker_.CalledOnValidThread());
   DCHECK(!track_.isNull());
-  DCHECK(track_.extraData());
+  DCHECK(track_.getExtraData());
 
   // StartFrameEncode() will be called on Render IO thread.
   AddToVideoTrack(this,
diff --git a/content/renderer/media/webmediaplayer_ms_compositor.cc b/content/renderer/media/webmediaplayer_ms_compositor.cc
index 7bd992d..ac82084 100644
--- a/content/renderer/media/webmediaplayer_ms_compositor.cc
+++ b/content/renderer/media/webmediaplayer_ms_compositor.cc
@@ -185,6 +185,7 @@
   base::AutoLock auto_lock(current_frame_lock_);
   ++total_frame_count_;
 
+  // With algorithm off, just let |current_frame_| hold the incoming |frame|.
   if (!rendering_frame_buffer_) {
     SetCurrentFrame(frame);
     return;
@@ -200,6 +201,9 @@
     return;
   }
 
+  // If we detect a bad frame without |render_time|, we switch off algorithm,
+  // because without |render_time|, algorithm cannot work.
+  // In general, this should not happen.
   base::TimeTicks render_time;
   if (!frame->metadata()->GetTimeTicks(
           media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
@@ -211,20 +215,25 @@
     return;
   }
 
-  timestamps_to_clock_times_[frame->timestamp()] = render_time;
-
-  rendering_frame_buffer_->EnqueueFrame(frame);
-
+  // The code below handles the case where UpdateCurrentFrame() callbacks stop.
+  // These callbacks can stop when the tab is hidden or the page area containing
+  // the video frame is scrolled out of view.
+  // Since some hardware decoders only have a limited number of output frames,
+  // we must aggressively release frames in this case.
   const base::TimeTicks now = base::TimeTicks::Now();
-  if (now <= last_deadline_max_)
-    return;
+  if (now > last_deadline_max_) {
+    // Note: the frame in |rendering_frame_buffer_| with lowest index is the
+    // same as |current_frame_|. Function SetCurrentFrame() handles whether
+    // to increase |dropped_frame_count_| for that frame, so here we should
+    // increase |dropped_frame_count_| by the count of all other frames.
+    dropped_frame_count_ += rendering_frame_buffer_->frames_queued() - 1;
+    rendering_frame_buffer_->Reset();
+    timestamps_to_clock_times_.clear();
+    SetCurrentFrame(frame);
+  }
 
-  // This shows vsyncs stops rendering frames. A probable cause is that the
-  // tab is not in the front. But we still have to let old frames go.
-  const base::TimeTicks deadline_max =
-      std::max(now, last_deadline_max_ + last_render_length_);
-
-  Render(deadline_max - last_render_length_, deadline_max);
+  timestamps_to_clock_times_[frame->timestamp()] = render_time;
+  rendering_frame_buffer_->EnqueueFrame(frame);
 }
 
 bool WebMediaPlayerMSCompositor::UpdateCurrentFrame(
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_adapter.h b/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
index eba23db..c4052550 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
+++ b/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
@@ -34,7 +34,7 @@
   ~WebRtcMediaStreamAdapter() override;
 
   bool IsEqual(const blink::WebMediaStream& web_stream) {
-    return web_stream_.extraData() == web_stream.extraData();
+    return web_stream_.getExtraData() == web_stream.getExtraData();
   }
 
   webrtc::MediaStreamInterface* webrtc_media_stream() {
diff --git a/content/renderer/mojo_context_state.cc b/content/renderer/mojo_context_state.cc
index 6d71589..4274fee 100644
--- a/content/renderer/mojo_context_state.cc
+++ b/content/renderer/mojo_context_state.cc
@@ -171,28 +171,30 @@
                  blink::WebURLRequest::FrameTypeNone,
                  ResourceFetcher::PLATFORM_LOADER,
                  base::Bind(&MojoContextState::OnFetchModuleComplete,
-                            base::Unretained(this), fetcher));
+                            base::Unretained(this), fetcher, id));
 }
 
 void MojoContextState::OnFetchModuleComplete(
     ResourceFetcher* fetcher,
+    const std::string& id,
     const blink::WebURLResponse& response,
     const std::string& data) {
-  DCHECK_EQ(module_prefix_,
-            response.url().string().utf8().substr(0, module_prefix_.size()));
-  const std::string module =
-      response.url().string().utf8().substr(module_prefix_.size());
+  if (response.isNull()) {
+    LOG(ERROR) << "Failed to fetch source for module \"" << id << "\"";
+    return;
+  }
+  DCHECK_EQ(module_prefix_ + id, response.url().string().utf8());
   // We can't delete fetch right now as the arguments to this function come from
   // it and are used below. Instead use a scope_ptr to cleanup.
   scoped_ptr<ResourceFetcher> deleter(fetcher);
   module_fetchers_.weak_erase(
       std::find(module_fetchers_.begin(), module_fetchers_.end(), fetcher));
   if (data.empty()) {
-    NOTREACHED();
-    return;  // TODO(sky): log something?
+    LOG(ERROR) << "Fetched empty source for module \"" << id << "\"";
+    return;
   }
 
-  runner_->Run(data, module);
+  runner_->Run(data, id);
 }
 
 void MojoContextState::OnDidAddPendingModule(
diff --git a/content/renderer/mojo_context_state.h b/content/renderer/mojo_context_state.h
index c9af262..eaca530 100644
--- a/content/renderer/mojo_context_state.h
+++ b/content/renderer/mojo_context_state.h
@@ -55,6 +55,7 @@
 
   // Callback once a module has finished downloading. Passes data to |runner_|.
   void OnFetchModuleComplete(ResourceFetcher* fetcher,
+                             const std::string& id,
                              const blink::WebURLResponse& response,
                              const std::string& data);
 
diff --git a/content/renderer/mus/compositor_mus_connection.h b/content/renderer/mus/compositor_mus_connection.h
index 7b0f6961..70f8b2d 100644
--- a/content/renderer/mus/compositor_mus_connection.h
+++ b/content/renderer/mus/compositor_mus_connection.h
@@ -6,11 +6,13 @@
 #define CONTENT_RENDERER_MUS_COMPOSITOR_MUS_CONNECTION_H_
 
 #include "base/bind.h"
+#include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "components/mus/public/cpp/input_event_handler.h"
 #include "components/mus/public/cpp/window.h"
 #include "components/mus/public/cpp/window_tree_connection.h"
 #include "components/mus/public/cpp/window_tree_delegate.h"
+#include "content/common/content_export.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
 
 namespace content {
@@ -23,9 +25,9 @@
 // threads. CompositorMusConnection is constructed on the main thread. By
 // default all other methods are assumed to run on the compositor thread unless
 // explicited suffixed with OnMainThread.
-class CompositorMusConnection
-    : public mus::WindowTreeDelegate,
-      public mus::InputEventHandler,
+class CONTENT_EXPORT CompositorMusConnection
+    : NON_EXPORTED_BASE(public mus::WindowTreeDelegate),
+      NON_EXPORTED_BASE(public mus::InputEventHandler),
       public base::RefCountedThreadSafe<CompositorMusConnection> {
  public:
   // Created on main thread.
diff --git a/content/renderer/mus/render_widget_mus_connection.h b/content/renderer/mus/render_widget_mus_connection.h
index 26f1b4b..fea8db3b 100644
--- a/content/renderer/mus/render_widget_mus_connection.h
+++ b/content/renderer/mus/render_widget_mus_connection.h
@@ -9,6 +9,7 @@
 #include "base/threading/thread_checker.h"
 #include "cc/output/output_surface.h"
 #include "components/mus/public/cpp/window_surface.h"
+#include "content/common/content_export.h"
 #include "content/renderer/input/render_widget_input_handler_delegate.h"
 #include "content/renderer/mus/compositor_mus_connection.h"
 
@@ -17,7 +18,8 @@
 class InputHandlerManager;
 
 // Use on main thread.
-class RenderWidgetMusConnection : public RenderWidgetInputHandlerDelegate {
+class CONTENT_EXPORT RenderWidgetMusConnection
+    : public RenderWidgetInputHandlerDelegate {
  public:
   // Bind to a WindowTreeClient request.
   void Bind(mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request);
diff --git a/content/renderer/npapi/webplugin_impl.cc b/content/renderer/npapi/webplugin_impl.cc
index 2ad057c..eeaef51 100644
--- a/content/renderer/npapi/webplugin_impl.cc
+++ b/content/renderer/npapi/webplugin_impl.cc
@@ -21,7 +21,6 @@
 #include "cc/layers/io_surface_layer.h"
 #include "cc/layers/layer_settings.h"
 #include "content/child/appcache/web_application_cache_host_impl.h"
-#include "content/child/multipart_response_delegate.h"
 #include "content/child/npapi/plugin_host.h"
 #include "content/child/npapi/plugin_instance.h"
 #include "content/child/npapi/webplugin_delegate_impl.h"
diff --git a/content/renderer/origin_trials/trial_token.cc b/content/renderer/origin_trials/trial_token.cc
index 5cf69ac6..2cd9f186 100644
--- a/content/renderer/origin_trials/trial_token.cc
+++ b/content/renderer/origin_trials/trial_token.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "url/gurl.h"
 #include "url/origin.h"
 
 namespace content {
@@ -77,64 +78,50 @@
   }
 
   // Ensure that the origin is a valid (non-unique) origin URL
-  GURL origin_url(origin_string);
-  if (url::Origin(origin_url).unique()) {
+  url::Origin origin = url::Origin(GURL(origin_string));
+  if (origin.unique()) {
     return nullptr;
   }
 
   // Signed data is (origin + "|" + feature_name + "|" + expiry).
   std::string data = token_contents.substr(signature.length() + 1);
 
-  return make_scoped_ptr(new TrialToken(version, signature, data, origin_url,
+  return make_scoped_ptr(new TrialToken(version, signature, data, origin,
                                         feature_name, expiry_timestamp));
 }
 
-TrialToken::TrialToken(uint8_t version,
-                       const std::string& signature,
-                       const std::string& data,
-                       const GURL& origin,
-                       const std::string& feature_name,
-                       uint64_t expiry_timestamp)
-    : version_(version),
-      signature_(signature),
-      data_(data),
-      origin_(origin),
-      feature_name_(feature_name),
-      expiry_timestamp_(expiry_timestamp) {}
-
-bool TrialToken::IsAppropriate(const std::string& origin,
-                               const std::string& feature_name) const {
+bool TrialToken::IsAppropriate(const url::Origin& origin,
+                               base::StringPiece feature_name) const {
   return ValidateOrigin(origin) && ValidateFeatureName(feature_name);
 }
 
 bool TrialToken::IsValid(const base::Time& now,
-                         const base::StringPiece& public_key) const {
+                         base::StringPiece public_key) const {
   // TODO(iclelland): Allow for multiple signing keys, and iterate over all
   // active keys here. https://crbug.com/543220
   return ValidateDate(now) && ValidateSignature(public_key);
 }
 
-bool TrialToken::ValidateOrigin(const std::string& origin) const {
-  return GURL(origin) == origin_;
+bool TrialToken::ValidateOrigin(const url::Origin& origin) const {
+  return origin == origin_;
 }
 
-bool TrialToken::ValidateFeatureName(const std::string& feature_name) const {
+bool TrialToken::ValidateFeatureName(base::StringPiece feature_name) const {
   return feature_name == feature_name_;
 }
 
 bool TrialToken::ValidateDate(const base::Time& now) const {
-  base::Time expiry_time = base::Time::FromDoubleT((double)expiry_timestamp_);
-  return expiry_time > now;
+  return expiry_time_ > now;
 }
 
-bool TrialToken::ValidateSignature(const base::StringPiece& public_key) const {
+bool TrialToken::ValidateSignature(base::StringPiece public_key) const {
   return ValidateSignature(signature_, data_, public_key);
 }
 
 // static
 bool TrialToken::ValidateSignature(const std::string& signature_text,
                                    const std::string& data,
-                                   const base::StringPiece& public_key) {
+                                   base::StringPiece public_key) {
   // Public key must be 32 bytes long for Ed25519.
   CHECK_EQ(public_key.length(), 32UL);
 
@@ -156,4 +143,17 @@
   return (result != 0);
 }
 
+TrialToken::TrialToken(uint8_t version,
+                       const std::string& signature,
+                       const std::string& data,
+                       const url::Origin& origin,
+                       const std::string& feature_name,
+                       uint64_t expiry_timestamp)
+    : version_(version),
+      signature_(signature),
+      data_(data),
+      origin_(origin),
+      feature_name_(feature_name),
+      expiry_time_(base::Time::FromDoubleT(expiry_timestamp)) {}
+
 }  // namespace content
diff --git a/content/renderer/origin_trials/trial_token.h b/content/renderer/origin_trials/trial_token.h
index 7ad75df5..216c9b9 100644
--- a/content/renderer/origin_trials/trial_token.h
+++ b/content/renderer/origin_trials/trial_token.h
@@ -11,7 +11,7 @@
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "content/common/content_export.h"
-#include "url/gurl.h"
+#include "url/origin.h"
 
 namespace content {
 
@@ -40,37 +40,36 @@
   // Returns true if this feature is appropriate for use by the given origin,
   // for the given feature name. This does not check whether the signature is
   // valid, or whether the token itself has expired.
-  bool IsAppropriate(const std::string& origin,
-                     const std::string& featureName) const;
+  bool IsAppropriate(const url::Origin& origin,
+                     base::StringPiece feature_name) const;
 
   // Returns true if this token has a valid signature, and has not expired.
-  bool IsValid(const base::Time& now,
-               const base::StringPiece& public_key) const;
+  bool IsValid(const base::Time& now, base::StringPiece public_key) const;
 
   uint8_t version() { return version_; }
   std::string signature() { return signature_; }
   std::string data() { return data_; }
-  GURL origin() { return origin_; }
+  url::Origin origin() { return origin_; }
   std::string feature_name() { return feature_name_; }
-  uint64_t expiry_timestamp() { return expiry_timestamp_; }
+  base::Time expiry_time() { return expiry_time_; }
 
  protected:
   friend class TrialTokenTest;
 
-  bool ValidateOrigin(const std::string& origin) const;
-  bool ValidateFeatureName(const std::string& feature_name) const;
+  bool ValidateOrigin(const url::Origin& origin) const;
+  bool ValidateFeatureName(base::StringPiece feature_name) const;
   bool ValidateDate(const base::Time& now) const;
-  bool ValidateSignature(const base::StringPiece& public_key) const;
+  bool ValidateSignature(base::StringPiece public_key) const;
 
   static bool ValidateSignature(const std::string& signature_text,
                                 const std::string& data,
-                                const base::StringPiece& public_key);
+                                base::StringPiece public_key);
 
  private:
   TrialToken(uint8_t version,
              const std::string& signature,
              const std::string& data,
-             const GURL& origin,
+             const url::Origin& origin,
              const std::string& feature_name,
              uint64_t expiry_timestamp);
 
@@ -96,14 +95,13 @@
   std::string data_;
 
   // The origin for which this token is valid. Must be a secure origin.
-  GURL origin_;
+  url::Origin origin_;
 
   // The name of the experimental feature which this token enables.
   std::string feature_name_;
 
-  // The time until which this token should be considered valid, in UTC, as
-  // seconds since the Unix epoch.
-  uint64_t expiry_timestamp_;
+  // The time until which this token should be considered valid.
+  base::Time expiry_time_;
 };
 
 }  // namespace content
diff --git a/content/renderer/origin_trials/trial_token_unittest.cc b/content/renderer/origin_trials/trial_token_unittest.cc
index 2552152..e7e52e7e 100644
--- a/content/renderer/origin_trials/trial_token_unittest.cc
+++ b/content/renderer/origin_trials/trial_token_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/test/simple_test_clock.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace content {
 
@@ -113,7 +114,10 @@
 class TrialTokenTest : public testing::Test {
  public:
   TrialTokenTest()
-      : correct_public_key_(
+      : expected_origin_(GURL(kExpectedOrigin)),
+        invalid_origin_(GURL(kInvalidOrigin)),
+        insecure_origin_(GURL(kInsecureOrigin)),
+        correct_public_key_(
             base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey),
                               arraysize(kTestPublicKey))),
         incorrect_public_key_(
@@ -121,7 +125,7 @@
                               arraysize(kTestPublicKey2))) {}
 
  protected:
-  bool ValidateOrigin(TrialToken* token, const char* origin) {
+  bool ValidateOrigin(TrialToken* token, const url::Origin origin) {
     return token->ValidateOrigin(origin);
   }
 
@@ -138,10 +142,12 @@
     return token->ValidateSignature(public_key);
   }
 
-  const base::StringPiece& correct_public_key() { return correct_public_key_; }
-  const base::StringPiece& incorrect_public_key() {
-    return incorrect_public_key_;
-  }
+  base::StringPiece correct_public_key() { return correct_public_key_; }
+  base::StringPiece incorrect_public_key() { return incorrect_public_key_; }
+
+  const url::Origin expected_origin_;
+  const url::Origin invalid_origin_;
+  const url::Origin insecure_origin_;
 
  private:
   base::StringPiece correct_public_key_;
@@ -168,16 +174,16 @@
   EXPECT_EQ(kExpectedFeatureName, token->feature_name());
   EXPECT_EQ(kExpectedSignature, token->signature());
   EXPECT_EQ(kExpectedData, token->data());
-  EXPECT_EQ(GURL(kExpectedOrigin), token->origin());
-  EXPECT_EQ(kExpectedExpiry, token->expiry_timestamp());
+  EXPECT_EQ(expected_origin_, token->origin());
+  EXPECT_EQ(base::Time::FromDoubleT(kExpectedExpiry), token->expiry_time());
 }
 
 TEST_F(TrialTokenTest, ValidateValidToken) {
   scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken);
   ASSERT_TRUE(token);
-  EXPECT_TRUE(ValidateOrigin(token.get(), kExpectedOrigin));
-  EXPECT_FALSE(ValidateOrigin(token.get(), kInvalidOrigin));
-  EXPECT_FALSE(ValidateOrigin(token.get(), kInsecureOrigin));
+  EXPECT_TRUE(ValidateOrigin(token.get(), expected_origin_));
+  EXPECT_FALSE(ValidateOrigin(token.get(), invalid_origin_));
+  EXPECT_FALSE(ValidateOrigin(token.get(), insecure_origin_));
   EXPECT_TRUE(ValidateFeatureName(token.get(), kExpectedFeatureName));
   EXPECT_FALSE(ValidateFeatureName(token.get(), kInvalidFeatureName));
   EXPECT_FALSE(ValidateFeatureName(
@@ -193,14 +199,14 @@
 TEST_F(TrialTokenTest, TokenIsAppropriateForOriginAndFeature) {
   scoped_ptr<TrialToken> token = TrialToken::Parse(kSampleToken);
   ASSERT_TRUE(token);
-  EXPECT_TRUE(token->IsAppropriate(kExpectedOrigin, kExpectedFeatureName));
-  EXPECT_FALSE(token->IsAppropriate(kExpectedOrigin,
+  EXPECT_TRUE(token->IsAppropriate(expected_origin_, kExpectedFeatureName));
+  EXPECT_FALSE(token->IsAppropriate(expected_origin_,
                                     base::ToUpperASCII(kExpectedFeatureName)));
-  EXPECT_FALSE(token->IsAppropriate(kExpectedOrigin,
+  EXPECT_FALSE(token->IsAppropriate(expected_origin_,
                                     base::ToLowerASCII(kExpectedFeatureName)));
-  EXPECT_FALSE(token->IsAppropriate(kInvalidOrigin, kExpectedFeatureName));
-  EXPECT_FALSE(token->IsAppropriate(kInsecureOrigin, kExpectedFeatureName));
-  EXPECT_FALSE(token->IsAppropriate(kExpectedOrigin, kInvalidFeatureName));
+  EXPECT_FALSE(token->IsAppropriate(invalid_origin_, kExpectedFeatureName));
+  EXPECT_FALSE(token->IsAppropriate(insecure_origin_, kExpectedFeatureName));
+  EXPECT_FALSE(token->IsAppropriate(expected_origin_, kInvalidFeatureName));
 }
 
 TEST_F(TrialTokenTest, ValidateValidSignature) {
diff --git a/content/renderer/origin_trials/trial_token_validator.cc b/content/renderer/origin_trials/trial_token_validator.cc
index 1df8dc78..f34afd1 100644
--- a/content/renderer/origin_trials/trial_token_validator.cc
+++ b/content/renderer/origin_trials/trial_token_validator.cc
@@ -15,7 +15,7 @@
 TrialTokenValidator::~TrialTokenValidator() {}
 
 bool TrialTokenValidator::validateToken(const blink::WebString& token,
-                                        const blink::WebString& origin,
+                                        const blink::WebSecurityOrigin& origin,
                                         const blink::WebString& featureName) {
   scoped_ptr<TrialToken> trial_token = TrialToken::Parse(token.utf8());
 
@@ -26,7 +26,7 @@
       content_client->renderer()->GetOriginTrialPublicKey();
 
   return !public_key.empty() && trial_token &&
-         trial_token->IsAppropriate(origin.utf8(), featureName.utf8()) &&
+         trial_token->IsAppropriate(origin, featureName.utf8()) &&
          trial_token->IsValid(base::Time::Now(), public_key);
 }
 
diff --git a/content/renderer/origin_trials/trial_token_validator.h b/content/renderer/origin_trials/trial_token_validator.h
index a0ce6c2..4d877fc 100644
--- a/content/renderer/origin_trials/trial_token_validator.h
+++ b/content/renderer/origin_trials/trial_token_validator.h
@@ -23,7 +23,7 @@
 
   // blink::WebTrialTokenValidator implementation
   bool validateToken(const blink::WebString& token,
-                     const blink::WebString& origin,
+                     const blink::WebSecurityOrigin& origin,
                      const blink::WebString& featureName) override;
 
  private:
diff --git a/content/renderer/origin_trials/trial_token_validator_unittest.cc b/content/renderer/origin_trials/trial_token_validator_unittest.cc
index 2bdb8883..858aa6f 100644
--- a/content/renderer/origin_trials/trial_token_validator_unittest.cc
+++ b/content/renderer/origin_trials/trial_token_validator_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/time/time.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
 
 namespace content {
 
@@ -84,7 +85,10 @@
 
 class TrialTokenValidatorTest : public testing::Test {
  public:
-  TrialTokenValidatorTest() {
+  TrialTokenValidatorTest()
+      : appropriate_origin_(GURL(kAppropriateOrigin)),
+        inappropriate_origin_(GURL(kInappropriateOrigin)),
+        insecure_origin_(GURL(kInsecureOrigin)) {
     SetPublicKey(kTestPublicKey);
     SetRendererClientForTesting(&test_content_renderer_client_);
   }
@@ -94,6 +98,9 @@
   }
 
   TrialTokenValidator trial_token_validator_;
+  const url::Origin appropriate_origin_;
+  const url::Origin inappropriate_origin_;
+  const url::Origin insecure_origin_;
 
  private:
   TestContentRendererClient test_content_renderer_client_;
@@ -101,40 +108,40 @@
 
 TEST_F(TrialTokenValidatorTest, ValidateValidToken) {
   EXPECT_TRUE(trial_token_validator_.validateToken(
-      kSampleToken, kAppropriateOrigin, kAppropriateFeatureName));
+      kSampleToken, appropriate_origin_, kAppropriateFeatureName));
 }
 
 TEST_F(TrialTokenValidatorTest, ValidateInappropriateOrigin) {
   EXPECT_FALSE(TrialTokenValidator().validateToken(
-      kSampleToken, kInappropriateOrigin, kAppropriateFeatureName));
+      kSampleToken, inappropriate_origin_, kAppropriateFeatureName));
   EXPECT_FALSE(TrialTokenValidator().validateToken(
-      kSampleToken, kInsecureOrigin, kAppropriateFeatureName));
+      kSampleToken, insecure_origin_, kAppropriateFeatureName));
 }
 
 TEST_F(TrialTokenValidatorTest, ValidateInappropriateFeature) {
   EXPECT_FALSE(TrialTokenValidator().validateToken(
-      kSampleToken, kAppropriateOrigin, kInappropriateFeatureName));
+      kSampleToken, appropriate_origin_, kInappropriateFeatureName));
 }
 
 TEST_F(TrialTokenValidatorTest, ValidateInvalidSignature) {
   EXPECT_FALSE(TrialTokenValidator().validateToken(
-      kInvalidSignatureToken, kAppropriateOrigin, kAppropriateFeatureName));
+      kInvalidSignatureToken, appropriate_origin_, kAppropriateFeatureName));
 }
 
 TEST_F(TrialTokenValidatorTest, ValidateUnparsableToken) {
   EXPECT_FALSE(TrialTokenValidator().validateToken(
-      kUnparsableToken, kAppropriateOrigin, kAppropriateFeatureName));
+      kUnparsableToken, appropriate_origin_, kAppropriateFeatureName));
 }
 
 TEST_F(TrialTokenValidatorTest, ValidateExpiredToken) {
   EXPECT_FALSE(TrialTokenValidator().validateToken(
-      kExpiredToken, kAppropriateOrigin, kAppropriateFeatureName));
+      kExpiredToken, appropriate_origin_, kAppropriateFeatureName));
 }
 
 TEST_F(TrialTokenValidatorTest, ValidateValidTokenWithIncorrectKey) {
   SetPublicKey(kTestPublicKey2);
   EXPECT_FALSE(TrialTokenValidator().validateToken(
-      kSampleToken, kAppropriateOrigin, kAppropriateFeatureName));
+      kSampleToken, appropriate_origin_, kAppropriateFeatureName));
 }
 
 }  // namespace content
diff --git a/content/renderer/p2p/host_address_request.h b/content/renderer/p2p/host_address_request.h
index 1734d2a1..dfcb14f 100644
--- a/content/renderer/p2p/host_address_request.h
+++ b/content/renderer/p2p/host_address_request.h
@@ -13,7 +13,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
-#include "net/base/ip_address_number.h"
+#include "net/base/ip_address.h"
 #include "third_party/webrtc/base/asyncresolverinterface.h"
 
 namespace base {
diff --git a/content/renderer/p2p/ipc_socket_factory.cc b/content/renderer/p2p/ipc_socket_factory.cc
index 779bb216..724b1ed 100644
--- a/content/renderer/p2p/ipc_socket_factory.cc
+++ b/content/renderer/p2p/ipc_socket_factory.cc
@@ -24,6 +24,7 @@
 #include "content/renderer/p2p/socket_client_impl.h"
 #include "content/renderer/p2p/socket_dispatcher.h"
 #include "jingle/glue/utils.h"
+#include "net/base/ip_address.h"
 #include "third_party/webrtc/base/asyncpacketsocket.h"
 
 namespace content {
diff --git a/content/renderer/p2p/socket_dispatcher.h b/content/renderer/p2p/socket_dispatcher.h
index 527921b3..3a80f2a 100644
--- a/content/renderer/p2p/socket_dispatcher.h
+++ b/content/renderer/p2p/socket_dispatcher.h
@@ -35,6 +35,7 @@
 #include "content/common/p2p_socket_type.h"
 #include "content/renderer/p2p/network_list_manager.h"
 #include "ipc/message_filter.h"
+#include "net/base/ip_address.h"
 #include "net/base/ip_address_number.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/network_interfaces.h"
diff --git a/content/renderer/pepper/v8_var_converter_unittest.cc b/content/renderer/pepper/v8_var_converter_unittest.cc
index cd07abb..e030ffdb 100644
--- a/content/renderer/pepper/v8_var_converter_unittest.cc
+++ b/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -29,6 +29,7 @@
 #include "ppapi/shared_impl/var.h"
 #include "ppapi/shared_impl/var_tracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 using ppapi::ArrayBufferVar;
@@ -403,6 +404,7 @@
     v8::Local<v8::Context> context =
         v8::Local<v8::Context>::New(isolate_, context_);
     v8::Context::Scope context_scope(context);
+    blink::WebScopedMicrotaskSuppression microtasks_scope;
 
     const char* source =
         "(function() {"
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 125edab..69c7e94f 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -325,7 +325,7 @@
 
 WebURLResponseExtraDataImpl* GetExtraDataFromResponse(
     const WebURLResponse& response) {
-  return static_cast<WebURLResponseExtraDataImpl*>(response.extraData());
+  return static_cast<WebURLResponseExtraDataImpl*>(response.getExtraData());
 }
 
 void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
@@ -599,7 +599,7 @@
           request->inputPerfMetricReportPolicy());
 
   const RequestExtraData* extra_data =
-      static_cast<RequestExtraData*>(request->extraData());
+      static_cast<RequestExtraData*>(request->getExtraData());
   DCHECK(extra_data);
   return CommonNavigationParams(
       request->url(), referrer, extra_data->transition_type(),
@@ -3760,9 +3760,9 @@
   WebString custom_user_agent;
   WebString requested_with;
   scoped_ptr<StreamOverrideParameters> stream_override;
-  if (request.extraData()) {
+  if (request.getExtraData()) {
     RequestExtraData* old_extra_data =
-        static_cast<RequestExtraData*>(request.extraData());
+        static_cast<RequestExtraData*>(request.getExtraData());
 
     custom_user_agent = old_extra_data->custom_user_agent();
     if (!custom_user_agent.isNull()) {
@@ -4491,8 +4491,8 @@
     params.base_url = frame->document().baseURL();
 
   GetRedirectChain(ds, &params.redirects);
-  params.should_update_history = !ds->hasUnreachableURL() &&
-      !response.isMultipartPayload() && (response.httpStatusCode() != 404);
+  params.should_update_history =
+      !ds->hasUnreachableURL() && response.httpStatusCode() != 404;
 
   params.searchable_form_url = internal_data->searchable_form_url();
   params.searchable_form_encoding = internal_data->searchable_form_encoding();
@@ -5735,11 +5735,11 @@
   willSendRequest(frame_, 0, *request, blink::WebURLResponse());
 
   // Update the transition type of the request for client side redirects.
-  if (!request->extraData())
+  if (!request->getExtraData())
     request->setExtraData(new RequestExtraData());
   if (is_client_redirect) {
     RequestExtraData* extra_data =
-        static_cast<RequestExtraData*>(request->extraData());
+        static_cast<RequestExtraData*>(request->getExtraData());
     extra_data->set_transition_type(ui::PageTransitionFromInt(
         extra_data->transition_type() | ui::PAGE_TRANSITION_CLIENT_REDIRECT));
   }
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 202c5f9..b1b76c9 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1177,10 +1177,13 @@
 #if defined(OS_ANDROID)
   SynchronousCompositorFactory* sync_compositor_factory =
       SynchronousCompositorFactory::GetInstance();
+  const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
   bool using_ipc_sync_compositing =
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kIPCSyncCompositing);
+      cmd_line->HasSwitch(switches::kIPCSyncCompositing);
+  bool sync_input_for_sync_compositing =
+      cmd_line->HasSwitch(switches::kSyncInputForSyncCompositor);
   DCHECK(!sync_compositor_factory || !using_ipc_sync_compositing);
+  DCHECK(!sync_input_for_sync_compositing || using_ipc_sync_compositing);
 
   if (sync_compositor_factory) {
     compositor_task_runner_ =
@@ -1201,16 +1204,23 @@
                    false));
   }
 
-  InputHandlerManagerClient* input_handler_manager_client = NULL;
+  InputHandlerManagerClient* input_handler_manager_client = nullptr;
+  SynchronousInputHandlerProxyClient* synchronous_input_handler_proxy_client =
+      nullptr;
 #if defined(OS_ANDROID)
   if (using_ipc_sync_compositing) {
     sync_compositor_message_filter_ =
         new SynchronousCompositorFilter(compositor_task_runner_);
     AddFilter(sync_compositor_message_filter_.get());
-    input_handler_manager_client = sync_compositor_message_filter_.get();
+    if (sync_input_for_sync_compositing)
+      input_handler_manager_client = sync_compositor_message_filter_.get();
+    synchronous_input_handler_proxy_client =
+        sync_compositor_message_filter_.get();
   } else if (sync_compositor_factory) {
     input_handler_manager_client =
         sync_compositor_factory->GetInputHandlerManagerClient();
+    synchronous_input_handler_proxy_client =
+        sync_compositor_factory->GetSynchronousInputHandlerProxyClient();
   }
 #endif
   if (!input_handler_manager_client) {
@@ -1223,7 +1233,7 @@
   }
   input_handler_manager_.reset(new InputHandlerManager(
       compositor_task_runner_, input_handler_manager_client,
-      renderer_scheduler_.get()));
+      synchronous_input_handler_proxy_client, renderer_scheduler_.get()));
 }
 
 void RenderThreadImpl::EnsureWebKitInitialized() {
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index a47e73df..6e85b394 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -2063,7 +2063,7 @@
       DocumentState::FromDataSource(GetMainFrame()->dataSource()));
   ASSERT_TRUE(provider);
   extra_data = static_cast<RequestExtraData*>(
-      GetMainFrame()->dataSource()->request().extraData());
+      GetMainFrame()->dataSource()->request().getExtraData());
   ASSERT_TRUE(extra_data);
   EXPECT_EQ(extra_data->service_worker_provider_id(),
             provider->provider_id());
@@ -2076,7 +2076,7 @@
   ASSERT_TRUE(provider);
   EXPECT_NE(provider1_id, provider->provider_id());
   extra_data = static_cast<RequestExtraData*>(
-      GetMainFrame()->dataSource()->request().extraData());
+      GetMainFrame()->dataSource()->request().getExtraData());
   ASSERT_TRUE(extra_data);
   EXPECT_EQ(extra_data->service_worker_provider_id(),
             provider->provider_id());
@@ -2087,7 +2087,7 @@
   request.setRequestContext(blink::WebURLRequest::RequestContextSubresource);
   blink::WebURLResponse redirect_response;
   frame()->willSendRequest(GetMainFrame(), 0, request, redirect_response);
-  extra_data = static_cast<RequestExtraData*>(request.extraData());
+  extra_data = static_cast<RequestExtraData*>(request.getExtraData());
   ASSERT_TRUE(extra_data);
   EXPECT_EQ(extra_data->service_worker_provider_id(),
             provider->provider_id());
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 807be31..00db538 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1958,7 +1958,7 @@
                                    const WebImage& image,
                                    const WebPoint& webImageOffset) {
   blink::WebRect offset_in_window(webImageOffset.x, webImageOffset.y, 0, 0);
-  convertViewportToWindow(&offset_in_window);
+  ConvertViewportToWindowViaWidget(&offset_in_window);
   DropData drop_data(DropDataBuilder::Build(data));
   drop_data.referrer_policy = frame->document().referrerPolicy();
   gfx::Vector2d imageOffset(offset_in_window.x, offset_in_window.y);
@@ -1989,7 +1989,7 @@
   if (!toNode.isNull() && toNode.isElementNode()) {
     WebElement element = const_cast<WebNode&>(toNode).to<WebElement>();
     blink::WebRect rect = element.boundsInViewport();
-    convertViewportToWindow(&rect);
+    ConvertViewportToWindowViaWidget(&rect);
     node_bounds = gfx::Rect(rect);
     is_editable = element.isEditable();
   }
@@ -2187,14 +2187,14 @@
   return renderer_preferences_.accept_languages;
 }
 
-void RenderViewImpl::convertViewportToWindow(blink::WebRect* rect) {
-  RenderWidget::convertViewportToWindow(rect);
+void RenderViewImpl::ConvertViewportToWindowViaWidget(blink::WebRect* rect) {
+  convertViewportToWindow(rect);
 }
 
 gfx::RectF RenderViewImpl::ElementBoundsInWindow(
     const blink::WebElement& element) {
   blink::WebRect bounding_box_in_window = element.boundsInViewport();
-  convertViewportToWindow(&bounding_box_in_window);
+  ConvertViewportToWindowViaWidget(&bounding_box_in_window);
   return gfx::RectF(bounding_box_in_window);
 }
 
@@ -3076,7 +3076,7 @@
     // use the caret position as an empty range for now. It will be updated
     // after Pepper API equips features related to surrounding text retrieval.
     blink::WebRect caret(focused_pepper_plugin_->GetCaretBounds());
-    convertViewportToWindow(&caret);
+    ConvertViewportToWindowViaWidget(&caret);
     *start = caret;
     *end = caret;
     return;
@@ -3117,7 +3117,7 @@
       bounds_in_window->clear();
       return;
     }
-    convertViewportToWindow(&webrect);
+    ConvertViewportToWindowViaWidget(&webrect);
     bounds_in_window->push_back(webrect);
   }
 }
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 4af994a..8e4878ff 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -444,7 +444,7 @@
                               TopControlsState current,
                               bool animate) override;
 #endif
-  void convertViewportToWindow(blink::WebRect* rect) override;
+  void ConvertViewportToWindowViaWidget(blink::WebRect* rect) override;
   gfx::RectF ElementBoundsInWindow(const blink::WebElement& element) override;
   float GetDeviceScaleFactorForTest() const override;
 
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 2347d801..b8b4ad4f 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1578,10 +1578,6 @@
 }
 
 void RenderWidget::UpdateCompositionInfo(bool should_update_range) {
-#if defined(OS_ANDROID)
-// TODO(yukawa): Start sending character bounds when the browser side
-// implementation becomes ready (crbug.com/424866).
-#else
   TRACE_EVENT0("renderer", "RenderWidget::UpdateCompositionInfo");
   gfx::Range range = gfx::Range();
   if (should_update_range) {
@@ -1598,7 +1594,6 @@
   composition_range_ = range;
   Send(new InputHostMsg_ImeCompositionRangeChanged(
       routing_id(), composition_range_, composition_character_bounds_));
-#endif
 }
 
 void RenderWidget::convertViewportToWindow(blink::WebRect* rect) {
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
index 678e20d..661319b2 100644
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -19,7 +19,6 @@
 #include "base/strings/string_util.h"
 #include "base/sys_info.h"
 #include "base/threading/platform_thread.h"
-#include "base/timer/elapsed_timer.h"
 #include "base/timer/hi_res_timer_manager.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
@@ -94,12 +93,7 @@
 
   const base::CommandLine& parsed_command_line = parameters.command_line;
 
-  {
-    base::ElapsedTimer timer;
-    MojoShellConnectionImpl::Create();
-    UMA_HISTOGRAM_TIMES("Mojo.Shell.RenderProcessInitializationTime",
-                        timer.Elapsed());
-  }
+  MojoShellConnectionImpl::Create();
 
 #if defined(OS_MACOSX)
   base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool;
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index a6cec82..28fdecb 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -18,6 +18,7 @@
 #include "content/child/notifications/notification_data_conversions.h"
 #include "content/child/request_extra_data.h"
 #include "content/child/service_worker/service_worker_dispatcher.h"
+#include "content/child/service_worker/service_worker_handle_reference.h"
 #include "content/child/service_worker/service_worker_network_provider.h"
 #include "content/child/service_worker/service_worker_provider_context.h"
 #include "content/child/service_worker/service_worker_registration_handle_reference.h"
@@ -97,7 +98,7 @@
                        blink::WebURLRequest& request) override {
     ServiceWorkerNetworkProvider* provider =
         ServiceWorkerNetworkProvider::FromDocumentState(
-            static_cast<DataSourceExtraData*>(data_source->extraData()));
+            static_cast<DataSourceExtraData*>(data_source->getExtraData()));
     scoped_ptr<RequestExtraData> extra_data(new RequestExtraData);
     extra_data->set_service_worker_provider_id(provider->provider_id());
     extra_data->set_originated_from_service_worker(true);
@@ -737,15 +738,33 @@
 
 void ServiceWorkerContextClient::OnExtendableMessageEvent(
     int request_id,
-    const base::string16& message,
-    const std::vector<TransferredMessagePort>& sent_message_ports,
-    const std::vector<int>& new_routing_ids) {
+    const ServiceWorkerMsg_ExtendableMessageEvent_Params& params) {
   TRACE_EVENT0("ServiceWorker",
                "ServiceWorkerContextClient::OnExtendableMessageEvent");
   blink::WebMessagePortChannelArray ports =
-      WebMessagePortChannelImpl::CreatePorts(
-          sent_message_ports, new_routing_ids, main_thread_task_runner_);
-  proxy_->dispatchExtendableMessageEvent(request_id, message, ports);
+      WebMessagePortChannelImpl::CreatePorts(params.message_ports,
+                                             params.new_routing_ids,
+                                             main_thread_task_runner_);
+  if (params.source.client_info.IsValid()) {
+    blink::WebServiceWorkerClientInfo web_client =
+        ToWebServiceWorkerClientInfo(params.source.client_info);
+    proxy_->dispatchExtendableMessageEvent(
+        request_id, params.message, params.source_origin, ports, web_client);
+    return;
+  }
+
+  DCHECK(params.source.service_worker_info.IsValid());
+  scoped_ptr<ServiceWorkerHandleReference> handle =
+      ServiceWorkerHandleReference::Adopt(params.source.service_worker_info,
+                                          sender_.get());
+  ServiceWorkerDispatcher* dispatcher =
+      ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
+          sender_.get(), main_thread_task_runner_.get());
+  scoped_refptr<WebServiceWorkerImpl> worker =
+      dispatcher->GetOrCreateServiceWorker(std::move(handle));
+  proxy_->dispatchExtendableMessageEvent(
+      request_id, params.message, params.source_origin, ports,
+      WebServiceWorkerImpl::CreateHandle(worker));
 }
 
 void ServiceWorkerContextClient::OnInstallEvent(int request_id) {
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h
index d16a093..8642547 100644
--- a/content/renderer/service_worker/service_worker_context_client.h
+++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -30,6 +30,8 @@
 #include "third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h"
 #include "v8/include/v8.h"
 
+struct ServiceWorkerMsg_ExtendableMessageEvent_Params;
+
 namespace base {
 class SingleThreadTaskRunner;
 class TaskRunner;
@@ -196,9 +198,7 @@
   void OnActivateEvent(int request_id);
   void OnExtendableMessageEvent(
       int request_id,
-      const base::string16& message,
-      const std::vector<TransferredMessagePort>& sent_message_ports,
-      const std::vector<int>& new_routing_ids);
+      const ServiceWorkerMsg_ExtendableMessageEvent_Params& params);
   void OnInstallEvent(int request_id);
   void OnFetchEvent(int request_id, const ServiceWorkerFetchRequest& request);
   void OnNotificationClickEvent(
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
index a41be61..b1f001c7 100644
--- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -113,7 +113,7 @@
   ServiceWorkerNetworkProvider* GetNetworkProviderFromDataSource(
       const blink::WebDataSource* data_source) {
     return ServiceWorkerNetworkProvider::FromDocumentState(
-        static_cast<DataSourceExtraData*>(data_source->extraData()));
+        static_cast<DataSourceExtraData*>(data_source->getExtraData()));
   }
 };
 
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 2dbf048..9ceb8eb 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -464,6 +464,11 @@
         "//tools/imagediff($host_toolchain)",
       ]
     }
+
+    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" ]
+    }
   }
 } else {
   group("content_shell") {
diff --git a/device/bluetooth/bluetooth_gatt_characteristic.h b/device/bluetooth/bluetooth_gatt_characteristic.h
index 6dabe87..8cce601 100644
--- a/device/bluetooth/bluetooth_gatt_characteristic.h
+++ b/device/bluetooth/bluetooth_gatt_characteristic.h
@@ -181,6 +181,12 @@
   // notifications/indications. On success, the characteristic starts sending
   // value notifications and |callback| is called with a session object whose
   // ownership belongs to the caller. |error_callback| is called on errors.
+  //
+  // Writes to the Client Characteristic Configuration descriptor to enable
+  // notifications/indications. Core Bluetooth Specification [V4.2 Vol 3 Part G
+  // Section 3.3.1.1. Characteristic Properties] requires this descriptor to be
+  // present when notifications/indications are supported. If the descriptor is
+  // not present |error_callback| will be run.
   virtual void StartNotifySession(const NotifySessionCallback& callback,
                                   const ErrorCallback& error_callback) = 0;
 
diff --git a/extensions/common/api/externs_checker.py b/extensions/common/api/externs_checker.py
index 58c0076f..fd60fdd 100644
--- a/extensions/common/api/externs_checker.py
+++ b/extensions/common/api/externs_checker.py
@@ -12,6 +12,10 @@
     self._output_api = output_api
     self._api_pairs = api_pairs
 
+    for path in api_pairs.keys() + api_pairs.values():
+      if not input_api.os_path.exists(path):
+        raise OSError('Path Not Found: %s' % path)
+
   def RunChecks(self):
     bad_files = []
     affected = [f.AbsoluteLocalPath() for f in self._input_api.AffectedFiles()]
diff --git a/extensions/common/api/externs_checker_test.py b/extensions/common/api/externs_checker_test.py
index 73b65fa..9bcc651 100755
--- a/extensions/common/api/externs_checker_test.py
+++ b/extensions/common/api/externs_checker_test.py
@@ -18,8 +18,9 @@
 class ExternsCheckerTest(unittest.TestCase):
   API_PAIRS = {'a': '1', 'b': '2', 'c': '3'}
 
-  def _runChecks(self, files):
+  def _runChecks(self, files, exists=lambda f: True):
     input_api = MockInputApi()
+    input_api.os_path.exists = exists
     input_api.files = [MockFile(f, '') for f in files]
     output_api = MockOutputApi()
     checker = ExternsChecker(input_api, output_api, self.API_PAIRS)
@@ -58,6 +59,12 @@
     self.assertEquals(1, len(results[0].items))
     self.assertEquals('c', results[0].items[0])
 
+  def testApiFileDoesNotExist(self):
+    exists = lambda f: f in ['a', 'b', 'c', '1', '2']
+    with self.assertRaises(OSError) as e:
+      self._runChecks(['a'], exists)
+    self.assertEqual('Path Not Found: 3', str(e.exception))
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/extensions/renderer/activity_log_converter_strategy_unittest.cc b/extensions/renderer/activity_log_converter_strategy_unittest.cc
index 9237cad..aa80447 100644
--- a/extensions/renderer/activity_log_converter_strategy_unittest.cc
+++ b/extensions/renderer/activity_log_converter_strategy_unittest.cc
@@ -6,6 +6,7 @@
 #include "base/values.h"
 #include "extensions/renderer/activity_log_converter_strategy.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 using content::V8ValueConverter;
@@ -122,6 +123,7 @@
       "};"
       "})();";
 
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
   v8::Local<v8::Script> script(
       v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
   v8::Local<v8::Object> v8_object = script->Run().As<v8::Object>();
diff --git a/extensions/renderer/api_test_base.cc b/extensions/renderer/api_test_base.cc
index abf868b..79f95e27 100644
--- a/extensions/renderer/api_test_base.cc
+++ b/extensions/renderer/api_test_base.cc
@@ -214,7 +214,7 @@
 }
 
 void ApiTestEnvironment::RunPromisesAgain() {
-  env()->isolate()->RunMicrotasks();
+  v8::MicrotasksScope::PerformCheckpoint(env()->isolate());
   base::MessageLoop::current()->PostTask(
       FROM_HERE, base::Bind(&ApiTestEnvironment::RunPromisesAgain,
                             base::Unretained(this)));
diff --git a/extensions/renderer/extension_helper.cc b/extensions/renderer/extension_helper.cc
index 728ea13..4d3bd27 100644
--- a/extensions/renderer/extension_helper.cc
+++ b/extensions/renderer/extension_helper.cc
@@ -47,7 +47,7 @@
   std::vector<DraggableRegion> regions;
   for (size_t i = 0; i < webregions.size(); ++i) {
     DraggableRegion region;
-    render_view()->convertViewportToWindow(&webregions[i].bounds);
+    render_view()->ConvertViewportToWindowViaWidget(&webregions[i].bounds);
     region.bounds = webregions[i].bounds;
     region.draggable = webregions[i].draggable;
     regions.push_back(region);
diff --git a/extensions/renderer/module_system_test.cc b/extensions/renderer/module_system_test.cc
index 68c4bd1..06a4d55 100644
--- a/extensions/renderer/module_system_test.cc
+++ b/extensions/renderer/module_system_test.cc
@@ -253,7 +253,7 @@
 }
 
 void ModuleSystemTest::RunResolvedPromises() {
-  isolate_->RunMicrotasks();
+  v8::MicrotasksScope::PerformCheckpoint(isolate_);
 }
 
 }  // namespace extensions
diff --git a/extensions/renderer/safe_builtins.cc b/extensions/renderer/safe_builtins.cc
index 3bfa01a..3a66eaf1 100644
--- a/extensions/renderer/safe_builtins.cc
+++ b/extensions/renderer/safe_builtins.cc
@@ -9,6 +9,7 @@
 #include "base/strings/stringprintf.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/v8_helpers.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 
 namespace extensions {
 
@@ -200,6 +201,7 @@
         return;
     }
 
+    blink::WebScopedMicrotaskSuppression microtasks_scope;
     v8::Local<v8::Value> return_value;
     if (function->Call(context, recv, argc, argv.get()).ToLocal(&return_value))
       info.GetReturnValue().Set(return_value);
diff --git a/extensions/renderer/v8_helpers.h b/extensions/renderer/v8_helpers.h
index 3017772..560beee 100644
--- a/extensions/renderer/v8_helpers.h
+++ b/extensions/renderer/v8_helpers.h
@@ -9,6 +9,7 @@
 #include <string.h>
 
 #include "base/strings/string_number_conversions.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
 #include "v8/include/v8.h"
 
 namespace extensions {
@@ -172,6 +173,7 @@
                          int argc,
                          v8::Local<v8::Value> argv[],
                          v8::Local<v8::Value>* out) {
+  blink::WebScopedMicrotaskSuppression microtasks_scope;
   return function->Call(context, recv, argc, argv).ToLocal(out);
 }
 
diff --git a/gin/run_microtasks_observer.cc b/gin/run_microtasks_observer.cc
index f453a66..0ca0078 100644
--- a/gin/run_microtasks_observer.cc
+++ b/gin/run_microtasks_observer.cc
@@ -15,7 +15,7 @@
 
 void RunMicrotasksObserver::DidProcessTask(const base::PendingTask& task) {
   v8::Isolate::Scope scope(isolate_);
-  isolate_->RunMicrotasks();
+  v8::MicrotasksScope::PerformCheckpoint(isolate_);
 }
 
 }  // namespace gin
diff --git a/gin/run_microtasks_observer.h b/gin/run_microtasks_observer.h
index 7f1431f..ca160be 100644
--- a/gin/run_microtasks_observer.h
+++ b/gin/run_microtasks_observer.h
@@ -12,7 +12,7 @@
 
 // Runs any pending v8 Microtasks each time a task is completed.
 // TODO(hansmuller); At some point perhaps this can be replaced with
-// the (currently experimental) Isolate::SetAutorunMicrotasks() method.
+// the (currently experimental) v8::MicrotasksPolicy::kAuto method.
 
 class RunMicrotasksObserver : public base::MessageLoop::TaskObserver {
  public:
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 3c8586b..b54561d 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -47,11 +47,37 @@
 namespace gpu {
 namespace gles2 {
 
+namespace {
+
+void CopyRectToBuffer(const void* pixels,
+                      uint32_t height,
+                      uint32_t unpadded_row_size,
+                      uint32_t pixels_padded_row_size,
+                      void* buffer,
+                      uint32_t buffer_padded_row_size) {
+  if (height == 0)
+    return;
+  const int8_t* source = static_cast<const int8_t*>(pixels);
+  int8_t* dest = static_cast<int8_t*>(buffer);
+  if (pixels_padded_row_size != buffer_padded_row_size) {
+    for (uint32_t ii = 0; ii < height; ++ii) {
+      memcpy(dest, source, unpadded_row_size);
+      dest += buffer_padded_row_size;
+      source += pixels_padded_row_size;
+    }
+  } else {
+    uint32_t size = (height - 1) * pixels_padded_row_size + unpadded_row_size;
+    memcpy(dest, source, size);
+  }
+}
+
 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint.
-static GLuint ToGLuint(const void* ptr) {
+GLuint ToGLuint(const void* ptr) {
   return static_cast<GLuint>(reinterpret_cast<size_t>(ptr));
 }
 
+}  // anonymous namespace
+
 #if !defined(_MSC_VER)
 const size_t GLES2Implementation::kMaxSizeOfSimpleResult;
 const unsigned int GLES2Implementation::kStartingOffset;
@@ -2123,24 +2149,30 @@
   return true;
 }
 
-BufferTracker::Buffer*
-GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid(
-    GLuint buffer_id,
-    const char* function_name,
-    GLuint offset, GLsizei size) {
+BufferTracker::Buffer* GLES2Implementation::GetBoundPixelTransferBufferIfValid(
+    GLuint buffer_id, const char* function_name, GLuint offset, GLsizei size) {
   DCHECK(buffer_id);
   BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
   if (!buffer) {
     SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer");
-    return NULL;
+    return nullptr;
   }
   if (buffer->mapped()) {
     SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped");
-    return NULL;
+    return nullptr;
   }
-  if ((buffer->size() - offset) < static_cast<GLuint>(size)) {
+  base::CheckedNumeric<uint32_t> buffer_offset = buffer->shm_offset();
+  buffer_offset += offset;
+  if (!buffer_offset.IsValid()) {
+    SetGLError(GL_INVALID_VALUE, function_name, "offset to large");
+    return nullptr;
+  }
+  base::CheckedNumeric<uint32_t> required_size = offset;
+  required_size += size;
+  if (!required_size.IsValid() ||
+      buffer->size() < required_size.ValueOrDefault(0)) {
     SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large");
-    return NULL;
+    return nullptr;
   }
   return buffer;
 }
@@ -2168,7 +2200,7 @@
   // CompressedTexImage2D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(data);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
         bound_pixel_unpack_transfer_buffer_id_,
         "glCompressedTexImage2D", offset, image_size);
     if (buffer && buffer->shm_id() != -1) {
@@ -2209,7 +2241,7 @@
   // CompressedTexSubImage2D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(data);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
         bound_pixel_unpack_transfer_buffer_id_,
         "glCompressedTexSubImage2D", offset, image_size);
     if (buffer && buffer->shm_id() != -1) {
@@ -2253,7 +2285,7 @@
   // CompressedTexImage3D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(data);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
         bound_pixel_unpack_transfer_buffer_id_,
         "glCompressedTexImage3D", offset, image_size);
     if (buffer && buffer->shm_id() != -1) {
@@ -2295,7 +2327,7 @@
   // CompressedTexSubImage3D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(data);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
         bound_pixel_unpack_transfer_buffer_id_,
         "glCompressedTexSubImage3D", offset, image_size);
     if (buffer && buffer->shm_id() != -1) {
@@ -2319,34 +2351,6 @@
   CheckGLError();
 }
 
-namespace {
-
-void CopyRectToBuffer(const void* pixels,
-                      uint32_t height,
-                      uint32_t unpadded_row_size,
-                      uint32_t pixels_padded_row_size,
-                      void* buffer,
-                      uint32_t buffer_padded_row_size) {
-  if (height == 0)
-    return;
-  const int8_t* source = static_cast<const int8_t*>(pixels);
-  int8_t* dest = static_cast<int8_t*>(buffer);
-  if (pixels_padded_row_size != buffer_padded_row_size) {
-    // the last row is copied unpadded at the end
-    for (; height > 1; --height) {
-      memcpy(dest, source, buffer_padded_row_size);
-      dest += buffer_padded_row_size;
-      source += pixels_padded_row_size;
-    }
-    memcpy(dest, source, unpadded_row_size);
-  } else {
-    uint32_t size = (height - 1) * pixels_padded_row_size + unpadded_row_size;
-    memcpy(dest, source, size);
-  }
-}
-
-}  // anonymous namespace
-
 void GLES2Implementation::TexImage2D(
     GLenum target, GLint level, GLint internalformat, GLsizei width,
     GLsizei height, GLint border, GLenum format, GLenum type,
@@ -2381,9 +2385,8 @@
   // If there's a pixel unpack buffer bound use it when issuing TexImage2D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(pixels);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
-        bound_pixel_unpack_transfer_buffer_id_,
-        "glTexImage2D", offset, size);
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
+        bound_pixel_unpack_transfer_buffer_id_, "glTexImage2D", offset, size);
     if (buffer && buffer->shm_id() != -1) {
       helper_->TexImage2D(
           target, level, internalformat, width, height, format, type,
@@ -2505,9 +2508,8 @@
   // If there's a pixel unpack buffer bound use it when issuing TexImage3D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(pixels);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
-        bound_pixel_unpack_transfer_buffer_id_,
-        "glTexImage3D", offset, size);
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
+        bound_pixel_unpack_transfer_buffer_id_, "glTexImage3D", offset, size);
     if (buffer && buffer->shm_id() != -1) {
       helper_->TexImage3D(
           target, level, internalformat, width, height, depth, format, type,
@@ -2642,7 +2644,7 @@
   // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(pixels);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
         bound_pixel_unpack_transfer_buffer_id_,
         "glTexSubImage2D", offset, temp_size);
     if (buffer && buffer->shm_id() != -1) {
@@ -2721,7 +2723,7 @@
   // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
   if (bound_pixel_unpack_transfer_buffer_id_) {
     GLuint offset = ToGLuint(pixels);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
         bound_pixel_unpack_transfer_buffer_id_,
         "glTexSubImage3D", offset, temp_size);
     if (buffer && buffer->shm_id() != -1) {
@@ -3657,7 +3659,7 @@
     }
     DCHECK_EQ(0u, skip_size);
     GLuint offset = ToGLuint(pixels);
-    BufferTracker::Buffer* buffer = GetBoundPixelUnpackTransferBufferIfValid(
+    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
         bound_pixel_pack_transfer_buffer_id_, "glReadPixels", offset, size);
     if (buffer && buffer->shm_id() != -1) {
       helper_->ReadPixels(xoffset, yoffset, width, height, format, type,
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index e32b3c15..8b8ef63f 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -652,7 +652,7 @@
 
   bool GetBoundPixelTransferBuffer(
       GLenum target, const char* function_name, GLuint* buffer_id);
-  BufferTracker::Buffer* GetBoundPixelUnpackTransferBufferIfValid(
+  BufferTracker::Buffer* GetBoundPixelTransferBufferIfValid(
       GLuint buffer_id,
       const char* function_name, GLuint offset, GLsizei size);
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 49dbed8c..743e618 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -10249,11 +10249,21 @@
 
   uint32_t size;
   uint32_t padded_row_size;
+  uint32_t padding;
   // Here we use unpack buffer to upload zeros into the texture, one layer
-  // at a time. We haven't applied unpack parameters to GL except alignment.
-  if (!GLES2Util::ComputeImageDataSizes(
-          width, height, depth, format, type, state_.unpack_alignment, &size,
-          nullptr, &padded_row_size)) {
+  // at a time.
+  // We only take into consideration UNPACK_ALIGNMENT, and clear other unpack
+  // parameters if necessary before TexSubImage3D calls.
+  PixelStoreParams params;
+  params.alignment = state_.unpack_alignment;
+  if (!GLES2Util::ComputeImageDataSizesES3(width, height, depth,
+                                           format, type,
+                                           params,
+                                           &size,
+                                           nullptr,
+                                           &padded_row_size,
+                                           nullptr,
+                                           &padding)) {
     return false;
   }
   const uint32_t kMaxZeroSize = 1024 * 1024 * 2;
@@ -10315,6 +10325,9 @@
   glGenBuffersARB(1, &buffer_id);
   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer_id);
   {
+    // Include padding as some drivers incorrectly requires padding for the
+    // last row.
+    buffer_size += padding;
     scoped_ptr<char[]> zero(new char[buffer_size]);
     memset(zero.get(), 0, buffer_size);
     // TODO(zmo): Consider glMapBufferRange instead.
@@ -10322,6 +10335,20 @@
         GL_PIXEL_UNPACK_BUFFER, buffer_size, zero.get(), GL_STATIC_DRAW);
   }
 
+  Buffer* bound_buffer = buffer_manager()->GetBufferInfoForTarget(
+      &state_, GL_PIXEL_UNPACK_BUFFER);
+  if (bound_buffer) {
+    // If an unpack buffer is bound, we need to clear unpack parameters
+    // because they have been applied to the driver.
+    if (state_.unpack_row_length > 0)
+      glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    if (state_.unpack_image_height > 0)
+      glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
+    DCHECK_EQ(0, state_.unpack_skip_pixels);
+    DCHECK_EQ(0, state_.unpack_skip_rows);
+    DCHECK_EQ(0, state_.unpack_skip_images);
+  }
+
   glBindTexture(texture->target(), texture->service_id());
 
   for (size_t ii = 0; ii < subs.size(); ++ii) {
@@ -10330,8 +10357,13 @@
                     subs[ii].depth, format, type, nullptr);
   }
 
-  Buffer* bound_buffer = buffer_manager()->GetBufferInfoForTarget(
-      &state_, GL_PIXEL_UNPACK_BUFFER);
+  if (bound_buffer) {
+    if (state_.unpack_row_length > 0)
+      glPixelStorei(GL_UNPACK_ROW_LENGTH, state_.unpack_row_length);
+    if (state_.unpack_image_height > 0)
+      glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, state_.unpack_image_height);
+  }
+
   glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
                bound_buffer ? bound_buffer->service_id() : 0);
   glDeleteBuffersARB(1, &buffer_id);
@@ -11308,15 +11340,8 @@
 }
 
 void GLES2DecoderImpl::DoCompressedTexSubImage2D(
-  GLenum target,
-  GLint level,
-  GLint xoffset,
-  GLint yoffset,
-  GLsizei width,
-  GLsizei height,
-  GLenum format,
-  GLsizei image_size,
-  const void * data) {
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+    GLsizei height, GLenum format, GLsizei image_size, const void * data) {
   TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
       &state_, target);
   if (!texture_ref) {
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg
index ce8180a1..dc696e0 100644
--- a/infra/config/cq.cfg
+++ b/infra/config/cq.cfg
@@ -65,15 +65,9 @@
     buckets {
       name: "tryserver.chromium.mac"
       builders { name: "ios_dbg_simulator_ninja" }
-      builders {
-        name: "ios_dbg_simulator_gn"
-        experiment_percentage: 100
-      }
+      builders { name: "ios_dbg_simulator_gn" }
       builders { name: "ios_rel_device_ninja" }
-      builders {
-        name: "ios_rel_device_gn"
-        experiment_percentage: 100
-      }
+      builders { name: "ios_rel_device_gn" }
       builders { name: "mac_chromium_compile_dbg_ng" }
       builders { name: "mac_chromium_gn_rel" }
       builders { name: "mac_chromium_rel_ng" }
diff --git a/ios/chrome/ios_share_extension_resources.gyp b/ios/chrome/ios_share_extension_resources.gyp
new file mode 100644
index 0000000..9fc705c
--- /dev/null
+++ b/ios/chrome/ios_share_extension_resources.gyp
@@ -0,0 +1,87 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'variables': {
+    'chromium_code': 1,
+    'grit_base_dir': '<(SHARED_INTERMEDIATE_DIR)',
+    'grit_out_dir': '<(grit_base_dir)/ios/share_extension',
+  },
+  'targets': [
+    {
+      'target_name': 'ios_share_extension_resources',
+      'type': 'none',
+      'dependencies': [
+        'ios_share_extension_strings_gen',
+      ],
+    },
+    {
+      'target_name': 'ios_share_extension_strings_gen',
+      'type': 'none',
+      'hard_dependency': 1,
+      'actions': [
+        {
+          'action_name': 'generate_ios_share_extension_strings',
+          'variables': {
+            'grit_grd_file': 'share_extension/strings/ios_share_extension_strings.grd',
+          },
+          'includes': [ '../../build/grit_action.gypi' ],
+        },
+      ],
+      'includes': [ '../../build/grit_target.gypi' ],
+      # Override the exported include-dirs; ios/chrome/grit/ios_*strings.h
+      # should only be referenceable as ios/chrome/grit to allow DEPS-time
+      # checking of usage.
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '<(grit_base_dir)',
+        ],
+        'include_dirs!': [
+          '<(grit_out_dir)',
+        ],
+      }
+    },
+    {
+      'target_name': 'ios_share_extension_packed_resources',
+      'type': 'none',
+      'dependencies': [
+        'ios_share_extension_resources',
+      ],
+      'actions': [
+        {
+          'action_name': 'repack_ios_share_extension_locales',
+          'variables': {
+            'repack_locales_path': 'tools/build/ios_repack_extension_locales.py',
+          },
+          'inputs': [
+            'tools/build/ios_repack_extension_locales.py',
+            '<!@pymod_do_main(ios_repack_extension_locales -i '
+              '-n share_extension '
+              '-s <(SHARED_INTERMEDIATE_DIR) '
+              '-x <(SHARED_INTERMEDIATE_DIR)/repack_share_extension '
+              '-b <(branding_path_component) '
+              '<(locales))'
+          ],
+          'outputs': [
+            '<!@pymod_do_main(ios_repack_extension_locales -o '
+              '-n share_extension '
+              '-s <(SHARED_INTERMEDIATE_DIR) '
+              '-x <(SHARED_INTERMEDIATE_DIR)/repack_share_extension '
+              '<(locales))'
+          ],
+          'action': [
+            'python',
+            'tools/build/ios_repack_extension_locales.py',
+            '-n', 'share_extension',
+            '-x', '<(SHARED_INTERMEDIATE_DIR)/repack_share_extension',
+            '-s', '<(SHARED_INTERMEDIATE_DIR)',
+            '-b', '<(branding_path_component)',
+            '<@(locales)',
+          ],
+        },
+      ],
+    },
+  ],
+}
+
diff --git a/ios/chrome/ios_today_extension_resources.gyp b/ios/chrome/ios_today_extension_resources.gyp
index 62b05a5..519fb48 100644
--- a/ios/chrome/ios_today_extension_resources.gyp
+++ b/ios/chrome/ios_today_extension_resources.gyp
@@ -52,25 +52,28 @@
         {
           'action_name': 'repack_ios_today_extension_locales',
           'variables': {
-            'repack_locales_path': 'tools/build/ios_repack_today_extension_locales.py',
+            'repack_locales_path': 'tools/build/ios_repack_extension_locales.py',
           },
           'inputs': [
-            'tools/build/ios_repack_today_extension_locales.py',
-            '<!@pymod_do_main(ios_repack_today_extension_locales -i '
+            'tools/build/ios_repack_extension_locales.py',
+            '<!@pymod_do_main(ios_repack_extension_locales -i '
+              '-n today_extension '
               '-s <(SHARED_INTERMEDIATE_DIR) '
               '-x <(SHARED_INTERMEDIATE_DIR)/repack_today_extension '
               '-b <(branding_path_component) '
               '<(locales))'
           ],
           'outputs': [
-            '<!@pymod_do_main(ios_repack_today_extension_locales -o '
+            '<!@pymod_do_main(ios_repack_extension_locales -o '
+              '-n today_extension '
               '-s <(SHARED_INTERMEDIATE_DIR) '
               '-x <(SHARED_INTERMEDIATE_DIR)/repack_today_extension '
               '<(locales))'
           ],
           'action': [
             'python',
-            'tools/build/ios_repack_today_extension_locales.py',
+            'tools/build/ios_repack_extension_locales.py',
+            '-n', 'today_extension',
             '-x', '<(SHARED_INTERMEDIATE_DIR)/repack_today_extension',
             '-s', '<(SHARED_INTERMEDIATE_DIR)',
             '-b', '<(branding_path_component)',
diff --git a/ios/chrome/ios_today_extension_resources_bundle.gypi b/ios/chrome/ios_today_extension_resources_bundle.gypi
index 9552a8d..cddc6443 100644
--- a/ios/chrome/ios_today_extension_resources_bundle.gypi
+++ b/ios/chrome/ios_today_extension_resources_bundle.gypi
@@ -6,7 +6,8 @@
     '<(DEPTH)/ios/chrome/ios_today_extension_resources.gyp:ios_today_extension_packed_resources',
   ],
   'mac_bundle_resources': [
-    '<!@pymod_do_main(ios_repack_today_extension_locales -o -s <(SHARED_INTERMEDIATE_DIR) '
+    '<!@pymod_do_main(ios_repack_extension_locales -n today_extension -o '
+      '-s <(SHARED_INTERMEDIATE_DIR) '
       '-x <(SHARED_INTERMEDIATE_DIR)/repack_today_extension <(locales))',
   ],
 }
diff --git a/ios/chrome/share_extension/strings/ios_share_extension_strings.grd b/ios/chrome/share_extension/strings/ios_share_extension_strings.grd
new file mode 100644
index 0000000..cc58579
--- /dev/null
+++ b/ios/chrome/share_extension/strings/ios_share_extension_strings.grd
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+This file contains definition of resources that will be translated for each
+locale.  The variables is_win, is_macosx, is_linux, is_ios and is_posix are
+available for making strings OS specific.  Other platform defines such as
+use_titlecase are declared in build/common.gypi.
+
+The strings in this file are specific to iOS, thus is_ios will be true and
+all other OS specific variables will be false.
+-->
+
+<grit base_dir="." latest_public_release="0" current_release="1"
+      source_lang_id="en" enc_check="möl">
+  <outputs>
+    <output filename="grit/ios_share_extension_strings.h" type="rc_header">
+      <emit emit_type="prepend"></emit>
+    </output>
+    <output filename="ios_share_extension_strings_am.pak" type="data_package" lang="am" />
+    <output filename="ios_share_extension_strings_ar.pak" type="data_package" lang="ar" />
+    <output filename="ios_share_extension_strings_bg.pak" type="data_package" lang="bg" />
+    <output filename="ios_share_extension_strings_bn.pak" type="data_package" lang="bn" />
+    <output filename="ios_share_extension_strings_ca.pak" type="data_package" lang="ca" />
+    <output filename="ios_share_extension_strings_cs.pak" type="data_package" lang="cs" />
+    <output filename="ios_share_extension_strings_da.pak" type="data_package" lang="da" />
+    <output filename="ios_share_extension_strings_de.pak" type="data_package" lang="de" />
+    <output filename="ios_share_extension_strings_el.pak" type="data_package" lang="el" />
+    <output filename="ios_share_extension_strings_en-GB.pak" type="data_package" lang="en-GB" />
+    <output filename="ios_share_extension_strings_en-US.pak" type="data_package" lang="en" />
+    <output filename="ios_share_extension_strings_es.pak" type="data_package" lang="es" />
+    <output filename="ios_share_extension_strings_es-MX.pak" type="data_package" lang="es-419" />
+    <output filename="ios_share_extension_strings_et.pak" type="data_package" lang="et" />
+    <output filename="ios_share_extension_strings_fa.pak" type="data_package" lang="fa" />
+    <output filename="ios_share_extension_strings_fake-bidi.pak" type="data_package" lang="fake-bidi" />
+    <output filename="ios_share_extension_strings_fi.pak" type="data_package" lang="fi" />
+    <output filename="ios_share_extension_strings_fil.pak" type="data_package" lang="fil" />
+    <output filename="ios_share_extension_strings_fr.pak" type="data_package" lang="fr" />
+    <output filename="ios_share_extension_strings_gu.pak" type="data_package" lang="gu" />
+    <output filename="ios_share_extension_strings_he.pak" type="data_package" lang="he" />
+    <output filename="ios_share_extension_strings_hi.pak" type="data_package" lang="hi" />
+    <output filename="ios_share_extension_strings_hr.pak" type="data_package" lang="hr" />
+    <output filename="ios_share_extension_strings_hu.pak" type="data_package" lang="hu" />
+    <output filename="ios_share_extension_strings_id.pak" type="data_package" lang="id" />
+    <output filename="ios_share_extension_strings_it.pak" type="data_package" lang="it" />
+    <output filename="ios_share_extension_strings_ja.pak" type="data_package" lang="ja" />
+    <output filename="ios_share_extension_strings_kn.pak" type="data_package" lang="kn" />
+    <output filename="ios_share_extension_strings_ko.pak" type="data_package" lang="ko" />
+    <output filename="ios_share_extension_strings_lt.pak" type="data_package" lang="lt" />
+    <output filename="ios_share_extension_strings_lv.pak" type="data_package" lang="lv" />
+    <output filename="ios_share_extension_strings_ml.pak" type="data_package" lang="ml" />
+    <output filename="ios_share_extension_strings_mr.pak" type="data_package" lang="mr" />
+    <output filename="ios_share_extension_strings_ms.pak" type="data_package" lang="ms" />
+    <output filename="ios_share_extension_strings_nl.pak" type="data_package" lang="nl" />
+    <!-- The translation console uses 'no' for Norwegian Bokmål. It should
+         be 'nb'. -->
+    <output filename="ios_share_extension_strings_nb.pak" type="data_package" lang="no" />
+    <output filename="ios_share_extension_strings_pl.pak" type="data_package" lang="pl" />
+    <output filename="ios_share_extension_strings_pt.pak" type="data_package" lang="pt-BR" />
+    <output filename="ios_share_extension_strings_pt-PT.pak" type="data_package" lang="pt-PT" />
+    <output filename="ios_share_extension_strings_ro.pak" type="data_package" lang="ro" />
+    <output filename="ios_share_extension_strings_ru.pak" type="data_package" lang="ru" />
+    <output filename="ios_share_extension_strings_sk.pak" type="data_package" lang="sk" />
+    <output filename="ios_share_extension_strings_sl.pak" type="data_package" lang="sl" />
+    <output filename="ios_share_extension_strings_sr.pak" type="data_package" lang="sr" />
+    <output filename="ios_share_extension_strings_sv.pak" type="data_package" lang="sv" />
+    <output filename="ios_share_extension_strings_sw.pak" type="data_package" lang="sw" />
+    <output filename="ios_share_extension_strings_ta.pak" type="data_package" lang="ta" />
+    <output filename="ios_share_extension_strings_te.pak" type="data_package" lang="te" />
+    <output filename="ios_share_extension_strings_th.pak" type="data_package" lang="th" />
+    <output filename="ios_share_extension_strings_tr.pak" type="data_package" lang="tr" />
+    <output filename="ios_share_extension_strings_uk.pak" type="data_package" lang="uk" />
+    <output filename="ios_share_extension_strings_vi.pak" type="data_package" lang="vi" />
+    <output filename="ios_share_extension_strings_zh-CN.pak" type="data_package" lang="zh-CN" />
+    <output filename="ios_share_extension_strings_zh-TW.pak" type="data_package" lang="zh-TW" />
+  </outputs>
+  <translations>
+    <file path="resources/ios_share_extension_strings_am.xtb" lang="am" />
+    <file path="resources/ios_share_extension_strings_ar.xtb" lang="ar" />
+    <file path="resources/ios_share_extension_strings_bg.xtb" lang="bg" />
+    <file path="resources/ios_share_extension_strings_bn.xtb" lang="bn" />
+    <file path="resources/ios_share_extension_strings_ca.xtb" lang="ca" />
+    <file path="resources/ios_share_extension_strings_cs.xtb" lang="cs" />
+    <file path="resources/ios_share_extension_strings_da.xtb" lang="da" />
+    <file path="resources/ios_share_extension_strings_de.xtb" lang="de" />
+    <file path="resources/ios_share_extension_strings_el.xtb" lang="el" />
+    <file path="resources/ios_share_extension_strings_en-GB.xtb" lang="en-GB" />
+    <file path="resources/ios_share_extension_strings_es.xtb" lang="es" />
+    <file path="resources/ios_share_extension_strings_es-419.xtb" lang="es-419" />
+    <file path="resources/ios_share_extension_strings_et.xtb" lang="et" />
+    <file path="resources/ios_share_extension_strings_fa.xtb" lang="fa" />
+    <file path="resources/ios_share_extension_strings_fi.xtb" lang="fi" />
+    <file path="resources/ios_share_extension_strings_fil.xtb" lang="fil" />
+    <file path="resources/ios_share_extension_strings_fr.xtb" lang="fr" />
+    <file path="resources/ios_share_extension_strings_gu.xtb" lang="gu" />
+    <file path="resources/ios_share_extension_strings_hi.xtb" lang="hi" />
+    <file path="resources/ios_share_extension_strings_hr.xtb" lang="hr" />
+    <file path="resources/ios_share_extension_strings_hu.xtb" lang="hu" />
+    <file path="resources/ios_share_extension_strings_id.xtb" lang="id" />
+    <file path="resources/ios_share_extension_strings_it.xtb" lang="it" />
+    <!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
+    <file path="resources/ios_share_extension_strings_iw.xtb" lang="he" />
+    <file path="resources/ios_share_extension_strings_ja.xtb" lang="ja" />
+    <file path="resources/ios_share_extension_strings_kn.xtb" lang="kn" />
+    <file path="resources/ios_share_extension_strings_ko.xtb" lang="ko" />
+    <file path="resources/ios_share_extension_strings_lt.xtb" lang="lt" />
+    <file path="resources/ios_share_extension_strings_lv.xtb" lang="lv" />
+    <file path="resources/ios_share_extension_strings_ml.xtb" lang="ml" />
+    <file path="resources/ios_share_extension_strings_mr.xtb" lang="mr" />
+    <file path="resources/ios_share_extension_strings_ms.xtb" lang="ms" />
+    <file path="resources/ios_share_extension_strings_nl.xtb" lang="nl" />
+    <file path="resources/ios_share_extension_strings_no.xtb" lang="no" />
+    <file path="resources/ios_share_extension_strings_pl.xtb" lang="pl" />
+    <file path="resources/ios_share_extension_strings_pt-BR.xtb" lang="pt-BR" />
+    <file path="resources/ios_share_extension_strings_pt-PT.xtb" lang="pt-PT" />
+    <file path="resources/ios_share_extension_strings_ro.xtb" lang="ro" />
+    <file path="resources/ios_share_extension_strings_ru.xtb" lang="ru" />
+    <file path="resources/ios_share_extension_strings_sk.xtb" lang="sk" />
+    <file path="resources/ios_share_extension_strings_sl.xtb" lang="sl" />
+    <file path="resources/ios_share_extension_strings_sr.xtb" lang="sr" />
+    <file path="resources/ios_share_extension_strings_sv.xtb" lang="sv" />
+    <file path="resources/ios_share_extension_strings_sw.xtb" lang="sw" />
+    <file path="resources/ios_share_extension_strings_ta.xtb" lang="ta" />
+    <file path="resources/ios_share_extension_strings_te.xtb" lang="te" />
+    <file path="resources/ios_share_extension_strings_th.xtb" lang="th" />
+    <file path="resources/ios_share_extension_strings_tr.xtb" lang="tr" />
+    <file path="resources/ios_share_extension_strings_uk.xtb" lang="uk" />
+    <file path="resources/ios_share_extension_strings_vi.xtb" lang="vi" />
+    <file path="resources/ios_share_extension_strings_zh-CN.xtb" lang="zh-CN" />
+    <file path="resources/ios_share_extension_strings_zh-TW.xtb" lang="zh-TW" />
+  </translations>
+  <release seq="1" allow_pseudo="false">
+    <messages fallback_to_english="true">
+      <message name="IDS_IOS_ADD_READING_LIST_SHARE_EXTENSION" desc="Share extension button to add to reading list [Length: 30em]">
+        Reading List
+      </message>
+      <message name="IDS_IOS_ADD_BOOKMARKS_SHARE_EXTENSION" desc="Share extension button to add to bookmarks [Length: 30em]">
+        Bookmarks 
+      </message>
+      <message name="IDS_IOS_ADD_BUTTON_SHARE_EXTENSION" desc="Share extension button to validate add [Length: 12em]">
+        Add
+      </message>
+    </messages>
+  </release>
+</grit>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_am.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_am.xtb
new file mode 100644
index 0000000..6c985cb8
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_am.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="am">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ar.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ar.xtb
new file mode 100644
index 0000000..e8b5562
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ar.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ar">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_bg.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_bg.xtb
new file mode 100644
index 0000000..ebab473
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_bg.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bg">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_bn.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_bn.xtb
new file mode 100644
index 0000000..a66cc1fc
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_bn.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="bn">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ca.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ca.xtb
new file mode 100644
index 0000000..1438d89
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ca.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ca">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_cs.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_cs.xtb
new file mode 100644
index 0000000..2d95130
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_cs.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="cs">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_da.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_da.xtb
new file mode 100644
index 0000000..751fa4a8
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_da.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="da">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_de.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_de.xtb
new file mode 100644
index 0000000..91de7f51
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_de.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="de">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_el.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_el.xtb
new file mode 100644
index 0000000..6e5e7d8
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_el.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="el">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_en-GB.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_en-GB.xtb
new file mode 100644
index 0000000..0fb2133
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_en-GB.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="en-GB">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_es-419.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_es-419.xtb
new file mode 100644
index 0000000..2fe4770
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_es-419.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es-419">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_es.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_es.xtb
new file mode 100644
index 0000000..64022ec
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_es.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="es">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_et.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_et.xtb
new file mode 100644
index 0000000..5244dfd
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_et.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="et">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fa.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fa.xtb
new file mode 100644
index 0000000..18626f8
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fa.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fa">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fi.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fi.xtb
new file mode 100644
index 0000000..4691cd5
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fi.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fi">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fil.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fil.xtb
new file mode 100644
index 0000000..443630e7
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fil.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fil">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fr.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fr.xtb
new file mode 100644
index 0000000..63026a3
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_fr.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="fr">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_gu.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_gu.xtb
new file mode 100644
index 0000000..7d8a4df1
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_gu.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="gu">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hi.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hi.xtb
new file mode 100644
index 0000000..a6ddd5d
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hi.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hi">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hr.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hr.xtb
new file mode 100644
index 0000000..26f99d0
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hr.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hr">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hu.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hu.xtb
new file mode 100644
index 0000000..7ef9a5e0
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_hu.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="hu">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_id.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_id.xtb
new file mode 100644
index 0000000..aa34783
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_id.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="id">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_it.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_it.xtb
new file mode 100644
index 0000000..a6ac8d46
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_it.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="it">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_iw.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_iw.xtb
new file mode 100644
index 0000000..86b5533
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_iw.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="iw">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ja.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ja.xtb
new file mode 100644
index 0000000..23139e6
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ja.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ja">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_kn.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_kn.xtb
new file mode 100644
index 0000000..cc3643a2
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_kn.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="kn">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ko.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ko.xtb
new file mode 100644
index 0000000..e0fc370
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ko.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ko">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_lt.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_lt.xtb
new file mode 100644
index 0000000..5804ae2a
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_lt.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lt">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_lv.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_lv.xtb
new file mode 100644
index 0000000..a0a1c477
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_lv.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="lv">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ml.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ml.xtb
new file mode 100644
index 0000000..f7db315
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ml.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ml">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_mr.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_mr.xtb
new file mode 100644
index 0000000..098d29c
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_mr.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="mr">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ms.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ms.xtb
new file mode 100644
index 0000000..1fb470a
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ms.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ms">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_nl.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_nl.xtb
new file mode 100644
index 0000000..e782410
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_nl.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="nl">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_no.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_no.xtb
new file mode 100644
index 0000000..913638b
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_no.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="no">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pl.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pl.xtb
new file mode 100644
index 0000000..4519e3d
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pl.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pl">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pt-BR.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pt-BR.xtb
new file mode 100644
index 0000000..e95eb56b
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pt-BR.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-BR">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pt-PT.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pt-PT.xtb
new file mode 100644
index 0000000..1dcf557a
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_pt-PT.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="pt-PT">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ro.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ro.xtb
new file mode 100644
index 0000000..9e43493
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ro.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ro">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ru.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ru.xtb
new file mode 100644
index 0000000..c4a621b
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ru.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ru">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sk.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sk.xtb
new file mode 100644
index 0000000..00750d31
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sk.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sk">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sl.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sl.xtb
new file mode 100644
index 0000000..489b7e46
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sl.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sl">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sr.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sr.xtb
new file mode 100644
index 0000000..38f6f35
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sr.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sr">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sv.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sv.xtb
new file mode 100644
index 0000000..ddea3dc
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sv.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sv">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sw.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sw.xtb
new file mode 100644
index 0000000..b775088
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_sw.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="sw">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ta.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ta.xtb
new file mode 100644
index 0000000..ef90687
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_ta.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="ta">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_te.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_te.xtb
new file mode 100644
index 0000000..48c714b
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_te.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="te">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_th.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_th.xtb
new file mode 100644
index 0000000..fae31966
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_th.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="th">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_tr.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_tr.xtb
new file mode 100644
index 0000000..9a29951
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_tr.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="tr">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_uk.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_uk.xtb
new file mode 100644
index 0000000..f0db52c
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_uk.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="uk">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_vi.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_vi.xtb
new file mode 100644
index 0000000..b2957da
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_vi.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="vi">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_zh-CN.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_zh-CN.xtb
new file mode 100644
index 0000000..26e8b40
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_zh-CN.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-CN">
+</translationbundle>
diff --git a/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_zh-TW.xtb b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_zh-TW.xtb
new file mode 100644
index 0000000..935ef485
--- /dev/null
+++ b/ios/chrome/share_extension/strings/resources/ios_share_extension_strings_zh-TW.xtb
@@ -0,0 +1,4 @@
+<?xml version="1.0" ?>
+<!DOCTYPE translationbundle>
+<translationbundle lang="zh-TW">
+</translationbundle>
diff --git a/ios/chrome/tools/build/ios_repack_today_extension_locales.py b/ios/chrome/tools/build/ios_repack_extension_locales.py
similarity index 89%
rename from ios/chrome/tools/build/ios_repack_today_extension_locales.py
rename to ios/chrome/tools/build/ios_repack_extension_locales.py
index d7e2334..529b8ed 100755
--- a/ios/chrome/tools/build/ios_repack_today_extension_locales.py
+++ b/ios/chrome/tools/build/ios_repack_extension_locales.py
@@ -3,7 +3,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""Helper script to repack paks for a list of locales for today extension.
+"""Helper script to repack paks for a list of locales for extensions.
 
 Gyp doesn't have any built-in looping capability, so this just provides a way to
 loop over a list of locales when repacking pak files, thus avoiding a
@@ -42,9 +42,11 @@
   """Determine the files that need processing for the given locale."""
   inputs = []
 
-  #e.g. 'out/Debug/gen/ios/today_extension/ios_today_extension_strings_da.pak'
-  inputs.append(os.path.join(options.share_int_dir, 'ios', 'today_extension',
-                'ios_today_extension_strings_%s.pak' % (locale)))
+  #e.g.
+  #'out/Debug/gen/ios/%(extension_name)/ios_%(extension_name)_strings_da.pak'
+  inputs.append(os.path.join(options.share_int_dir, 'ios',
+                options.extension_name,
+                'ios_%s_strings_%s.pak' % (options.extension_name, locale)))
 
   # Add any extra input files.
   for extra_file in options.extra_input:
@@ -109,6 +111,9 @@
       "-b", action="store", dest="branding",
       help="Branding type of this build.")
   parser.add_option(
+      "-n", action="store", dest="extension_name",
+      help="Name of the extension.")
+  parser.add_option(
       "-e", action="append", dest="extra_input", default=[],
       help="Full path to an extra input pak file without the "
            "locale suffix and \".pak\" extension.")
@@ -120,6 +125,9 @@
   if not locales:
     parser.error('Please specificy at least one locale to process.\n')
 
+  if not options.extension_name:
+    parser.error('Please specificy extension name.\n')
+
   if not (options.out_dir and options.share_int_dir):
     parser.error('Please specify all of "-x" and "-s".\n')
   if options.print_inputs and options.print_outputs:
diff --git a/ios/ios.gyp b/ios/ios.gyp
index b29bdd2..ba0c3265 100644
--- a/ios/ios.gyp
+++ b/ios/ios.gyp
@@ -11,6 +11,7 @@
       'type': 'none',
       'dependencies': [
         'chrome/ios_chrome_tests.gyp:*',
+        'chrome/ios_share_extension_resources.gyp:*',
         'chrome/ios_today_extension_resources.gyp:*',
         'consumer/ios_consumer_base.gyp:*',
         'crnet/crnet.gyp:*',
diff --git a/ios/web/web_state/js/crw_js_post_request_loader_unittest.mm b/ios/web/web_state/js/crw_js_post_request_loader_unittest.mm
index 15992012..60f90b2 100644
--- a/ios/web/web_state/js/crw_js_post_request_loader_unittest.mm
+++ b/ios/web/web_state/js/crw_js_post_request_loader_unittest.mm
@@ -38,7 +38,7 @@
 #if TARGET_IPHONE_SIMULATOR
 #define MAYBE_LoadsCorrectHTML LoadsCorrectHTML
 #else
-#define MAYBE_LoadsCorrectHTML FLAKY_LoadsCorrectHTML
+#define MAYBE_LoadsCorrectHTML DISABLED_LoadsCorrectHTML
 #endif
 TEST_F(CRWJSPOSTRequestLoaderTest, MAYBE_LoadsCorrectHTML) {
   // Set up necessary objects.
diff --git a/ios/web/web_state/js/resources/common.js b/ios/web/web_state/js/resources/common.js
index e5fbc836..41c7485 100644
--- a/ios/web/web_state/js/resources/common.js
+++ b/ios/web/web_state/js/resources/common.js
@@ -79,19 +79,6 @@
   };
 
   /**
-   * Detects focusable elements.
-   * @param {Element} element A DOM element.
-   * @return {boolean} true if the |element| is focusable.
-   */
-  __gCrWeb.common.isFocusable = function(element) {
-    // When the disabled or hidden attributes are present, controls do not
-    // receive focus.
-    if (element.hasAttribute('disabled') || element.hasAttribute('hidden'))
-      return false;
-    return __gCrWeb.common.isFormControlElement(element);
-  };
-
-  /**
    * Returns an array of control elements in a form.
    *
    * This method is based on the logic in method
diff --git a/ipc/unix_domain_socket_util.cc b/ipc/unix_domain_socket_util.cc
index c69c5d8..414674c6 100644
--- a/ipc/unix_domain_socket_util.cc
+++ b/ipc/unix_domain_socket_util.cc
@@ -24,9 +24,10 @@
 
 namespace {
 
-// Returns true on success, false otherwise. If successful, fills in
-// |unix_addr| with the appropriate data for the socket, and sets
-// |unix_addr_len| to the length of the data therein.
+// This function fills in |unix_addr| with the appropriate data for the socket,
+// and sets |unix_addr_len| to the length of the data therein.
+// Returns true on success, or false on failure (typically because |socket_name|
+// violated the naming rules).
 bool MakeUnixAddrForPath(const std::string& socket_name,
                          struct sockaddr_un* unix_addr,
                          size_t* unix_addr_len) {
@@ -53,7 +54,8 @@
   return true;
 }
 
-// Returns a valid socket on success.
+// This functions creates a unix domain socket, and set it as non-blocking.
+// Returns a valid socket descriptor on success, or an invalid one otherwise.
 base::ScopedFD CreateUnixDomainSocket() {
   // Create socket.
   base::ScopedFD fd(socket(AF_UNIX, SOCK_STREAM, 0));
diff --git a/mash/wm/window_manager_apptest.cc b/mash/wm/window_manager_apptest.cc
index 7ea0a25..605b825 100644
--- a/mash/wm/window_manager_apptest.cc
+++ b/mash/wm/window_manager_apptest.cc
@@ -31,7 +31,7 @@
 
 using WindowManagerAppTest = mojo::test::ApplicationTestBase;
 
-void OnEmbed(bool success, uint16_t id) {
+void OnEmbed(bool success) {
   ASSERT_TRUE(success);
 }
 
@@ -55,9 +55,7 @@
   // |child_window|. This blocks until it succeeds.
   mus::mojom::WindowTreeClientPtr tree_client;
   auto tree_client_request = GetProxy(&tree_client);
-  child_window->Embed(std::move(tree_client),
-                      mus::mojom::WindowTree::kAccessPolicyDefault,
-                      base::Bind(&OnEmbed));
+  child_window->Embed(std::move(tree_client), base::Bind(&OnEmbed));
   scoped_ptr<mus::WindowTreeConnection> child_connection(
       mus::WindowTreeConnection::Create(
           &window_tree_delegate, std::move(tree_client_request),
diff --git a/media/BUILD.gn b/media/BUILD.gn
index cb135342..34f6759e 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -574,6 +574,7 @@
     "formats/webm/webm_cluster_parser_unittest.cc",
     "formats/webm/webm_content_encodings_client_unittest.cc",
     "formats/webm/webm_parser_unittest.cc",
+    "formats/webm/webm_stream_parser_unittest.cc",
     "formats/webm/webm_tracks_parser_unittest.cc",
     "formats/webm/webm_webvtt_parser_unittest.cc",
     "muxers/webm_muxer_unittest.cc",
diff --git a/media/base/android/media_codec_player_unittest.cc b/media/base/android/media_codec_player_unittest.cc
index 10ce91c..5076e48 100644
--- a/media/base/android/media_codec_player_unittest.cc
+++ b/media/base/android/media_codec_player_unittest.cc
@@ -382,7 +382,7 @@
 
   // Conditions to wait for.
   bool IsInitialized() const { return client_; }
-  bool HasPendingConfigs() const { return pending_configs_; }
+  bool HasPendingConfigs() const { return !!pending_configs_; }
   bool ReceivedSeekRequest() const { return num_seeks_ > 0; }
   bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_ > 0; }
 
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index f768a1af..1d8361b4 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -27,6 +27,7 @@
 #include "media/base/decrypt_config.h"
 #include "media/base/limits.h"
 #include "media/base/media_log.h"
+#include "media/base/media_tracks.h"
 #include "media/base/timestamp_constants.h"
 #include "media/ffmpeg/ffmpeg_common.h"
 #include "media/filters/ffmpeg_aac_bitstream_converter.h"
@@ -1089,6 +1090,7 @@
     }
   }
 
+  scoped_ptr<MediaTracks> media_tracks(new MediaTracks());
   AVStream* audio_stream = NULL;
   AudioDecoderConfig audio_config;
   AVStream* video_stream = NULL;
@@ -1158,6 +1160,19 @@
       continue;
     }
 
+    std::string track_id = base::IntToString(stream->id);
+    std::string track_label = streams_[i]->GetMetadata("handler_name");
+    std::string track_language = streams_[i]->GetMetadata("language");
+
+    // Some metadata is named differently in FFmpeg for webm files.
+    if (strstr(format_context->iformat->name, "webm") ||
+        strstr(format_context->iformat->name, "matroska")) {
+      // TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files.
+      // Need to fix that and use it as track id. crbug.com/323183
+      track_id = base::UintToString(media_tracks->tracks().size() + 1);
+      track_label = streams_[i]->GetMetadata("title");
+    }
+
     // Note when we find our audio/video stream (we only want one of each) and
     // record src= playback UMA stats for the stream's decoder config.
     if (codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -1165,11 +1180,17 @@
       audio_stream = stream;
       audio_config = streams_[i]->audio_decoder_config();
       RecordAudioCodecStats(audio_config);
+
+      media_tracks->AddAudioTrack(audio_config, track_id, "main", track_label,
+                                  track_language);
     } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
       CHECK(!video_stream);
       video_stream = stream;
       video_config = streams_[i]->video_decoder_config();
       RecordVideoCodecStats(video_config, stream->codec->color_range);
+
+      media_tracks->AddVideoTrack(video_config, track_id, "main", track_label,
+                                  track_language);
     }
 
     max_duration = std::max(max_duration, streams_[i]->duration());
@@ -1340,6 +1361,8 @@
   media_log_->SetTimeProperty("start_time", start_time_);
   media_log_->SetIntegerProperty("bitrate", bitrate_);
 
+  media_tracks_updated_cb_.Run(std::move(media_tracks));
+
   status_cb.Run(PIPELINE_OK);
 }
 
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index a6b82e22..01f57a1 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -208,7 +208,10 @@
                void(EmeInitDataType init_data_type,
                     const std::vector<uint8_t>& init_data));
 
-  void OnMediaTracksUpdated(scoped_ptr<MediaTracks> tracks) {}
+  void OnMediaTracksUpdated(scoped_ptr<MediaTracks> tracks) {
+    CHECK(tracks.get());
+    media_tracks_ = std::move(tracks);
+  }
 
   // Accessor to demuxer internals.
   void set_duration_known(bool duration_known) {
@@ -225,6 +228,7 @@
   scoped_ptr<FileDataSource> data_source_;
   scoped_ptr<FFmpegDemuxer> demuxer_;
   StrictMock<MockDemuxerHost> host_;
+  scoped_ptr<MediaTracks> media_tracks_;
   base::MessageLoop message_loop_;
 
   AVFormatContext* format_context() {
@@ -1190,6 +1194,48 @@
 #endif
 }
 
+TEST_F(FFmpegDemuxerTest, Read_Mp4_Media_Track_Info) {
+  CreateDemuxer("bear.mp4");
+  InitializeDemuxer();
+
+  EXPECT_EQ(media_tracks_->tracks().size(), 2u);
+
+  const MediaTrack& audio_track = *(media_tracks_->tracks()[0]);
+  EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
+  EXPECT_EQ(audio_track.id(), "1");
+  EXPECT_EQ(audio_track.kind(), "main");
+  EXPECT_EQ(audio_track.label(), "GPAC ISO Audio Handler");
+  EXPECT_EQ(audio_track.language(), "und");
+
+  const MediaTrack& video_track = *(media_tracks_->tracks()[1]);
+  EXPECT_EQ(video_track.type(), MediaTrack::Video);
+  EXPECT_EQ(video_track.id(), "2");
+  EXPECT_EQ(video_track.kind(), "main");
+  EXPECT_EQ(video_track.label(), "GPAC ISO Video Handler");
+  EXPECT_EQ(video_track.language(), "und");
+}
+
 #endif  // defined(USE_PROPRIETARY_CODECS)
 
+TEST_F(FFmpegDemuxerTest, Read_Webm_Media_Track_Info) {
+  CreateDemuxer("bear.webm");
+  InitializeDemuxer();
+
+  EXPECT_EQ(media_tracks_->tracks().size(), 2u);
+
+  const MediaTrack& video_track = *(media_tracks_->tracks()[0]);
+  EXPECT_EQ(video_track.type(), MediaTrack::Video);
+  EXPECT_EQ(video_track.id(), "1");
+  EXPECT_EQ(video_track.kind(), "main");
+  EXPECT_EQ(video_track.label(), "");
+  EXPECT_EQ(video_track.language(), "");
+
+  const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
+  EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
+  EXPECT_EQ(audio_track.id(), "2");
+  EXPECT_EQ(audio_track.kind(), "main");
+  EXPECT_EQ(audio_track.label(), "");
+  EXPECT_EQ(audio_track.language(), "");
+}
+
 }  // namespace media
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc
index 705232f4e..a95c78f 100644
--- a/media/formats/mp4/box_definitions.cc
+++ b/media/formats/mp4/box_definitions.cc
@@ -434,8 +434,29 @@
 
 bool HandlerReference::Parse(BoxReader* reader) {
   FourCC hdlr_type;
-  RCHECK(reader->SkipBytes(8) && reader->ReadFourCC(&hdlr_type));
-  // Note: remaining fields in box ignored
+  RCHECK(reader->ReadFullBoxHeader() && reader->SkipBytes(4) &&
+         reader->ReadFourCC(&hdlr_type) && reader->SkipBytes(12));
+
+  // Now we should be at the beginning of the |name| field of HDLR box. The
+  // |name| is a zero-terminated ASCII string in ISO BMFF, but it was a
+  // Pascal-style counted string in older QT/Mov formats. So we'll read the
+  // remaining box bytes first, then if the last one is zero, we strip the last
+  // zero byte, otherwise we'll string the first byte (containing the length of
+  // the Pascal-style string).
+  std::vector<uint8_t> name_bytes;
+  RCHECK(reader->ReadVec(&name_bytes, reader->size() - reader->pos()));
+  if (name_bytes.size() == 0) {
+    name = "";
+  } else if (name_bytes.back() == 0) {
+    // This is a zero-terminated C-style string, exclude the last byte.
+    name = std::string(name_bytes.begin(), name_bytes.end() - 1);
+  } else {
+    // Check that the length of the Pascal-style string is correct.
+    RCHECK(name_bytes[0] == (name_bytes.size() - 1));
+    // Skip the first byte, containing the length of the Pascal-string.
+    name = std::string(name_bytes.begin() + 1, name_bytes.end());
+  }
+
   if (hdlr_type == FOURCC_VIDE) {
     type = kVideo;
   } else if (hdlr_type == FOURCC_SOUN) {
@@ -691,7 +712,8 @@
     : creation_time(0),
       modification_time(0),
       timescale(0),
-      duration(0) {}
+      duration(0),
+      language_code(0) {}
 MediaHeader::~MediaHeader() {}
 FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; }
 
@@ -699,18 +721,43 @@
   RCHECK(reader->ReadFullBoxHeader());
 
   if (reader->version() == 1) {
-    RCHECK(reader->Read8(&creation_time) &&
-           reader->Read8(&modification_time) &&
-           reader->Read4(&timescale) &&
-           reader->Read8(&duration));
+    RCHECK(reader->Read8(&creation_time) && reader->Read8(&modification_time) &&
+           reader->Read4(&timescale) && reader->Read8(&duration) &&
+           reader->Read2(&language_code));
   } else {
     RCHECK(reader->Read4Into8(&creation_time) &&
            reader->Read4Into8(&modification_time) &&
-           reader->Read4(&timescale) &&
-           reader->Read4Into8(&duration));
+           reader->Read4(&timescale) && reader->Read4Into8(&duration) &&
+           reader->Read2(&language_code));
   }
-  // Skip language information
-  return reader->SkipBytes(4);
+  // ISO 639-2/T language code only uses 15 lower bits, so reset the 16th bit.
+  language_code &= 0x7fff;
+  // Skip playback quality information
+  return reader->SkipBytes(2);
+}
+
+std::string MediaHeader::language() const {
+  if (language_code == 0x7fff || language_code < 0x400) {
+    return "und";
+  }
+  char lang_chars[4];
+  lang_chars[3] = 0;
+  lang_chars[2] = 0x60 + (language_code & 0x1f);
+  lang_chars[1] = 0x60 + ((language_code >> 5) & 0x1f);
+  lang_chars[0] = 0x60 + ((language_code >> 10) & 0x1f);
+
+  if (lang_chars[0] < 'a' || lang_chars[0] > 'z' || lang_chars[1] < 'a' ||
+      lang_chars[1] > 'z' || lang_chars[2] < 'a' || lang_chars[2] > 'z') {
+    // Got unexpected characteds in ISO 639-2/T language code. Something must be
+    // wrong with the input file, report 'und' language to be safe.
+    DVLOG(2) << "Ignoring MDHD language_code (non ISO 639-2 compliant): "
+             << lang_chars;
+    lang_chars[0] = 'u';
+    lang_chars[1] = 'n';
+    lang_chars[2] = 'd';
+  }
+
+  return lang_chars;
 }
 
 MediaInformation::MediaInformation() {}
diff --git a/media/formats/mp4/box_definitions.h b/media/formats/mp4/box_definitions.h
index 542f4de..24b585b 100644
--- a/media/formats/mp4/box_definitions.h
+++ b/media/formats/mp4/box_definitions.h
@@ -197,6 +197,7 @@
   DECLARE_BOX_METHODS(HandlerReference);
 
   TrackType type;
+  std::string name;
 };
 
 struct MEDIA_EXPORT AVCDecoderConfigurationRecord : Box {
@@ -310,10 +311,13 @@
 struct MEDIA_EXPORT MediaHeader : Box {
   DECLARE_BOX_METHODS(MediaHeader);
 
+  std::string language() const;
+
   uint64_t creation_time;
   uint64_t modification_time;
   uint32_t timescale;
   uint64_t duration;
+  uint16_t language_code;
 };
 
 struct MEDIA_EXPORT MediaInformation : Box {
diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc
index 95abf83..37b5396 100644
--- a/media/formats/mp4/mp4_stream_parser.cc
+++ b/media/formats/mp4/mp4_stream_parser.cc
@@ -11,6 +11,7 @@
 
 #include "base/callback_helpers.h"
 #include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "media/base/audio_decoder_config.h"
@@ -187,6 +188,7 @@
   has_audio_ = false;
   has_video_ = false;
 
+  scoped_ptr<MediaTracks> media_tracks(new MediaTracks());
   AudioDecoderConfig audio_config;
   VideoDecoderConfig video_config;
 
@@ -307,6 +309,9 @@
                               is_audio_track_encrypted_, base::TimeDelta(), 0);
       has_audio_ = true;
       audio_track_id_ = track->header.track_id;
+      media_tracks->AddAudioTrack(
+          audio_config, base::UintToString(audio_track_id_), "main",
+          track->media.handler.name, track->media.header.language());
     }
     if (track->media.handler.type == kVideo && !video_config.IsValidConfig()) {
       RCHECK(!samp_descr.video_entries.empty());
@@ -348,21 +353,15 @@
           std::vector<uint8_t>(), is_video_track_encrypted_);
       has_video_ = true;
       video_track_id_ = track->header.track_id;
+      media_tracks->AddVideoTrack(
+          video_config, base::UintToString(video_track_id_), "main",
+          track->media.handler.name, track->media.header.language());
     }
   }
 
   if (!moov_->pssh.empty())
     OnEncryptedMediaInitData(moov_->pssh);
 
-  scoped_ptr<MediaTracks> media_tracks(new MediaTracks());
-  // TODO(servolk): Implement proper sourcing of media track info as described
-  // in crbug.com/590085
-  if (audio_config.IsValidConfig()) {
-    media_tracks->AddAudioTrack(audio_config, "audio", "", "", "");
-  }
-  if (video_config.IsValidConfig()) {
-    media_tracks->AddVideoTrack(video_config, "video", "", "", "");
-  }
   RCHECK(config_cb_.Run(std::move(media_tracks), TextTrackConfigMap()));
 
   StreamParser::InitParameters params(kInfiniteDuration());
diff --git a/media/formats/mp4/mp4_stream_parser_unittest.cc b/media/formats/mp4/mp4_stream_parser_unittest.cc
index c7d41fe..26144ee3 100644
--- a/media/formats/mp4/mp4_stream_parser_unittest.cc
+++ b/media/formats/mp4/mp4_stream_parser_unittest.cc
@@ -69,6 +69,7 @@
   scoped_refptr<StrictMock<MockMediaLog>> media_log_;
   scoped_ptr<MP4StreamParser> parser_;
   bool configs_received_;
+  scoped_ptr<MediaTracks> media_tracks_;
   AudioDecoderConfig audio_decoder_config_;
   VideoDecoderConfig video_decoder_config_;
   DecodeTimestamp lower_bound_;
@@ -102,9 +103,11 @@
   bool NewConfigF(scoped_ptr<MediaTracks> tracks,
                   const StreamParser::TextTrackConfigMap& tc) {
     configs_received_ = true;
-    audio_decoder_config_ = tracks->getFirstAudioConfig();
-    video_decoder_config_ = tracks->getFirstVideoConfig();
-    DVLOG(1) << "NewConfigF: track count=" << tracks->tracks().size()
+    CHECK(tracks.get());
+    media_tracks_ = std::move(tracks);
+    audio_decoder_config_ = media_tracks_->getFirstAudioConfig();
+    video_decoder_config_ = media_tracks_->getFirstVideoConfig();
+    DVLOG(1) << "NewConfigF: track count=" << media_tracks_->tracks().size()
              << " audio=" << audio_decoder_config_.IsValidConfig()
              << " video=" << video_decoder_config_.IsValidConfig();
     return true;
@@ -417,5 +420,26 @@
   EXPECT_EQ("0x66616b00", FourCCToString(static_cast<FourCC>(0x66616b00)));
 }
 
+TEST_F(MP4StreamParserTest, MediaTrackInfoSourcing) {
+  EXPECT_MEDIA_LOG(VideoCodecLog("avc1.64001F"));
+  EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2"));
+  ParseMP4File("bear-1280x720-av_frag.mp4", 4096);
+
+  EXPECT_EQ(media_tracks_->tracks().size(), 2u);
+  const MediaTrack& video_track = *(media_tracks_->tracks()[0]);
+  EXPECT_EQ(video_track.type(), MediaTrack::Video);
+  EXPECT_EQ(video_track.id(), "1");
+  EXPECT_EQ(video_track.kind(), "main");
+  EXPECT_EQ(video_track.label(), "VideoHandler");
+  EXPECT_EQ(video_track.language(), "und");
+
+  const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
+  EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
+  EXPECT_EQ(audio_track.id(), "2");
+  EXPECT_EQ(audio_track.kind(), "main");
+  EXPECT_EQ(audio_track.label(), "SoundHandler");
+  EXPECT_EQ(audio_track.language(), "und");
+}
+
 }  // namespace mp4
 }  // namespace media
diff --git a/media/formats/webm/webm_stream_parser.cc b/media/formats/webm/webm_stream_parser.cc
index 3090768..0e82ca2 100644
--- a/media/formats/webm/webm_stream_parser.cc
+++ b/media/formats/webm/webm_stream_parser.cc
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
 #include "media/base/media_track.h"
 #include "media/base/media_tracks.h"
 #include "media/base/timestamp_constants.h"
@@ -224,15 +225,8 @@
   if (video_config.is_encrypted())
     OnEncryptedMediaInitData(tracks_parser.video_encryption_key_id());
 
-  scoped_ptr<MediaTracks> media_tracks(new MediaTracks());
-  // TODO(servolk): Implement proper sourcing of media track info as described
-  // in crbug.com/590085
-  if (audio_config.IsValidConfig()) {
-    media_tracks->AddAudioTrack(audio_config, "audio", "", "", "");
-  }
-  if (video_config.IsValidConfig()) {
-    media_tracks->AddVideoTrack(video_config, "video", "", "", "");
-  }
+  scoped_ptr<MediaTracks> media_tracks = tracks_parser.media_tracks();
+  CHECK(media_tracks.get());
   if (!config_cb_.Run(std::move(media_tracks), tracks_parser.text_tracks())) {
     DVLOG(1) << "New config data isn't allowed.";
     return -1;
diff --git a/media/formats/webm/webm_stream_parser.h b/media/formats/webm/webm_stream_parser.h
index 6de1deda..78f14976 100644
--- a/media/formats/webm/webm_stream_parser.h
+++ b/media/formats/webm/webm_stream_parser.h
@@ -12,6 +12,7 @@
 #include "base/memory/ref_counted.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/byte_queue.h"
+#include "media/base/media_export.h"
 #include "media/base/stream_parser.h"
 #include "media/base/video_decoder_config.h"
 
@@ -19,7 +20,7 @@
 
 class WebMClusterParser;
 
-class WebMStreamParser : public StreamParser {
+class MEDIA_EXPORT WebMStreamParser : public StreamParser {
  public:
   WebMStreamParser();
   ~WebMStreamParser() override;
diff --git a/media/formats/webm/webm_stream_parser_unittest.cc b/media/formats/webm/webm_stream_parser_unittest.cc
new file mode 100644
index 0000000..0386e8f
--- /dev/null
+++ b/media/formats/webm/webm_stream_parser_unittest.cc
@@ -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.
+
+#include "base/bind.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/media_tracks.h"
+#include "media/base/mock_media_log.h"
+#include "media/base/test_data_util.h"
+#include "media/base/text_track_config.h"
+#include "media/formats/webm/webm_stream_parser.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+
+namespace media {
+
+class WebMStreamParserTest : public testing::Test {
+ public:
+  WebMStreamParserTest()
+      : media_log_(new testing::StrictMock<MockMediaLog>()) {}
+
+ protected:
+  void ParseWebMFile(const std::string& filename) {
+    scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
+    parser_.reset(new WebMStreamParser());
+    Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb =
+        base::Bind(&WebMStreamParserTest::OnEncryptedMediaInitData,
+                   base::Unretained(this));
+
+    EXPECT_CALL(*this, InitCB(_));
+    EXPECT_CALL(*this, NewMediaSegmentCB()).Times(testing::AnyNumber());
+    EXPECT_CALL(*this, EndMediaSegmentCB()).Times(testing::AnyNumber());
+    EXPECT_CALL(*this, NewBuffersCB(_, _, _))
+        .Times(testing::AnyNumber())
+        .WillRepeatedly(testing::Return(true));
+    parser_->Init(
+        base::Bind(&WebMStreamParserTest::InitCB, base::Unretained(this)),
+        base::Bind(&WebMStreamParserTest::NewConfigCB, base::Unretained(this)),
+        base::Bind(&WebMStreamParserTest::NewBuffersCB, base::Unretained(this)),
+        true,  // ignore_text_track
+        encrypted_media_init_data_cb,
+        base::Bind(&WebMStreamParserTest::NewMediaSegmentCB,
+                   base::Unretained(this)),
+        base::Bind(&WebMStreamParserTest::EndMediaSegmentCB,
+                   base::Unretained(this)),
+        media_log_);
+    bool result = parser_->Parse(buffer->data(), buffer->data_size());
+    EXPECT_TRUE(result);
+  }
+
+  MOCK_METHOD1(InitCB, void(const StreamParser::InitParameters& params));
+
+  bool NewConfigCB(scoped_ptr<MediaTracks> tracks,
+                   const StreamParser::TextTrackConfigMap& text_track_map) {
+    DCHECK(tracks.get());
+    media_tracks_ = std::move(tracks);
+    return true;
+  }
+
+  MOCK_METHOD3(NewBuffersCB,
+               bool(const StreamParser::BufferQueue&,
+                    const StreamParser::BufferQueue&,
+                    const StreamParser::TextBufferQueueMap&));
+  MOCK_METHOD2(OnEncryptedMediaInitData,
+               void(EmeInitDataType init_data_type,
+                    const std::vector<uint8_t>& init_data));
+  MOCK_METHOD0(NewMediaSegmentCB, void());
+  MOCK_METHOD0(EndMediaSegmentCB, void());
+
+  scoped_refptr<testing::StrictMock<MockMediaLog>> media_log_;
+  scoped_ptr<WebMStreamParser> parser_;
+  scoped_ptr<MediaTracks> media_tracks_;
+};
+
+TEST_F(WebMStreamParserTest, VerifyMediaTrackMetadata) {
+  EXPECT_MEDIA_LOG(testing::HasSubstr("Estimating WebM block duration"))
+      .Times(testing::AnyNumber());
+  ParseWebMFile("bear.webm");
+  EXPECT_NE(media_tracks_.get(), nullptr);
+
+  EXPECT_EQ(media_tracks_->tracks().size(), 2u);
+
+  const MediaTrack& video_track = *(media_tracks_->tracks()[0]);
+  EXPECT_EQ(video_track.type(), MediaTrack::Video);
+  EXPECT_EQ(video_track.id(), "1");
+  EXPECT_EQ(video_track.kind(), "main");
+  EXPECT_EQ(video_track.label(), "");
+  EXPECT_EQ(video_track.language(), "und");
+
+  const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
+  EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
+  EXPECT_EQ(audio_track.id(), "2");
+  EXPECT_EQ(audio_track.kind(), "main");
+  EXPECT_EQ(audio_track.label(), "");
+  EXPECT_EQ(audio_track.language(), "und");
+}
+
+}  // namespace media
diff --git a/media/formats/webm/webm_tracks_parser.cc b/media/formats/webm/webm_tracks_parser.cc
index 464a77ff..5ffa0aa 100644
--- a/media/formats/webm/webm_tracks_parser.cc
+++ b/media/formats/webm/webm_tracks_parser.cc
@@ -77,6 +77,7 @@
   video_decoder_config_ = VideoDecoderConfig();
   text_tracks_.clear();
   ignored_tracks_.clear();
+  media_tracks_.reset(new MediaTracks());
 
   WebMListParser parser(kWebMIdTracks, this);
   int result = parser.Parse(buf, size);
@@ -210,6 +211,9 @@
                 !audio_encryption_key_id_.empty(), &audio_decoder_config_)) {
           return false;
         }
+        media_tracks_->AddAudioTrack(audio_decoder_config_,
+                                     base::Uint64ToString(track_num_), "main",
+                                     track_name_, track_language_);
       } else {
         MEDIA_LOG(DEBUG, media_log_) << "Ignoring audio track " << track_num_;
         ignored_tracks_.insert(track_num_);
@@ -232,6 +236,9 @@
                 &video_decoder_config_)) {
           return false;
         }
+        media_tracks_->AddVideoTrack(video_decoder_config_,
+                                     base::Uint64ToString(track_num_), "main",
+                                     track_name_, track_language_);
       } else {
         MEDIA_LOG(DEBUG, media_log_) << "Ignoring video track " << track_num_;
         ignored_tracks_.insert(track_num_);
@@ -335,7 +342,15 @@
   }
 
   if (id == kWebMIdLanguage) {
-    track_language_ = str;
+    // Check that the language string is in ISO 639-2 format (3 letter code of a
+    // language, all lower-case letters).
+    if (str.size() != 3 || str[0] < 'a' || str[0] > 'z' || str[1] < 'a' ||
+        str[1] > 'z' || str[2] < 'a' || str[2] > 'z') {
+      VLOG(2) << "Ignoring kWebMIdLanguage (not ISO 639-2 compliant): " << str;
+      track_language_ = "und";
+    } else {
+      track_language_ = str;
+    }
     return true;
   }
 
diff --git a/media/formats/webm/webm_tracks_parser.h b/media/formats/webm/webm_tracks_parser.h
index 3569907..6286b23 100644
--- a/media/formats/webm/webm_tracks_parser.h
+++ b/media/formats/webm/webm_tracks_parser.h
@@ -18,6 +18,7 @@
 #include "base/time/time.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/media_log.h"
+#include "media/base/media_tracks.h"
 #include "media/base/text_track_config.h"
 #include "media/base/video_decoder_config.h"
 #include "media/formats/webm/webm_audio_client.h"
@@ -77,6 +78,15 @@
     return text_tracks_;
   }
 
+  // Note: Calling media_tracks() method passes the ownership of the MediaTracks
+  // object from WebMTracksParser to the caller (which is typically
+  // WebMStreamParser object). So this method must be called only once, after
+  // track parsing has been completed.
+  scoped_ptr<MediaTracks> media_tracks() {
+    CHECK(media_tracks_.get());
+    return std::move(media_tracks_);
+  }
+
  private:
   // WebMParserClient implementation.
   WebMParserClient* OnListStart(int id) override;
@@ -114,6 +124,8 @@
   WebMVideoClient video_client_;
   VideoDecoderConfig video_decoder_config_;
 
+  scoped_ptr<MediaTracks> media_tracks_;
+
   DISALLOW_COPY_AND_ASSIGN(WebMTracksParser);
 };
 
diff --git a/media/media.gyp b/media/media.gyp
index e7780ae..f254b8fd 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -1279,6 +1279,7 @@
         'formats/webm/webm_cluster_parser_unittest.cc',
         'formats/webm/webm_content_encodings_client_unittest.cc',
         'formats/webm/webm_parser_unittest.cc',
+        'formats/webm/webm_stream_parser_unittest.cc',
         'formats/webm/webm_tracks_parser_unittest.cc',
         'formats/webm/webm_webvtt_parser_unittest.cc',
         'muxers/webm_muxer_unittest.cc',
diff --git a/media/midi/midi_manager_win.cc b/media/midi/midi_manager_win.cc
index 10a4910..43900243 100644
--- a/media/midi/midi_manager_win.cc
+++ b/media/midi/midi_manager_win.cc
@@ -135,10 +135,12 @@
   // From an observation on Windows 7/8.1 with a USB-MIDI keyboard,
   // midiOutLongMsg() will be always blocked. Sending 64 bytes or less data
   // takes roughly 300 usecs. Sending 2048 bytes or more data takes roughly
-  // |message.size() / (75 * 1024)| secs in practice. Here we put 60 KB size
+  // |message.size() / (75 * 1024)| secs in practice. Here we put 256 KB size
   // limit on SysEx message, with hoping that midiOutLongMsg will be blocked at
-  // most 1 sec or so with a typical USB-MIDI device.
-  const size_t kSysExSizeLimit = 60 * 1024;
+  // most 4 sec or so with a typical USB-MIDI device.
+  // TODO(crbug.com/383578): This restriction should be removed once Web MIDI
+  // defines a standardized way to handle large sysex messages.
+  const size_t kSysExSizeLimit = 256 * 1024;
   if (message.size() >= kSysExSizeLimit) {
     DVLOG(1) << "Ingnoreing SysEx message due to the size limit"
              << ", size = " << message.size();
diff --git a/media/mojo/common/BUILD.gn b/media/mojo/common/BUILD.gn
index 1d0fa812..2e3e230 100644
--- a/media/mojo/common/BUILD.gn
+++ b/media/mojo/common/BUILD.gn
@@ -44,6 +44,7 @@
     "//mojo/edk/test:run_all_unittests",
     "//testing/gmock",
     "//testing/gtest",
+    "//ui/gfx:test_support",
   ]
 }
 
diff --git a/media/mojo/common/media_type_converters.cc b/media/mojo/common/media_type_converters.cc
index 5735cb0..f1bf033c 100644
--- a/media/mojo/common/media_type_converters.cc
+++ b/media/mojo/common/media_type_converters.cc
@@ -20,8 +20,10 @@
 #include "media/base/media_keys.h"
 #include "media/base/video_decoder_config.h"
 #include "media/base/video_frame.h"
+#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
 #include "media/mojo/interfaces/demuxer_stream.mojom.h"
 #include "mojo/converters/geometry/geometry_type_converters.h"
+#include "mojo/public/cpp/system/buffer.h"
 
 namespace mojo {
 
@@ -293,54 +295,6 @@
 ASSERT_CDM_MESSAGE_TYPE(LICENSE_RENEWAL);
 ASSERT_CDM_MESSAGE_TYPE(LICENSE_RELEASE);
 
-namespace {
-
-// Copy the data for plane |plane| from |input| into the vector |dest|. This
-// function only copies the actual frame data. Any padding data is skipped.
-void CopyPlaneDataToVector(const scoped_refptr<media::VideoFrame>& input,
-                           size_t plane,
-                           std::vector<uint8_t>* dest) {
-  DCHECK(dest->empty());
-  uint8_t* source = input->data(plane);
-  size_t num_rows = input->rows(plane);
-  size_t stride = input->stride(plane);
-  size_t row_bytes = input->row_bytes(plane);
-  DCHECK_GE(stride, row_bytes);
-
-  // Copy |row_bytes| for each row, but increment by |stride| to point at the
-  // subsequent row.
-  dest->reserve(num_rows * row_bytes);
-  for (size_t i = 0; i < num_rows; ++i) {
-    dest->insert(dest->end(), source, source + row_bytes);
-    source += stride;
-  }
-}
-
-// Copy the data from |input| into the plane |plane| of |frame|. If there is
-// padding in |frame|, it is unchanged.
-void CopyPlaneData(const std::vector<uint8_t>& input,
-                   size_t plane,
-                   const scoped_refptr<media::VideoFrame>& frame) {
-  const uint8_t* source = input.data();
-  uint8_t* dest = frame->data(plane);
-  size_t num_rows = frame->rows(plane);
-  size_t stride = frame->stride(plane);
-  size_t row_bytes = frame->row_bytes(plane);
-  DCHECK_GE(stride, row_bytes);
-  DCHECK_EQ(input.size(), num_rows * row_bytes);
-
-  // Copy |row_bytes| for each row. |input| contains only the data bytes, so
-  // |source| is only incremented by |row_bytes|. |dest| may contain padding,
-  // so increment by |stride| to point at the subsequent row.
-  for (size_t i = 0; i < num_rows; ++i) {
-    memcpy(dest, source, row_bytes);
-    source += row_bytes;
-    dest += stride;
-  }
-}
-
-}  // namespace
-
 // static
 media::interfaces::SubsampleEntryPtr TypeConverter<
     media::interfaces::SubsampleEntryPtr,
@@ -643,36 +597,38 @@
 TypeConverter<media::interfaces::VideoFramePtr,
               scoped_refptr<media::VideoFrame>>::
     Convert(const scoped_refptr<media::VideoFrame>& input) {
-  media::interfaces::VideoFramePtr buffer(media::interfaces::VideoFrame::New());
-  buffer->end_of_stream =
+  media::interfaces::VideoFramePtr frame(media::interfaces::VideoFrame::New());
+  frame->end_of_stream =
       input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM);
-  if (buffer->end_of_stream)
-    return buffer;
+  if (frame->end_of_stream)
+    return frame;
 
-  // handle non EOS buffer.
-  buffer->format = static_cast<media::interfaces::VideoFormat>(input->format());
-  buffer->coded_size = Size::From(input->coded_size());
-  buffer->visible_rect = Rect::From(input->visible_rect());
-  buffer->natural_size = Size::From(input->natural_size());
-  buffer->timestamp_usec = input->timestamp().InMicroseconds();
+  // Handle non EOS frame. It must be a MojoSharedBufferVideoFrame.
+  // TODO(jrummell): Support other types of VideoFrame.
+  CHECK_EQ(media::VideoFrame::STORAGE_MOJO_SHARED_BUFFER,
+           input->storage_type());
+  media::MojoSharedBufferVideoFrame* input_frame =
+      static_cast<media::MojoSharedBufferVideoFrame*>(input.get());
+  mojo::ScopedSharedBufferHandle duplicated_handle;
+  const MojoResult result =
+      DuplicateBuffer(input_frame->Handle(), nullptr, &duplicated_handle);
+  CHECK_EQ(MOJO_RESULT_OK, result);
+  CHECK(duplicated_handle.is_valid());
 
-  if (!input->coded_size().IsEmpty()) {
-    // TODO(jrummell): Use a shared buffer rather than copying the data for
-    // each plane.
-    std::vector<uint8_t> y_data;
-    CopyPlaneDataToVector(input, media::VideoFrame::kYPlane, &y_data);
-    buffer->y_data.Swap(&y_data);
-
-    std::vector<uint8_t> u_data;
-    CopyPlaneDataToVector(input, media::VideoFrame::kUPlane, &u_data);
-    buffer->u_data.Swap(&u_data);
-
-    std::vector<uint8_t> v_data;
-    CopyPlaneDataToVector(input, media::VideoFrame::kVPlane, &v_data);
-    buffer->v_data.Swap(&v_data);
-  }
-
-  return buffer;
+  frame->format = static_cast<media::interfaces::VideoFormat>(input->format());
+  frame->coded_size = Size::From(input->coded_size());
+  frame->visible_rect = Rect::From(input->visible_rect());
+  frame->natural_size = Size::From(input->natural_size());
+  frame->timestamp_usec = input->timestamp().InMicroseconds();
+  frame->frame_data = std::move(duplicated_handle);
+  frame->frame_data_size = input_frame->MappedSize();
+  frame->y_stride = input_frame->stride(media::VideoFrame::kYPlane);
+  frame->u_stride = input_frame->stride(media::VideoFrame::kUPlane);
+  frame->v_stride = input_frame->stride(media::VideoFrame::kVPlane);
+  frame->y_offset = input_frame->PlaneOffset(media::VideoFrame::kYPlane);
+  frame->u_offset = input_frame->PlaneOffset(media::VideoFrame::kUPlane);
+  frame->v_offset = input_frame->PlaneOffset(media::VideoFrame::kVPlane);
+  return frame;
 }
 
 // static
@@ -683,16 +639,16 @@
   if (input->end_of_stream)
     return media::VideoFrame::CreateEOSFrame();
 
-  scoped_refptr<media::VideoFrame> frame = media::VideoFrame::CreateFrame(
+  return media::MojoSharedBufferVideoFrame::Create(
       static_cast<media::VideoPixelFormat>(input->format),
       input->coded_size.To<gfx::Size>(), input->visible_rect.To<gfx::Rect>(),
-      input->natural_size.To<gfx::Size>(),
+      input->natural_size.To<gfx::Size>(), std::move(input->frame_data),
+      base::saturated_cast<size_t>(input->frame_data_size),
+      base::saturated_cast<size_t>(input->y_offset),
+      base::saturated_cast<size_t>(input->u_offset),
+      base::saturated_cast<size_t>(input->v_offset), input->y_stride,
+      input->u_stride, input->v_stride,
       base::TimeDelta::FromMicroseconds(input->timestamp_usec));
-  CopyPlaneData(input->y_data.storage(), media::VideoFrame::kYPlane, frame);
-  CopyPlaneData(input->u_data.storage(), media::VideoFrame::kUPlane, frame);
-  CopyPlaneData(input->v_data.storage(), media::VideoFrame::kVPlane, frame);
-
-  return frame;
 }
 
 }  // namespace mojo
diff --git a/media/mojo/common/media_type_converters_unittest.cc b/media/mojo/common/media_type_converters_unittest.cc
index f9de05d..9858cd0 100644
--- a/media/mojo/common/media_type_converters_unittest.cc
+++ b/media/mojo/common/media_type_converters_unittest.cc
@@ -17,6 +17,7 @@
 #include "media/base/sample_format.h"
 #include "media/base/test_helpers.h"
 #include "media/base/video_frame.h"
+#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace media {
@@ -90,9 +91,8 @@
 
 void CompareVideoFrames(const scoped_refptr<VideoFrame>& original,
                         const scoped_refptr<VideoFrame>& result) {
-  if (original->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM)) {
-    EXPECT_TRUE(
-        result->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM));
+  if (original->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) {
+    EXPECT_TRUE(result->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
     return;
   }
 
@@ -104,9 +104,69 @@
   EXPECT_EQ(original->natural_size().height(), result->natural_size().height());
   EXPECT_EQ(original->natural_size().width(), result->natural_size().width());
 
-  CompareVideoPlane(media::VideoFrame::kYPlane, original, result);
-  CompareVideoPlane(media::VideoFrame::kUPlane, original, result);
-  CompareVideoPlane(media::VideoFrame::kVPlane, original, result);
+  CompareVideoPlane(VideoFrame::kYPlane, original, result);
+  CompareVideoPlane(VideoFrame::kUPlane, original, result);
+  CompareVideoPlane(VideoFrame::kVPlane, original, result);
+}
+
+// Returns a color VideoFrame that stores the data in a
+// mojo::SharedBufferHandle.
+scoped_refptr<VideoFrame> CreateMojoSharedBufferColorFrame() {
+  // Create a color VideoFrame to use as reference (data will need to be copied
+  // to a mojo::SharedBufferHandle).
+  const int kWidth = 16;
+  const int kHeight = 9;
+  const base::TimeDelta kTimestamp = base::TimeDelta::FromSeconds(26);
+  scoped_refptr<VideoFrame> color_frame(VideoFrame::CreateColorFrame(
+      gfx::Size(kWidth, kHeight), 255, 128, 24, kTimestamp));
+
+  // Allocate a mojo::SharedBufferHandle big enough to contain
+  // |color_frame|'s data.
+  const size_t allocation_size = VideoFrame::AllocationSize(
+      color_frame->format(), color_frame->coded_size());
+  mojo::ScopedSharedBufferHandle handle;
+  const MojoResult mojo_result =
+      mojo::CreateSharedBuffer(nullptr, allocation_size, &handle);
+  EXPECT_EQ(mojo_result, MOJO_RESULT_OK);
+
+  // Create a MojoSharedBufferVideoFrame whose dimensions match |color_frame|.
+  const size_t y_plane_size = color_frame->rows(VideoFrame::kYPlane) *
+                              color_frame->stride(VideoFrame::kYPlane);
+  const size_t u_plane_size = color_frame->rows(VideoFrame::kUPlane) *
+                              color_frame->stride(VideoFrame::kUPlane);
+  const size_t v_plane_size = color_frame->rows(VideoFrame::kVPlane) *
+                              color_frame->stride(VideoFrame::kVPlane);
+  scoped_refptr<VideoFrame> frame(MojoSharedBufferVideoFrame::Create(
+      color_frame->format(), color_frame->coded_size(),
+      color_frame->visible_rect(), color_frame->natural_size(),
+      std::move(handle), allocation_size, 0, y_plane_size,
+      y_plane_size + u_plane_size, color_frame->stride(VideoFrame::kYPlane),
+      color_frame->stride(VideoFrame::kUPlane),
+      color_frame->stride(VideoFrame::kVPlane), color_frame->timestamp()));
+  EXPECT_EQ(color_frame->coded_size(), frame->coded_size());
+  EXPECT_EQ(color_frame->visible_rect(), frame->visible_rect());
+  EXPECT_EQ(color_frame->natural_size(), frame->natural_size());
+  EXPECT_EQ(color_frame->rows(VideoFrame::kYPlane),
+            frame->rows(VideoFrame::kYPlane));
+  EXPECT_EQ(color_frame->rows(VideoFrame::kUPlane),
+            frame->rows(VideoFrame::kUPlane));
+  EXPECT_EQ(color_frame->rows(VideoFrame::kVPlane),
+            frame->rows(VideoFrame::kVPlane));
+  EXPECT_EQ(color_frame->stride(VideoFrame::kYPlane),
+            frame->stride(VideoFrame::kYPlane));
+  EXPECT_EQ(color_frame->stride(VideoFrame::kUPlane),
+            frame->stride(VideoFrame::kUPlane));
+  EXPECT_EQ(color_frame->stride(VideoFrame::kVPlane),
+            frame->stride(VideoFrame::kVPlane));
+
+  // Copy all the data from |color_frame| into |frame|.
+  memcpy(frame->data(VideoFrame::kYPlane),
+         color_frame->data(VideoFrame::kYPlane), y_plane_size);
+  memcpy(frame->data(VideoFrame::kUPlane),
+         color_frame->data(VideoFrame::kUPlane), u_plane_size);
+  memcpy(frame->data(VideoFrame::kVPlane),
+         color_frame->data(VideoFrame::kVPlane), v_plane_size);
+  return frame;
 }
 
 }  // namespace
@@ -372,30 +432,30 @@
   CompareVideoFrames(buffer, result);
 }
 
-TEST(MediaTypeConvertersTest, ConvertVideoFrame_BlackFrame) {
+TEST(MediaTypeConvertersTest, ConvertVideoFrame_EmptyFrame) {
   // Original.
-  scoped_refptr<VideoFrame> buffer(
-      VideoFrame::CreateBlackFrame(gfx::Size(100, 100)));
+  scoped_refptr<VideoFrame> frame(MojoSharedBufferVideoFrame::CreateDefaultI420(
+      gfx::Size(100, 100), base::TimeDelta::FromSeconds(100)));
 
   // Convert to and back.
-  interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+  interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(frame));
   scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+  EXPECT_NE(result.get(), nullptr);
 
   // Compare.
-  CompareVideoFrames(buffer, result);
+  CompareVideoFrames(frame, result);
 }
 
 TEST(MediaTypeConvertersTest, ConvertVideoFrame_ColorFrame) {
-  // Original.
-  scoped_refptr<VideoFrame> buffer(VideoFrame::CreateColorFrame(
-      gfx::Size(50, 100), 255, 128, 128, base::TimeDelta::FromSeconds(26)));
+  scoped_refptr<VideoFrame> frame(CreateMojoSharedBufferColorFrame());
 
   // Convert to and back.
-  interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+  interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(frame));
   scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+  EXPECT_NE(result.get(), nullptr);
 
   // Compare.
-  CompareVideoFrames(buffer, result);
+  CompareVideoFrames(frame, result);
 }
 
 }  // namespace media
diff --git a/media/mojo/common/mojo_shared_buffer_video_frame.cc b/media/mojo/common/mojo_shared_buffer_video_frame.cc
index fa226c2..3fca408b 100644
--- a/media/mojo/common/mojo_shared_buffer_video_frame.cc
+++ b/media/mojo/common/mojo_shared_buffer_video_frame.cc
@@ -144,4 +144,12 @@
   return offsets_[plane];
 }
 
+const mojo::SharedBufferHandle& MojoSharedBufferVideoFrame::Handle() const {
+  return shared_buffer_handle_.get();
+}
+
+size_t MojoSharedBufferVideoFrame::MappedSize() const {
+  return shared_buffer_size_;
+}
+
 }  // namespace media
diff --git a/media/mojo/common/mojo_shared_buffer_video_frame.h b/media/mojo/common/mojo_shared_buffer_video_frame.h
index d27a85f..bc49c3f 100644
--- a/media/mojo/common/mojo_shared_buffer_video_frame.h
+++ b/media/mojo/common/mojo_shared_buffer_video_frame.h
@@ -15,8 +15,19 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 
+namespace mojo {
+template <typename T, typename U>
+struct TypeConverter;
+template <typename T>
+class StructPtr;
+};
+
 namespace media {
 
+namespace interfaces {
+class VideoFrame;
+}
+
 // A derived class of media::VideoFrame holding a mojo::SharedBufferHandle
 // which is mapped on constructor and remains so for the lifetime of the
 // object. These frames are ref-counted.
@@ -53,6 +64,11 @@
   size_t PlaneOffset(size_t plane) const;
 
  private:
+  // mojo::TypeConverter added as a friend so that MojoSharedBufferVideoFrame
+  // can be transferred across a mojo connection.
+  friend struct mojo::TypeConverter<mojo::StructPtr<interfaces::VideoFrame>,
+                                    scoped_refptr<VideoFrame>>;
+
   MojoSharedBufferVideoFrame(VideoPixelFormat format,
                              const gfx::Size& coded_size,
                              const gfx::Rect& visible_rect,
@@ -71,6 +87,14 @@
             size_t u_offset,
             size_t v_offset);
 
+  // Returns the mojo shared memory handle. This object continues to own the
+  // handle. Caller should call duplicate the handle if they want to keep a
+  // copy of the shared memory.
+  const mojo::SharedBufferHandle& Handle() const;
+
+  // Returns the size of the shared memory.
+  size_t MappedSize() const;
+
   mojo::ScopedSharedBufferHandle shared_buffer_handle_;
   size_t shared_buffer_size_;
   uint8_t* shared_buffer_data_;
diff --git a/media/mojo/interfaces/media_types.mojom b/media/mojo/interfaces/media_types.mojom
index 085256e..44e6cdf 100644
--- a/media/mojo/interfaces/media_types.mojom
+++ b/media/mojo/interfaces/media_types.mojom
@@ -266,8 +266,6 @@
 };
 
 // This defines a mojo transport format for media::VideoFrame.
-// TODO(jrummell): Support shared memory based VideoFrame to avoid copying
-// the data multiple times.
 struct VideoFrame {
   // Format of the frame.
   VideoFormat format;
@@ -287,8 +285,16 @@
   // Timestamp in microseconds of the associated frame.
   int64 timestamp_usec;
 
-  // Frame data for each plane. Will be null for EOS buffers.
-  array<uint8>? y_data;
-  array<uint8>? u_data;
-  array<uint8>? v_data;
+  // Reference to the shared memory containing the frame's data.
+  handle<shared_buffer> frame_data;
+  uint64 frame_data_size;
+
+  // Stride and offsets for each plane. Offsets are relative to the start
+  // of |frame_data|.
+  int32 y_stride;
+  int32 u_stride;
+  int32 v_stride;
+  uint64 y_offset;
+  uint64 u_offset;
+  uint64 v_offset;
 };
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn
index 779cb894..e18e93d 100644
--- a/mojo/BUILD.gn
+++ b/mojo/BUILD.gn
@@ -41,7 +41,6 @@
     "//mojo/edk/test:mojo_public_bindings_unittests",
     "//mojo/edk/test:mojo_public_system_perftests",
     "//mojo/edk/test:mojo_public_system_unittests",
-    "//mojo/edk/test:mojo_public_utility_unittests",
     "//mojo/services/network:apptests",
     "//mojo/shell/public/cpp/tests:mojo_public_application_unittests",
     "//mojo/shell/runner/host:mojo_runner_host_unittests",
diff --git a/mojo/edk/embedder/embedder_unittest.cc b/mojo/edk/embedder/embedder_unittest.cc
index 9b96c1f5..b5927b3f 100644
--- a/mojo/edk/embedder/embedder_unittest.cc
+++ b/mojo/edk/embedder/embedder_unittest.cc
@@ -24,7 +24,6 @@
 #include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/c/system/core.h"
 #include "mojo/public/cpp/system/handle.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/mojo/edk/embedder/platform_channel_pair.h b/mojo/edk/embedder/platform_channel_pair.h
index 596ed2e..591592bd 100644
--- a/mojo/edk/embedder/platform_channel_pair.h
+++ b/mojo/edk/embedder/platform_channel_pair.h
@@ -11,7 +11,6 @@
 #include "build/build_config.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
 #include "mojo/edk/system/system_impl_export.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace base {
 class CommandLine;
diff --git a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
index 45a6dce..e05cd799 100644
--- a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
+++ b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
@@ -27,7 +27,6 @@
 #include "mojo/edk/embedder/platform_handle_vector.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
 #include "mojo/edk/test/test_utils.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/embedder/platform_shared_buffer.h b/mojo/edk/embedder/platform_shared_buffer.h
index 7ca596a..dfe91651 100644
--- a/mojo/edk/embedder/platform_shared_buffer.h
+++ b/mojo/edk/embedder/platform_shared_buffer.h
@@ -15,7 +15,6 @@
 #include "base/synchronization/lock.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
 #include "mojo/edk/system/system_impl_export.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace edk {
diff --git a/mojo/edk/embedder/platform_shared_buffer_unittest.cc b/mojo/edk/embedder/platform_shared_buffer_unittest.cc
index 5c12f85..098ff26a 100644
--- a/mojo/edk/embedder/platform_shared_buffer_unittest.cc
+++ b/mojo/edk/embedder/platform_shared_buffer_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/shared_memory.h"
 #include "base/sys_info.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(OS_WIN)
diff --git a/mojo/edk/js/test/BUILD.gn b/mojo/edk/js/test/BUILD.gn
index 0ac9945..3da5bc8b 100644
--- a/mojo/edk/js/test/BUILD.gn
+++ b/mojo/edk/js/test/BUILD.gn
@@ -14,7 +14,6 @@
     "//mojo/edk/test:run_all_unittests",
     "//mojo/edk/test:test_support",
     "//mojo/public/cpp/system",
-    "//mojo/public/cpp/utility",
     "//mojo/public/interfaces/bindings/tests:test_interfaces",
     "//mojo/public/interfaces/bindings/tests:test_interfaces_experimental",
   ]
diff --git a/mojo/edk/js/tests/js_to_cpp_tests.cc b/mojo/edk/js/tests/js_to_cpp_tests.cc
index 08f3a0c3..6d3426d 100644
--- a/mojo/edk/js/tests/js_to_cpp_tests.cc
+++ b/mojo/edk/js/tests/js_to_cpp_tests.cc
@@ -24,7 +24,6 @@
 #include "mojo/edk/test/test_utils.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/core.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/system/core_test_base.cc b/mojo/edk/system/core_test_base.cc
index dd1473a..635501aa 100644
--- a/mojo/edk/system/core_test_base.cc
+++ b/mojo/edk/system/core_test_base.cc
@@ -16,7 +16,6 @@
 #include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/core.h"
 #include "mojo/edk/system/dispatcher.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace edk {
diff --git a/mojo/edk/system/core_test_base.h b/mojo/edk/system/core_test_base.h
index 665b9a0..3d2346a2 100644
--- a/mojo/edk/system/core_test_base.h
+++ b/mojo/edk/system/core_test_base.h
@@ -12,7 +12,6 @@
 #include "mojo/edk/embedder/embedder_internal.h"
 #include "mojo/edk/system/test_utils.h"
 #include "mojo/public/c/system/types.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc
index a339767..7eeabc0 100644
--- a/mojo/edk/system/core_unittest.cc
+++ b/mojo/edk/system/core_unittest.cc
@@ -13,7 +13,6 @@
 #include "mojo/edk/system/awakable.h"
 #include "mojo/edk/system/core_test_base.h"
 #include "mojo/edk/system/test_utils.h"
-#include "mojo/public/cpp/system/macros.h"
 
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
diff --git a/mojo/edk/system/data_pipe.h b/mojo/edk/system/data_pipe.h
index d2b90bf..2428189 100644
--- a/mojo/edk/system/data_pipe.h
+++ b/mojo/edk/system/data_pipe.h
@@ -13,7 +13,6 @@
 #include "mojo/edk/system/system_impl_export.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/c/system/types.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace edk {
diff --git a/mojo/edk/system/data_pipe_unittest.cc b/mojo/edk/system/data_pipe_unittest.cc
index a3432824..944340b 100644
--- a/mojo/edk/system/data_pipe_unittest.cc
+++ b/mojo/edk/system/data_pipe_unittest.cc
@@ -19,7 +19,6 @@
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/c/system/functions.h"
 #include "mojo/public/c/system/message_pipe.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/system/mapping_table.h b/mojo/edk/system/mapping_table.h
index ed0a0f6..120f9cad 100644
--- a/mojo/edk/system/mapping_table.h
+++ b/mojo/edk/system/mapping_table.h
@@ -10,10 +10,10 @@
 #include <vector>
 
 #include "base/containers/hash_tables.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "mojo/edk/system/system_impl_export.h"
 #include "mojo/public/c/system/types.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/edk/system/options_validation.h b/mojo/edk/system/options_validation.h
index ac81954..e1b337d 100644
--- a/mojo/edk/system/options_validation.h
+++ b/mojo/edk/system/options_validation.h
@@ -20,7 +20,6 @@
 #include "base/macros.h"
 #include "mojo/edk/system/system_impl_export.h"
 #include "mojo/public/c/system/types.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace edk {
diff --git a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
index 902f7867..5605264 100644
--- a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
+++ b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
@@ -9,10 +9,10 @@
 
 #include <limits>
 
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "mojo/edk/embedder/platform_shared_buffer.h"
 #include "mojo/edk/system/dispatcher.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/system/test_utils.h b/mojo/edk/system/test_utils.h
index b576f817..1c90dc17 100644
--- a/mojo/edk/system/test_utils.h
+++ b/mojo/edk/system/test_utils.h
@@ -8,7 +8,6 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "mojo/public/c/system/types.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/system/wait_set_dispatcher_unittest.cc b/mojo/edk/system/wait_set_dispatcher_unittest.cc
index 10347054..a90a356 100644
--- a/mojo/edk/system/wait_set_dispatcher_unittest.cc
+++ b/mojo/edk/system/wait_set_dispatcher_unittest.cc
@@ -16,7 +16,6 @@
 #include "mojo/edk/system/message_pipe_dispatcher.h"
 #include "mojo/edk/system/test_utils.h"
 #include "mojo/edk/system/waiter.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/system/waiter_test_utils.h b/mojo/edk/system/waiter_test_utils.h
index 016b2959..eda1396 100644
--- a/mojo/edk/system/waiter_test_utils.h
+++ b/mojo/edk/system/waiter_test_utils.h
@@ -7,13 +7,13 @@
 
 #include <stdint.h>
 
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/simple_thread.h"
 #include "mojo/edk/system/dispatcher.h"
 #include "mojo/edk/system/handle_signals_state.h"
 #include "mojo/edk/system/waiter.h"
 #include "mojo/public/c/system/types.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace edk {
diff --git a/mojo/edk/system/waiter_unittest.cc b/mojo/edk/system/waiter_unittest.cc
index 16250cc..aa928ffe 100644
--- a/mojo/edk/system/waiter_unittest.cc
+++ b/mojo/edk/system/waiter_unittest.cc
@@ -11,10 +11,10 @@
 
 #include <stdint.h>
 
+#include "base/macros.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/simple_thread.h"
 #include "mojo/edk/system/test_utils.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/edk/test/BUILD.gn b/mojo/edk/test/BUILD.gn
index 171d087..791d62c0 100644
--- a/mojo/edk/test/BUILD.gn
+++ b/mojo/edk/test/BUILD.gn
@@ -94,7 +94,6 @@
     ":mojo_public_bindings_unittests",
     ":mojo_public_system_perftests",
     ":mojo_public_system_unittests",
-    ":mojo_public_utility_unittests",
   ]
 }
 
@@ -127,10 +126,3 @@
     "//mojo/public/cpp/system/tests",
   ]
 }
-
-test("mojo_public_utility_unittests") {
-  deps = [
-    ":run_all_unittests",
-    "//mojo/public/cpp/utility/tests",
-  ]
-}
diff --git a/mojo/edk/test/scoped_ipc_support.h b/mojo/edk/test/scoped_ipc_support.h
index ff2f558..04173d3 100644
--- a/mojo/edk/test/scoped_ipc_support.h
+++ b/mojo/edk/test/scoped_ipc_support.h
@@ -11,7 +11,6 @@
 #include "base/task_runner.h"
 #include "mojo/edk/embedder/process_delegate.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace edk {
diff --git a/mojo/mojo_base.gyp b/mojo/mojo_base.gyp
index 69f970a2..009dda1 100644
--- a/mojo/mojo_base.gyp
+++ b/mojo/mojo_base.gyp
@@ -215,7 +215,6 @@
         '../testing/gtest.gyp:gtest',
         'mojo_application_base',
         'mojo_edk.gyp:mojo_run_all_unittests',
-        'mojo_public.gyp:mojo_utility',
       ],
       'sources': [
         'shell/public/cpp/tests/interface_registry_unittest.cc',
diff --git a/mojo/mojo_edk_tests.gyp b/mojo/mojo_edk_tests.gyp
index 1055a86..b8ff828 100644
--- a/mojo/mojo_edk_tests.gyp
+++ b/mojo/mojo_edk_tests.gyp
@@ -21,7 +21,6 @@
         'mojo_public_bindings_unittests',
         'mojo_public_system_perftests',
         'mojo_public_system_unittests',
-        'mojo_public_utility_unittests',
         'mojo_system_unittests',
         'mojo_js_unittests',
         'mojo_js_integration_tests',
@@ -56,7 +55,6 @@
         'mojo_public.gyp:mojo_public_test_interfaces_chromium',
         'mojo_public.gyp:mojo_public_test_interfaces_struct_traits',
         'mojo_public.gyp:mojo_public_test_utils',
-        'mojo_public.gyp:mojo_utility',
       ],
       'sources': [
         'public/cpp/bindings/tests/array_unittest.cc',
@@ -72,6 +70,7 @@
         'public/cpp/bindings/tests/equals_unittest.cc',
         'public/cpp/bindings/tests/handle_passing_unittest.cc',
         'public/cpp/bindings/tests/interface_ptr_unittest.cc',
+        'public/cpp/bindings/tests/macros_unittest.cc',
         'public/cpp/bindings/tests/map_unittest.cc',
         'public/cpp/bindings/tests/message_queue.cc',
         'public/cpp/bindings/tests/message_queue.h',
@@ -115,7 +114,6 @@
         'mojo_public.gyp:mojo_public_bindings_test_utils',
         'mojo_public.gyp:mojo_public_test_interfaces',
         'mojo_public.gyp:mojo_public_test_utils',
-        'mojo_public.gyp:mojo_utility',
       ],
       'sources': [
         'public/cpp/bindings/tests/bindings_perftest.cc',
@@ -138,32 +136,6 @@
       ],
     },
     {
-      # GN version: //mojo/public/cpp/application/tests:mojo_public_utility_unittests
-      'target_name': 'mojo_public_utility_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../testing/gtest.gyp:gtest',
-        'mojo_edk.gyp:mojo_run_all_unittests',
-        'mojo_public.gyp:mojo_cpp_bindings',
-        'mojo_public.gyp:mojo_public_test_utils',
-        'mojo_public.gyp:mojo_utility',
-      ],
-      'sources': [
-        'public/cpp/utility/tests/mutex_unittest.cc',
-        'public/cpp/utility/tests/run_loop_unittest.cc',
-        'public/cpp/utility/tests/thread_unittest.cc',
-      ],
-      'conditions': [
-        # See crbug.com/342893:
-        ['OS=="win"', {
-          'sources!': [
-            'public/cpp/utility/tests/mutex_unittest.cc',
-            'public/cpp/utility/tests/thread_unittest.cc',
-          ],
-        }],
-      ],
-    },
-    {
       # GN version: //mojo/edk/test:mojo_public_system_perftests
       'target_name': 'mojo_public_system_perftests',
       'type': 'executable',
@@ -247,7 +219,6 @@
         'mojo_edk.gyp:mojo_run_all_unittests',
         'mojo_edk.gyp:mojo_js_lib',
         'mojo_public.gyp:mojo_public_test_interfaces',
-        'mojo_public.gyp:mojo_utility',
       ],
       'sources': [
         'edk/js/handle_unittest.cc',
@@ -266,7 +237,6 @@
         'mojo_edk.gyp:mojo_run_all_unittests',
         'mojo_js_to_cpp_bindings',
         'mojo_public.gyp:mojo_public_test_interfaces',
-        'mojo_public.gyp:mojo_utility',
       ],
       'sources': [
         'edk/js/test/run_js_integration_tests.cc',
@@ -313,19 +283,6 @@
             'mojo_public_system_unittests.isolate',
           ],
         },
-        {
-          'target_name': 'mojo_public_utility_unittests_run',
-          'type': 'none',
-          'dependencies': [
-            'mojo_public_utility_unittests',
-          ],
-          'includes': [
-            '../build/isolate.gypi',
-          ],
-          'sources': [
-            'mojo_public_utility_unittests.isolate',
-          ],
-        },
       ],
     }],
   ],
diff --git a/mojo/mojo_public.gyp b/mojo/mojo_public.gyp
index d090dc3..28441951 100644
--- a/mojo/mojo_public.gyp
+++ b/mojo/mojo_public.gyp
@@ -20,7 +20,6 @@
         'mojo_public_test_interfaces',
         'mojo_public_test_utils',
         'mojo_system',
-        'mojo_utility',
       ],
     },
     {
@@ -82,7 +81,6 @@
         'public/cpp/system/data_pipe.h',
         'public/cpp/system/functions.h',
         'public/cpp/system/handle.h',
-        'public/cpp/system/macros.h',
         'public/cpp/system/message_pipe.h',
         'public/cpp/system/watcher.cc',
         'public/cpp/system/watcher.h',
@@ -140,6 +138,7 @@
         'public/cpp/bindings/lib/interface_endpoint_client.cc',
         'public/cpp/bindings/lib/interface_endpoint_client.h',
         'public/cpp/bindings/lib/interface_ptr_state.h',
+        'public/cpp/bindings/lib/macros.h',
         'public/cpp/bindings/lib/map_data_internal.h',
         'public/cpp/bindings/lib/map_internal.h',
         'public/cpp/bindings/lib/map_serialization.h',
@@ -232,37 +231,6 @@
       ],
     },
     {
-      # GN version: //mojo/public/cpp/utility
-      'target_name': 'mojo_utility',
-      'type': 'static_library',
-      'sources': [
-        'public/cpp/utility/lib/mutex.cc',
-        'public/cpp/utility/lib/run_loop.cc',
-        'public/cpp/utility/lib/thread.cc',
-        'public/cpp/utility/lib/thread_local.h',
-        'public/cpp/utility/lib/thread_local_posix.cc',
-        'public/cpp/utility/lib/thread_local_win.cc',
-        'public/cpp/utility/mutex.h',
-        'public/cpp/utility/run_loop.h',
-        'public/cpp/utility/run_loop_handler.h',
-        'public/cpp/utility/thread.h',
-      ],
-      'conditions': [
-        # See crbug.com/342893:
-        ['OS=="win"', {
-          'sources!': [
-            'public/cpp/utility/lib/mutex.cc',
-            'public/cpp/utility/lib/thread.cc',
-            'public/cpp/utility/mutex.h',
-            'public/cpp/utility/thread.h',
-          ],
-        }],
-      ],
-      'include_dirs': [
-        '..',
-      ],
-    },
-    {
       'target_name': 'mojo_interface_bindings_mojom',
       'type': 'none',
       'variables': {
diff --git a/mojo/mojo_public_utility_unittests.isolate b/mojo/mojo_public_utility_unittests.isolate
deleted file mode 100644
index d3fccf9..0000000
--- a/mojo/mojo_public_utility_unittests.isolate
+++ /dev/null
@@ -1,44 +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.
-{
-  'includes': [
-    '../base/base.isolate',
-  ],
-  'conditions': [
-    ['OS=="win" or OS=="mac" or OS=="linux"', {
-      'variables': {
-        'command': [
-          '../testing/test_env.py',
-          '<(PRODUCT_DIR)/mojo_public_utility_unittests<(EXECUTABLE_SUFFIX)',
-          '--brave-new-test-launcher',
-          '--test-launcher-bot-mode',
-        ],
-        'files': [
-          '../testing/test_env.py',
-        ],
-      },
-    }],
-    ['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_shell.gyp b/mojo/mojo_shell.gyp
index 35192b1..213857b4 100644
--- a/mojo/mojo_shell.gyp
+++ b/mojo/mojo_shell.gyp
@@ -41,6 +41,9 @@
       '<(DEPTH)/net/net.gyp:net',
       '<(DEPTH)/url/url.gyp:url_lib',
     ],
+    'export_dependent_settings': [
+      '<(DEPTH)/mojo/mojo_base.gyp:mojo_application_bindings',
+    ],
   }, {
     'target_name': 'mojo_shell_unittests',
     'type': 'executable',
@@ -86,6 +89,9 @@
       '<(DEPTH)/mojo/mojo_platform_handle.gyp:platform_handle',
       '<(DEPTH)/mojo/mojo_public.gyp:mojo_message_pump_lib',
     ],
+    'export_dependent_settings': [
+      '<(DEPTH)/mojo/mojo_base.gyp:mojo_application_bindings',
+    ],
   }, {
     'target_name': 'mojo_runner_common_lib',
     'type': 'static_library',
@@ -121,10 +127,14 @@
       '<(DEPTH)/base/base.gyp:base',
       '<(DEPTH)/base/base.gyp:base_i18n',
       '<(DEPTH)/base/base.gyp:base_static',
+      '<(DEPTH)/mojo/mojo_base.gyp:mojo_application_bindings',
       '<(DEPTH)/mojo/mojo_edk.gyp:mojo_system_impl',
       '<(DEPTH)/mojo/mojo_platform_handle.gyp:platform_handle',
       '<(DEPTH)/mojo/mojo_public.gyp:mojo_message_pump_lib',
     ],
+    'export_dependent_settings': [
+      '<(DEPTH)/mojo/mojo_base.gyp:mojo_application_bindings',
+    ],
     'conditions': [
       ['OS=="linux"', {
         'sources': [
diff --git a/mojo/mojo_variables.gypi b/mojo/mojo_variables.gypi
index 66ec138..e19aa95 100644
--- a/mojo/mojo_variables.gypi
+++ b/mojo/mojo_variables.gypi
@@ -44,7 +44,6 @@
       '<(DEPTH)/mojo/public/c/system/tests/core_unittest_pure_c.c',
       '<(DEPTH)/mojo/public/c/system/tests/macros_unittest.cc',
       '<(DEPTH)/mojo/public/cpp/system/tests/core_unittest.cc',
-      '<(DEPTH)/mojo/public/cpp/system/tests/macros_unittest.cc',
       '<(DEPTH)/mojo/public/cpp/system/tests/watcher_unittest.cc',
     ],
   },
diff --git a/mojo/public/BUILD.gn b/mojo/public/BUILD.gn
index cbe8c7e..94424796 100644
--- a/mojo/public/BUILD.gn
+++ b/mojo/public/BUILD.gn
@@ -8,7 +8,6 @@
   deps = [
     ":sdk",
     "cpp/bindings",
-    "cpp/utility",
     "interfaces/bindings/tests:test_interfaces",
   ]
 
@@ -24,7 +23,6 @@
   deps = [
     "c/system",
     "cpp/bindings",
-    "cpp/utility",
     "interfaces/bindings",
     "js",
   ]
diff --git a/mojo/public/c/system/macros.h b/mojo/public/c/system/macros.h
index ce84170..917c69c 100644
--- a/mojo/public/c/system/macros.h
+++ b/mojo/public/c/system/macros.h
@@ -7,20 +7,6 @@
 
 #include <stddef.h>
 
-#ifdef __cplusplus
-// Used to explicitly mark the return value of a function as unused. If you are
-// really sure you don't want to do anything with the return value of a function
-// that has been marked WARN_UNUSED_RESULT, wrap it with this. Example:
-//
-//   scoped_ptr<MyType> my_var = ...;
-//   if (TakeOwnership(my_var.get()) == SUCCESS)
-//     mojo_ignore_result(my_var.release());
-//
-template <typename T>
-inline void mojo_ignore_result(const T&) {
-}
-#endif
-
 // Assert things at compile time. (|msg| should be a valid identifier name.)
 // This macro is currently C++-only, but we want to use it in the C core.h.
 // Use like:
diff --git a/mojo/public/c/system/tests/core_perftest.cc b/mojo/public/c/system/tests/core_perftest.cc
index 80734d30..5d4e56b 100644
--- a/mojo/public/c/system/tests/core_perftest.cc
+++ b/mojo/public/c/system/tests/core_perftest.cc
@@ -10,8 +10,8 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#include "base/macros.h"
 #include "base/threading/simple_thread.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/public/cpp/test_support/test_support.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/mojo/public/cpp/README.md b/mojo/public/cpp/README.md
index fbbf86cf..d0f1238 100644
--- a/mojo/public/cpp/README.md
+++ b/mojo/public/cpp/README.md
@@ -36,13 +36,3 @@
 The test_support/ subdirectory contains C++ wrappers of the test-only API
 defined in mojo/public/c/test_support/. It is not meant for general use by Mojo
 applications.
-
-Utility
--------
-
-TODO(yzshen): remove.
-
-The utility/ subdirectory contains a support (static) library that provides
-various basic functionality. Most notably, it provides an implementation of a
-RunLoop based on MojoWaitMany() that applications may use as the basis for
-asynchronous message processing.
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn
index 137d8d34..0486a52 100644
--- a/mojo/public/cpp/bindings/BUILD.gn
+++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -43,6 +43,7 @@
     "lib/interface_endpoint_client.h",
     "lib/interface_id.h",
     "lib/interface_ptr_state.h",
+    "lib/macros.h",
     "lib/map_data_internal.h",
     "lib/map_internal.h",
     "lib/map_serialization.h",
diff --git a/mojo/public/cpp/bindings/interface_ptr_info.h b/mojo/public/cpp/bindings/interface_ptr_info.h
index 4d559f5..014410d 100644
--- a/mojo/public/cpp/bindings/interface_ptr_info.h
+++ b/mojo/public/cpp/bindings/interface_ptr_info.h
@@ -8,7 +8,7 @@
 #include <stdint.h>
 #include <utility>
 
-#include "mojo/public/cpp/system/macros.h"
+#include "base/move.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 
 namespace mojo {
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc
index c7378f0..c84a93dc 100644
--- a/mojo/public/cpp/bindings/lib/connector.cc
+++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -108,7 +108,7 @@
     HandleError(rv != MOJO_RESULT_FAILED_PRECONDITION, false);
     return false;
   }
-  mojo_ignore_result(ReadSingleMessage(&rv));
+  ignore_result(ReadSingleMessage(&rv));
   return (rv == MOJO_RESULT_OK);
 }
 
diff --git a/mojo/public/cpp/bindings/lib/control_message_handler.h b/mojo/public/cpp/bindings/lib/control_message_handler.h
index 225dfec..27acde8c 100644
--- a/mojo/public/cpp/bindings/lib/control_message_handler.h
+++ b/mojo/public/cpp/bindings/lib/control_message_handler.h
@@ -7,8 +7,8 @@
 
 #include <stdint.h>
 
+#include "base/macros.h"
 #include "mojo/public/cpp/bindings/message.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace internal {
diff --git a/mojo/public/cpp/bindings/lib/control_message_proxy.cc b/mojo/public/cpp/bindings/lib/control_message_proxy.cc
index d450355..6208065 100644
--- a/mojo/public/cpp/bindings/lib/control_message_proxy.cc
+++ b/mojo/public/cpp/bindings/lib/control_message_proxy.cc
@@ -8,9 +8,9 @@
 #include <stdint.h>
 #include <utility>
 
+#include "base/macros.h"
 #include "mojo/public/cpp/bindings/lib/message_builder.h"
 #include "mojo/public/cpp/bindings/message.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
 
 namespace mojo {
diff --git a/mojo/public/cpp/bindings/lib/control_message_proxy.h b/mojo/public/cpp/bindings/lib/control_message_proxy.h
index 57b871e..33aaf82a9 100644
--- a/mojo/public/cpp/bindings/lib/control_message_proxy.h
+++ b/mojo/public/cpp/bindings/lib/control_message_proxy.h
@@ -7,8 +7,8 @@
 
 #include <stdint.h>
 
+#include "base/macros.h"
 #include "mojo/public/cpp/bindings/callback.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/public/cpp/bindings/lib/filter_chain.h b/mojo/public/cpp/bindings/lib/filter_chain.h
index 99e8e73..689a7fa 100644
--- a/mojo/public/cpp/bindings/lib/filter_chain.h
+++ b/mojo/public/cpp/bindings/lib/filter_chain.h
@@ -7,9 +7,9 @@
 
 #include <vector>
 
+#include "base/move.h"
 #include "mojo/public/cpp/bindings/message.h"
 #include "mojo/public/cpp/bindings/message_filter.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace internal {
diff --git a/mojo/public/cpp/system/macros.h b/mojo/public/cpp/bindings/lib/macros.h
similarity index 75%
rename from mojo/public/cpp/system/macros.h
rename to mojo/public/cpp/bindings/lib/macros.h
index 931c978..62f4292 100644
--- a/mojo/public/cpp/system/macros.h
+++ b/mojo/public/cpp/bindings/lib/macros.h
@@ -2,16 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Define a set of C++ specific macros.
-// Mojo C++ API users can assume that mojo/public/cpp/system/macros.h
-// includes mojo/public/c/system/macros.h.
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MACROS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MACROS_H_
 
-#ifndef MOJO_PUBLIC_CPP_SYSTEM_MACROS_H_
-#define MOJO_PUBLIC_CPP_SYSTEM_MACROS_H_
-
-#include <stddef.h>
-
-#include "mojo/public/c/system/macros.h"  // Symbols exposed.
+// This file defines macros that are only used by generated bindings.
 
 // The C++ standard requires that static const members have an out-of-class
 // definition (in a single compilation unit), but MSVC chokes on this (when
@@ -36,4 +30,4 @@
 #define MOJO_STATIC_CONST_MEMBER_DEFINITION
 #endif
 
-#endif  // MOJO_PUBLIC_CPP_SYSTEM_MACROS_H_
+#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_MACROS_H_
diff --git a/mojo/public/cpp/bindings/lib/shared_data.h b/mojo/public/cpp/bindings/lib/shared_data.h
index 0afd892..8e93300b 100644
--- a/mojo/public/cpp/bindings/lib/shared_data.h
+++ b/mojo/public/cpp/bindings/lib/shared_data.h
@@ -8,7 +8,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace internal {
diff --git a/mojo/public/cpp/bindings/lib/validate_params.h b/mojo/public/cpp/bindings/lib/validate_params.h
index 4f4735a6..78c0589 100644
--- a/mojo/public/cpp/bindings/lib/validate_params.h
+++ b/mojo/public/cpp/bindings/lib/validate_params.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#include "mojo/public/cpp/system/macros.h"
+#include "base/macros.h"
 
 namespace mojo {
 namespace internal {
diff --git a/mojo/public/cpp/bindings/lib/validation_errors.h b/mojo/public/cpp/bindings/lib/validation_errors.h
index 1fcd335..bdace6c2 100644
--- a/mojo/public/cpp/bindings/lib/validation_errors.h
+++ b/mojo/public/cpp/bindings/lib/validation_errors.h
@@ -6,8 +6,8 @@
 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
 
 #include "base/logging.h"
+#include "base/macros.h"
 #include "mojo/public/cpp/bindings/callback.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace internal {
diff --git a/mojo/public/cpp/bindings/message_filter.h b/mojo/public/cpp/bindings/message_filter.h
index 8e10f6b..638c53bc8 100644
--- a/mojo/public/cpp/bindings/message_filter.h
+++ b/mojo/public/cpp/bindings/message_filter.h
@@ -6,7 +6,6 @@
 #define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_FILTER_H_
 
 #include "mojo/public/cpp/bindings/message.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/public/cpp/bindings/struct_ptr.h b/mojo/public/cpp/bindings/struct_ptr.h
index 3e907e0d..e3b072d 100644
--- a/mojo/public/cpp/bindings/struct_ptr.h
+++ b/mojo/public/cpp/bindings/struct_ptr.h
@@ -8,8 +8,8 @@
 #include <new>
 
 #include "base/logging.h"
+#include "base/move.h"
 #include "mojo/public/cpp/bindings/type_converter.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 namespace internal {
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn
index fb058ce..c689fe31 100644
--- a/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -21,6 +21,7 @@
     "equals_unittest.cc",
     "handle_passing_unittest.cc",
     "interface_ptr_unittest.cc",
+    "macros_unittest.cc",
     "map_unittest.cc",
     "message_queue.cc",
     "message_queue.h",
@@ -57,7 +58,6 @@
     "//mojo/public/cpp/bindings:callback",
     "//mojo/public/cpp/system",
     "//mojo/public/cpp/test_support:test_utils",
-    "//mojo/public/cpp/utility",
     "//mojo/public/interfaces/bindings/tests:test_associated_interfaces",
     "//mojo/public/interfaces/bindings/tests:test_interfaces",
     "//mojo/public/interfaces/bindings/tests:test_interfaces_blink",
@@ -84,7 +84,6 @@
     "//mojo/public/cpp/bindings:callback",
     "//mojo/public/cpp/system",
     "//mojo/public/cpp/test_support:test_utils",
-    "//mojo/public/cpp/utility",
     "//mojo/public/interfaces/bindings/tests:test_interfaces",
     "//testing/gtest",
   ]
diff --git a/mojo/public/cpp/bindings/tests/binding_unittest.cc b/mojo/public/cpp/bindings/tests/binding_unittest.cc
index 6e8e578..15b899d 100644
--- a/mojo/public/cpp/bindings/tests/binding_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/binding_unittest.cc
@@ -10,11 +10,11 @@
 #include <stdint.h>
 #include <utility>
 
+#include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc
index a57459d5..04e6bc981 100644
--- a/mojo/public/cpp/bindings/tests/connector_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/connector_unittest.cc
@@ -14,7 +14,6 @@
 #include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/lib/message_builder.h"
 #include "mojo/public/cpp/bindings/tests/message_queue.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/public/cpp/bindings/tests/container_test_util.h b/mojo/public/cpp/bindings/tests/container_test_util.h
index ff46b8f..b2038ba 100644
--- a/mojo/public/cpp/bindings/tests/container_test_util.h
+++ b/mojo/public/cpp/bindings/tests/container_test_util.h
@@ -8,7 +8,6 @@
 #include <stddef.h>
 
 #include "base/move.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/public/cpp/system/tests/macros_unittest.cc b/mojo/public/cpp/bindings/tests/macros_unittest.cc
similarity index 97%
rename from mojo/public/cpp/system/tests/macros_unittest.cc
rename to mojo/public/cpp/bindings/tests/macros_unittest.cc
index 30d7c844..73d6a80 100644
--- a/mojo/public/cpp/system/tests/macros_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/macros_unittest.cc
@@ -10,7 +10,7 @@
 // TODO(vtl): Fix no-compile tests (which are all disabled; crbug.com/105388)
 // and write some "negative" tests.
 
-#include "mojo/public/cpp/system/macros.h"
+#include "mojo/public/cpp/bindings/lib/macros.h"
 
 #include <assert.h>
 #include <stdint.h>
diff --git a/mojo/public/cpp/bindings/tests/router_unittest.cc b/mojo/public/cpp/bindings/tests/router_unittest.cc
index 1f7160e..804e497 100644
--- a/mojo/public/cpp/bindings/tests/router_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/router_unittest.cc
@@ -11,7 +11,6 @@
 #include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/tests/message_queue.h"
 #include "mojo/public/cpp/bindings/tests/router_test_util.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index 252a31a6..d234d66 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -175,7 +175,7 @@
     base::RunLoop run_loop;
     mojo::internal::ValidationErrorObserverForTesting observer(
         run_loop.QuitClosure());
-    mojo_ignore_result(test_message_receiver->Accept(&message));
+    ignore_result(test_message_receiver->Accept(&message));
     if (expected != "PASS")  // Observer only gets called on errors.
       run_loop.Run();
     if (observer.last_error() == mojo::internal::VALIDATION_ERROR_NONE)
diff --git a/mojo/public/cpp/bindings/tests/versioning_apptest.cc b/mojo/public/cpp/bindings/tests/versioning_apptest.cc
index e3d63e1..6eb57cf3 100644
--- a/mojo/public/cpp/bindings/tests/versioning_apptest.cc
+++ b/mojo/public/cpp/bindings/tests/versioning_apptest.cc
@@ -5,7 +5,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "mojo/public/cpp/system/macros.h"
+#include "base/macros.h"
 #include "mojo/public/interfaces/bindings/tests/versioning_test_client.mojom.h"
 #include "mojo/shell/public/cpp/application_test_base.h"
 #include "mojo/shell/public/cpp/connector.h"
diff --git a/mojo/public/cpp/bindings/tests/versioning_test_service.cc b/mojo/public/cpp/bindings/tests/versioning_test_service.cc
index bf3ca87..30296d00 100644
--- a/mojo/public/cpp/bindings/tests/versioning_test_service.cc
+++ b/mojo/public/cpp/bindings/tests/versioning_test_service.cc
@@ -7,9 +7,9 @@
 #include <map>
 #include <utility>
 
+#include "base/macros.h"
 #include "mojo/public/c/system/main.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/public/interfaces/bindings/tests/versioning_test_service.mojom.h"
 #include "mojo/shell/public/cpp/application_runner.h"
 #include "mojo/shell/public/cpp/interface_factory.h"
diff --git a/mojo/public/cpp/system/BUILD.gn b/mojo/public/cpp/system/BUILD.gn
index dc2d28c..0aef01d 100644
--- a/mojo/public/cpp/system/BUILD.gn
+++ b/mojo/public/cpp/system/BUILD.gn
@@ -9,7 +9,6 @@
     "data_pipe.h",
     "functions.h",
     "handle.h",
-    "macros.h",
     "message_pipe.h",
     "watcher.cc",
     "watcher.h",
diff --git a/mojo/public/cpp/system/buffer.h b/mojo/public/cpp/system/buffer.h
index 607aea1e1..a2d524e 100644
--- a/mojo/public/cpp/system/buffer.h
+++ b/mojo/public/cpp/system/buffer.h
@@ -18,7 +18,6 @@
 #include "base/logging.h"
 #include "mojo/public/c/system/buffer.h"
 #include "mojo/public/cpp/system/handle.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/public/cpp/system/core.h b/mojo/public/cpp/system/core.h
index b08a5a6a..f1d18d97 100644
--- a/mojo/public/cpp/system/core.h
+++ b/mojo/public/cpp/system/core.h
@@ -9,7 +9,6 @@
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/functions.h"
 #include "mojo/public/cpp/system/handle.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 
 #endif  // MOJO_PUBLIC_CPP_SYSTEM_CORE_H_
diff --git a/mojo/public/cpp/system/data_pipe.h b/mojo/public/cpp/system/data_pipe.h
index c5f9707..0dbc3c7 100644
--- a/mojo/public/cpp/system/data_pipe.h
+++ b/mojo/public/cpp/system/data_pipe.h
@@ -18,7 +18,6 @@
 #include "base/logging.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/cpp/system/handle.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/public/cpp/system/handle.h b/mojo/public/cpp/system/handle.h
index 4df86af..a0c162a8 100644
--- a/mojo/public/cpp/system/handle.h
+++ b/mojo/public/cpp/system/handle.h
@@ -14,7 +14,6 @@
 #include "base/move.h"
 #include "mojo/public/c/system/functions.h"
 #include "mojo/public/c/system/types.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/public/cpp/system/message_pipe.h b/mojo/public/cpp/system/message_pipe.h
index fab23e47..94818e8 100644
--- a/mojo/public/cpp/system/message_pipe.h
+++ b/mojo/public/cpp/system/message_pipe.h
@@ -18,7 +18,6 @@
 #include "base/logging.h"
 #include "mojo/public/c/system/message_pipe.h"
 #include "mojo/public/cpp/system/handle.h"
-#include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
diff --git a/mojo/public/cpp/system/tests/BUILD.gn b/mojo/public/cpp/system/tests/BUILD.gn
index b6664af..8f98b92 100644
--- a/mojo/public/cpp/system/tests/BUILD.gn
+++ b/mojo/public/cpp/system/tests/BUILD.gn
@@ -7,7 +7,6 @@
 
   sources = [
     "core_unittest.cc",
-    "macros_unittest.cc",
     "watcher_unittest.cc",
   ]
 
diff --git a/mojo/public/cpp/system/tests/core_unittest.cc b/mojo/public/cpp/system/tests/core_unittest.cc
index 927c554..7a52ab5 100644
--- a/mojo/public/cpp/system/tests/core_unittest.cc
+++ b/mojo/public/cpp/system/tests/core_unittest.cc
@@ -13,7 +13,6 @@
 #include <map>
 #include <utility>
 
-#include "mojo/public/cpp/system/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
diff --git a/mojo/public/cpp/utility/BUILD.gn b/mojo/public/cpp/utility/BUILD.gn
deleted file mode 100644
index c95efac..0000000
--- a/mojo/public/cpp/utility/BUILD.gn
+++ /dev/null
@@ -1,33 +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.
-
-source_set("utility") {
-  sources = [
-    "lib/mutex.cc",
-    "lib/run_loop.cc",
-    "lib/thread.cc",
-    "lib/thread_local.h",
-    "lib/thread_local_posix.cc",
-    "lib/thread_local_win.cc",
-    "mutex.h",
-    "run_loop.h",
-    "run_loop_handler.h",
-    "thread.h",
-  ]
-
-  deps = [
-    "//mojo/public/cpp/bindings:callback",
-    "//mojo/public/cpp/system",
-  ]
-
-  if (is_win) {
-    # See crbug.com/342893:
-    sources -= [
-      "lib/mutex.cc",
-      "lib/thread.cc",
-      "mutex.h",
-      "thread.h",
-    ]
-  }
-}
diff --git a/mojo/public/cpp/utility/lib/mutex.cc b/mojo/public/cpp/utility/lib/mutex.cc
deleted file mode 100644
index 23370e1..0000000
--- a/mojo/public/cpp/utility/lib/mutex.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/mutex.h"
-
-#include <assert.h>
-#include <errno.h>
-
-namespace mojo {
-
-// Release builds have inlined (non-error-checking) definitions in the header.
-#if !defined(NDEBUG)
-Mutex::Mutex() {
-  pthread_mutexattr_t mutexattr;
-  int rv = pthread_mutexattr_init(&mutexattr);
-  assert(rv == 0);
-  rv = pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
-  assert(rv == 0);
-  rv = pthread_mutex_init(&mutex_, &mutexattr);
-  assert(rv == 0);
-  rv = pthread_mutexattr_destroy(&mutexattr);
-  assert(rv == 0);
-}
-
-Mutex::~Mutex() {
-  int rv = pthread_mutex_destroy(&mutex_);
-  assert(rv == 0);
-}
-
-void Mutex::Lock() {
-  int rv = pthread_mutex_lock(&mutex_);
-  assert(rv == 0);
-}
-
-void Mutex::Unlock() {
-  int rv = pthread_mutex_unlock(&mutex_);
-  assert(rv == 0);
-}
-
-bool Mutex::TryLock() {
-  int rv = pthread_mutex_trylock(&mutex_);
-  assert(rv == 0 || rv == EBUSY);
-  return rv == 0;
-}
-
-void Mutex::AssertHeld() {
-  assert(pthread_mutex_lock(&mutex_) == EDEADLK);
-}
-#endif  // !defined(NDEBUG)
-
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/lib/run_loop.cc b/mojo/public/cpp/utility/lib/run_loop.cc
deleted file mode 100644
index 8121afe..0000000
--- a/mojo/public/cpp/utility/lib/run_loop.cc
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/run_loop.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <vector>
-
-#include "mojo/public/cpp/utility/lib/thread_local.h"
-#include "mojo/public/cpp/utility/run_loop_handler.h"
-
-namespace mojo {
-namespace {
-
-internal::ThreadLocalPointer<RunLoop> current_run_loop;
-
-const MojoTimeTicks kInvalidTimeTicks = static_cast<MojoTimeTicks>(0);
-
-}  // namespace
-
-// State needed for one iteration of WaitMany().
-struct RunLoop::WaitState {
-  WaitState() : deadline(MOJO_DEADLINE_INDEFINITE) {}
-
-  std::vector<Handle> handles;
-  std::vector<MojoHandleSignals> handle_signals;
-  MojoDeadline deadline;
-};
-
-struct RunLoop::RunState {
-  RunState() : should_quit(false) {}
-
-  bool should_quit;
-};
-
-RunLoop::RunLoop()
-    : run_state_(nullptr), next_handler_id_(0), next_sequence_number_(0) {
-  assert(!current());
-  current_run_loop.Set(this);
-}
-
-RunLoop::~RunLoop() {
-  assert(current() == this);
-  NotifyHandlers(MOJO_RESULT_ABORTED, IGNORE_DEADLINE);
-  current_run_loop.Set(nullptr);
-}
-
-// static
-void RunLoop::SetUp() {
-  current_run_loop.Allocate();
-}
-
-// static
-void RunLoop::TearDown() {
-  assert(!current());
-  current_run_loop.Free();
-}
-
-// static
-RunLoop* RunLoop::current() {
-  return current_run_loop.Get();
-}
-
-void RunLoop::AddHandler(RunLoopHandler* handler,
-                         const Handle& handle,
-                         MojoHandleSignals handle_signals,
-                         MojoDeadline deadline) {
-  assert(current() == this);
-  assert(handler);
-  assert(handle.is_valid());
-  // Assume it's an error if someone tries to reregister an existing handle.
-  assert(0u == handler_data_.count(handle));
-  HandlerData handler_data;
-  handler_data.handler = handler;
-  handler_data.handle_signals = handle_signals;
-  handler_data.deadline =
-      (deadline == MOJO_DEADLINE_INDEFINITE)
-          ? kInvalidTimeTicks
-          : GetTimeTicksNow() + static_cast<MojoTimeTicks>(deadline);
-  handler_data.id = next_handler_id_++;
-  handler_data_[handle] = handler_data;
-}
-
-void RunLoop::RemoveHandler(const Handle& handle) {
-  assert(current() == this);
-  handler_data_.erase(handle);
-}
-
-bool RunLoop::HasHandler(const Handle& handle) const {
-  return handler_data_.find(handle) != handler_data_.end();
-}
-
-void RunLoop::Run() {
-  RunInternal(UNTIL_EMPTY);
-}
-
-void RunLoop::RunUntilIdle() {
-  RunInternal(UNTIL_IDLE);
-}
-
-void RunLoop::RunInternal(RunMode run_mode) {
-  assert(current() == this);
-  RunState* old_state = run_state_;
-  RunState run_state;
-  run_state_ = &run_state;
-  for (;;) {
-    bool did_work = DoDelayedWork();
-    if (run_state.should_quit)
-      break;
-    did_work |= Wait(run_mode == UNTIL_IDLE);
-    if (run_state.should_quit)
-      break;
-    if (!did_work && run_mode == UNTIL_IDLE)
-      break;
-  }
-  run_state_ = old_state;
-}
-
-bool RunLoop::DoDelayedWork() {
-  MojoTimeTicks now = GetTimeTicksNow();
-  if (!delayed_tasks_.empty() && delayed_tasks_.top().run_time <= now) {
-    PendingTask task = delayed_tasks_.top();
-    delayed_tasks_.pop();
-    task.task.Run();
-    return true;
-  }
-  return false;
-}
-
-void RunLoop::Quit() {
-  assert(current() == this);
-  if (run_state_)
-    run_state_->should_quit = true;
-}
-
-void RunLoop::PostDelayedTask(const Closure& task, MojoTimeTicks delay) {
-  assert(current() == this);
-  MojoTimeTicks run_time = delay + GetTimeTicksNow();
-  delayed_tasks_.push(PendingTask(task, run_time, next_sequence_number_++));
-}
-
-bool RunLoop::Wait(bool non_blocking) {
-  const WaitState wait_state = GetWaitState(non_blocking);
-  if (wait_state.handles.empty()) {
-    if (delayed_tasks_.empty())
-      Quit();
-    return false;
-  }
-
-  const WaitManyResult wmr =
-      WaitMany(wait_state.handles, wait_state.handle_signals,
-               wait_state.deadline, nullptr);
-
-  if (!wmr.IsIndexValid()) {
-    assert(wmr.result == MOJO_RESULT_DEADLINE_EXCEEDED);
-    return NotifyHandlers(MOJO_RESULT_DEADLINE_EXCEEDED, CHECK_DEADLINE);
-  }
-
-  Handle handle = wait_state.handles[wmr.index];
-  assert(handler_data_.find(handle) != handler_data_.end());
-  RunLoopHandler* handler = handler_data_[handle].handler;
-
-  switch (wmr.result) {
-    case MOJO_RESULT_OK:
-      handler->OnHandleReady(handle);
-      return true;
-    case MOJO_RESULT_INVALID_ARGUMENT:
-    case MOJO_RESULT_FAILED_PRECONDITION:
-      // Remove the handle first, this way if OnHandleError() tries to remove
-      // the handle our iterator isn't invalidated.
-      handler_data_.erase(handle);
-      handler->OnHandleError(handle, wmr.result);
-      return true;
-    default:
-      assert(false);
-      return false;
-  }
-}
-
-bool RunLoop::NotifyHandlers(MojoResult error, CheckDeadline check) {
-  bool notified = false;
-
-  // Make a copy in case someone tries to add/remove new handlers as part of
-  // notifying.
-  const HandleToHandlerData cloned_handlers(handler_data_);
-  const MojoTimeTicks now(GetTimeTicksNow());
-  for (HandleToHandlerData::const_iterator i = cloned_handlers.begin();
-       i != cloned_handlers.end();
-       ++i) {
-    // Only check deadline exceeded if that's what we're notifying.
-    if (check == CHECK_DEADLINE &&
-        (i->second.deadline == kInvalidTimeTicks || i->second.deadline > now)) {
-      continue;
-    }
-
-    // Since we're iterating over a clone of the handlers, verify the handler
-    // is still valid before notifying.
-    if (handler_data_.find(i->first) == handler_data_.end() ||
-        handler_data_[i->first].id != i->second.id) {
-      continue;
-    }
-
-    RunLoopHandler* handler = i->second.handler;
-    handler_data_.erase(i->first);
-    handler->OnHandleError(i->first, error);
-    notified = true;
-  }
-
-  return notified;
-}
-
-RunLoop::WaitState RunLoop::GetWaitState(bool non_blocking) const {
-  WaitState wait_state;
-  MojoTimeTicks min_time = kInvalidTimeTicks;
-  for (HandleToHandlerData::const_iterator i = handler_data_.begin();
-       i != handler_data_.end();
-       ++i) {
-    wait_state.handles.push_back(i->first);
-    wait_state.handle_signals.push_back(i->second.handle_signals);
-    if (!non_blocking && i->second.deadline != kInvalidTimeTicks &&
-        (min_time == kInvalidTimeTicks || i->second.deadline < min_time)) {
-      min_time = i->second.deadline;
-    }
-  }
-  if (!delayed_tasks_.empty()) {
-    MojoTimeTicks delayed_min_time = delayed_tasks_.top().run_time;
-    if (min_time == kInvalidTimeTicks)
-      min_time = delayed_min_time;
-    else
-      min_time = std::min(min_time, delayed_min_time);
-  }
-  if (non_blocking) {
-    wait_state.deadline = static_cast<MojoDeadline>(0);
-  } else if (min_time != kInvalidTimeTicks) {
-    const MojoTimeTicks now = GetTimeTicksNow();
-    if (min_time < now)
-      wait_state.deadline = static_cast<MojoDeadline>(0);
-    else
-      wait_state.deadline = static_cast<MojoDeadline>(min_time - now);
-  }
-  return wait_state;
-}
-
-RunLoop::PendingTask::PendingTask(const Closure& task,
-                                  MojoTimeTicks run_time,
-                                  uint64_t sequence_number)
-    : task(task), run_time(run_time), sequence_number(sequence_number) {
-}
-
-RunLoop::PendingTask::PendingTask(const PendingTask& other) = default;
-
-RunLoop::PendingTask::~PendingTask() {
-}
-
-bool RunLoop::PendingTask::operator<(const RunLoop::PendingTask& other) const {
-  if (run_time != other.run_time) {
-    // std::priority_queue<> puts the least element at the end of the queue. We
-    // want the soonest eligible task to be at the head of the queue, so
-    // run_times further in the future are considered lesser.
-    return run_time > other.run_time;
-  }
-
-  return sequence_number > other.sequence_number;
-}
-
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/lib/thread.cc b/mojo/public/cpp/utility/lib/thread.cc
deleted file mode 100644
index d9c5e523..0000000
--- a/mojo/public/cpp/utility/lib/thread.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/thread.h"
-
-#include <assert.h>
-
-#include "base/compiler_specific.h"
-
-namespace mojo {
-
-Thread::Thread() : options_(), thread_(), started_(false), joined_(false) {
-}
-
-Thread::Thread(const Options& options)
-    : options_(options), thread_(), started_(false), joined_(false) {
-}
-
-Thread::~Thread() {
-  // If it was started, it must have been joined.
-  assert(!started_ || joined_);
-}
-
-void Thread::Start() {
-  assert(!started_);
-  assert(!joined_);
-
-  pthread_attr_t attr;
-  int rv = pthread_attr_init(&attr);
-  ALLOW_UNUSED_LOCAL(rv);
-  assert(rv == 0);
-
-  // Non-default stack size?
-  if (options_.stack_size() != 0) {
-    rv = pthread_attr_setstacksize(&attr, options_.stack_size());
-    assert(rv == 0);
-  }
-
-  started_ = true;
-  rv = pthread_create(&thread_, &attr, &ThreadRunTrampoline, this);
-  assert(rv == 0);
-
-  rv = pthread_attr_destroy(&attr);
-  assert(rv == 0);
-}
-
-void Thread::Join() {
-  // Must have been started but not yet joined.
-  assert(started_);
-  assert(!joined_);
-
-  joined_ = true;
-  int rv = pthread_join(thread_, nullptr);
-  ALLOW_UNUSED_LOCAL(rv);
-  assert(rv == 0);
-}
-
-// static
-void* Thread::ThreadRunTrampoline(void* arg) {
-  Thread* self = static_cast<Thread*>(arg);
-  self->Run();
-  return nullptr;
-}
-
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/lib/thread_local.h b/mojo/public/cpp/utility/lib/thread_local.h
deleted file mode 100644
index f5461eea..0000000
--- a/mojo/public/cpp/utility/lib/thread_local.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_
-#define MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_
-
-#ifndef _WIN32
-#include <pthread.h>
-#endif
-
-#include "mojo/public/cpp/system/macros.h"
-
-namespace mojo {
-namespace internal {
-
-// Helper functions that abstract the cross-platform APIs.
-struct ThreadLocalPlatform {
-#ifdef _WIN32
-  typedef unsigned long SlotType;
-#else
-  typedef pthread_key_t SlotType;
-#endif
-
-  static void AllocateSlot(SlotType* slot);
-  static void FreeSlot(SlotType slot);
-  static void* GetValueFromSlot(SlotType slot);
-  static void SetValueInSlot(SlotType slot, void* value);
-};
-
-// This class is intended to be statically allocated.
-template <typename P>
-class ThreadLocalPointer {
- public:
-  ThreadLocalPointer() : slot_() {}
-
-  void Allocate() { ThreadLocalPlatform::AllocateSlot(&slot_); }
-
-  void Free() { ThreadLocalPlatform::FreeSlot(slot_); }
-
-  P* Get() {
-    return static_cast<P*>(ThreadLocalPlatform::GetValueFromSlot(slot_));
-  }
-
-  void Set(P* value) { ThreadLocalPlatform::SetValueInSlot(slot_, value); }
-
- private:
-  ThreadLocalPlatform::SlotType slot_;
-};
-
-}  // namespace internal
-}  // namespace mojo
-
-#endif  // MOJO_PUBLIC_CPP_UTILITY_LIB_THREAD_LOCAL_H_
diff --git a/mojo/public/cpp/utility/lib/thread_local_posix.cc b/mojo/public/cpp/utility/lib/thread_local_posix.cc
deleted file mode 100644
index ea7343e..0000000
--- a/mojo/public/cpp/utility/lib/thread_local_posix.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/lib/thread_local.h"
-
-#include <assert.h>
-
-namespace mojo {
-namespace internal {
-
-// static
-void ThreadLocalPlatform::AllocateSlot(SlotType* slot) {
-  if (pthread_key_create(slot, nullptr) != 0) {
-    assert(false);
-  }
-}
-
-// static
-void ThreadLocalPlatform::FreeSlot(SlotType slot) {
-  if (pthread_key_delete(slot) != 0) {
-    assert(false);
-  }
-}
-
-// static
-void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) {
-  return pthread_getspecific(slot);
-}
-
-// static
-void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) {
-  if (pthread_setspecific(slot, value) != 0) {
-    assert(false);
-  }
-}
-
-}  // namespace internal
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/lib/thread_local_win.cc b/mojo/public/cpp/utility/lib/thread_local_win.cc
deleted file mode 100644
index b8239cb..0000000
--- a/mojo/public/cpp/utility/lib/thread_local_win.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/lib/thread_local.h"
-
-#include <windows.h>
-#include <assert.h>
-
-namespace mojo {
-namespace internal {
-
-// static
-void ThreadLocalPlatform::AllocateSlot(SlotType* slot) {
-  *slot = TlsAlloc();
-  assert(*slot != TLS_OUT_OF_INDEXES);
-}
-
-// static
-void ThreadLocalPlatform::FreeSlot(SlotType slot) {
-  if (!TlsFree(slot)) {
-    assert(false);
-  }
-}
-
-// static
-void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) {
-  return TlsGetValue(slot);
-}
-
-// static
-void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) {
-  if (!TlsSetValue(slot, value)) {
-    assert(false);
-  }
-}
-
-}  // namespace internal
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/mutex.h b/mojo/public/cpp/utility/mutex.h
deleted file mode 100644
index 0f9bee0..0000000
--- a/mojo/public/cpp/utility/mutex.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
-#define MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
-
-#ifdef _WIN32
-#error "Not implemented: See crbug.com/342893."
-#endif
-
-#include <pthread.h>
-
-#include "base/macros.h"
-#include "mojo/public/cpp/system/macros.h"
-
-namespace mojo {
-
-#ifdef NDEBUG
-// Note: Make a C++ constant for |PTHREAD_MUTEX_INITIALIZER|. (We can't directly
-// use the C macro in an initializer list, since it might expand to |{ ... }|.)
-namespace internal {
-const pthread_mutex_t kPthreadMutexInitializer = PTHREAD_MUTEX_INITIALIZER;
-}
-#endif
-
-class Mutex {
- public:
-#ifdef NDEBUG
-  Mutex() : mutex_(internal::kPthreadMutexInitializer) {}
-  ~Mutex() { pthread_mutex_destroy(&mutex_); }
-
-  void Lock() { pthread_mutex_lock(&mutex_); }
-  void Unlock() { pthread_mutex_unlock(&mutex_); }
-  bool TryLock() { return pthread_mutex_trylock(&mutex_) == 0; }
-
-  void AssertHeld() {}
-#else
-  Mutex();
-  ~Mutex();
-
-  void Lock();
-  void Unlock();
-  bool TryLock();
-
-  void AssertHeld();
-#endif
-
- private:
-  pthread_mutex_t mutex_;
-
-  DISALLOW_COPY_AND_ASSIGN(Mutex);
-};
-
-class MutexLock {
- public:
-  explicit MutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
-  ~MutexLock() { mutex_->Unlock(); }
-
- private:
-  Mutex* const mutex_;
-
-  DISALLOW_COPY_AND_ASSIGN(MutexLock);
-};
-
-// Catch bug where variable name is omitted (e.g., |MutexLock (&mu)|).
-#define MutexLock(x) static_assert(0, "MutexLock() missing variable name");
-
-}  // namespace mojo
-
-#endif  // MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
diff --git a/mojo/public/cpp/utility/run_loop.h b/mojo/public/cpp/utility/run_loop.h
deleted file mode 100644
index e46a8c68..0000000
--- a/mojo/public/cpp/utility/run_loop.h
+++ /dev/null
@@ -1,159 +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 MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
-#define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <queue>
-
-#include "mojo/public/cpp/bindings/callback.h"
-#include "mojo/public/cpp/system/core.h"
-
-namespace mojo {
-
-class RunLoopHandler;
-
-// Watches handles for signals and calls event handlers when they occur. Also
-// executes delayed tasks. This class should only be used by a single thread.
-class RunLoop {
- public:
-  RunLoop();
-  ~RunLoop();
-
-  // Sets up state needed for RunLoop. This must be invoked before creating a
-  // RunLoop.
-  static void SetUp();
-
-  // Cleans state created by Setup().
-  static void TearDown();
-
-  // Returns the RunLoop for the current thread. Returns null if not yet
-  // created.
-  static RunLoop* current();
-
-  // Registers a RunLoopHandler for the specified handle. It is an error to
-  // register more than one handler for a handle, and crashes the process.
-  //
-  // The handler's OnHandleReady() method is invoked after one of the signals in
-  // |handle_signals| occurs. Note that the handler remains registered until
-  // explicitly removed or an error occurs.
-  //
-  // The handler's OnHandleError() method is invoked if the deadline elapses, an
-  // error is detected, or the RunLoop is being destroyed. The handler is
-  // automatically unregistered before calling OnHandleError(), so it will not
-  // receive any further notifications.
-  void AddHandler(RunLoopHandler* handler,
-                  const Handle& handle,
-                  MojoHandleSignals handle_signals,
-                  MojoDeadline deadline);
-  void RemoveHandler(const Handle& handle);
-  bool HasHandler(const Handle& handle) const;
-
-  // Runs the loop servicing handles and tasks as they are ready. This returns
-  // when Quit() is invoked, or there are no more handles nor tasks.
-  void Run();
-
-  // Runs the loop servicing any handles and tasks that are ready. Does not wait
-  // for handles or tasks to become ready before returning. Returns early if
-  // Quit() is invoked.
-  void RunUntilIdle();
-
-  void Quit();
-
-  // Adds a task to be performed after delay has elapsed. Must be posted to the
-  // current thread's RunLoop.
-  void PostDelayedTask(const Closure& task, MojoTimeTicks delay);
-
- private:
-  struct RunState;
-  struct WaitState;
-
-  // Contains the data needed to track a request to AddHandler().
-  struct HandlerData {
-    HandlerData()
-        : handler(nullptr),
-          handle_signals(MOJO_HANDLE_SIGNAL_NONE),
-          deadline(0),
-          id(0) {}
-
-    RunLoopHandler* handler;
-    MojoHandleSignals handle_signals;
-    MojoTimeTicks deadline;
-    // See description of |RunLoop::next_handler_id_| for details.
-    int id;
-  };
-
-  typedef std::map<Handle, HandlerData> HandleToHandlerData;
-
-  // Used for NotifyHandlers to specify whether HandlerData's |deadline|
-  // should be checked prior to notifying.
-  enum CheckDeadline { CHECK_DEADLINE, IGNORE_DEADLINE };
-
-  // Mode of operation of the run loop.
-  enum RunMode { UNTIL_EMPTY, UNTIL_IDLE };
-
-  // Runs the loop servicing any handles and tasks that are ready. If
-  // |run_mode| is |UNTIL_IDLE|, does not wait for handles or tasks to become
-  // ready before returning. Returns early if Quit() is invoked.
-  void RunInternal(RunMode run_mode);
-
-  // Do one unit of delayed work, if eligible. Returns true is a task was run.
-  bool DoDelayedWork();
-
-  // Waits for a handle to be ready or until the next task must be run. Returns
-  // after servicing at least one handle (or there are no more handles) unless
-  // a task must be run or |non_blocking| is true, in which case it will also
-  // return if no task is registered and servicing at least one handle would
-  // require blocking. Returns true if a RunLoopHandler was notified.
-  bool Wait(bool non_blocking);
-
-  // Notifies handlers of |error|.  If |check| == CHECK_DEADLINE, this will
-  // only notify handlers whose deadline has expired and skips the rest.
-  // Returns true if a RunLoopHandler was notified.
-  bool NotifyHandlers(MojoResult error, CheckDeadline check);
-
-  // Returns the state needed to pass to WaitMany().
-  WaitState GetWaitState(bool non_blocking) const;
-
-  HandleToHandlerData handler_data_;
-
-  // If non-null we're running (inside Run()). Member references a value on the
-  // stack.
-  RunState* run_state_;
-
-  // An ever increasing value assigned to each HandlerData::id. Used to detect
-  // uniqueness while notifying. That is, while notifying expired timers we copy
-  // |handler_data_| and only notify handlers whose id match. If the id does not
-  // match it means the handler was removed then added so that we shouldn't
-  // notify it.
-  int next_handler_id_;
-
-  struct PendingTask {
-    PendingTask(const Closure& task,
-                MojoTimeTicks runtime,
-                uint64_t sequence_number);
-    PendingTask(const PendingTask& other);
-    ~PendingTask();
-
-    bool operator<(const PendingTask& other) const;
-
-    Closure task;
-    MojoTimeTicks run_time;
-    uint64_t sequence_number;
-  };
-  // An ever increasing sequence number attached to each pending task in order
-  // to preserve relative order of tasks posted at the 'same' time.
-  uint64_t next_sequence_number_;
-  typedef std::priority_queue<PendingTask> DelayedTaskQueue;
-  DelayedTaskQueue delayed_tasks_;
-
-  DISALLOW_COPY_AND_ASSIGN(RunLoop);
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_H_
diff --git a/mojo/public/cpp/utility/run_loop_handler.h b/mojo/public/cpp/utility/run_loop_handler.h
deleted file mode 100644
index 69838d5..0000000
--- a/mojo/public/cpp/utility/run_loop_handler.h
+++ /dev/null
@@ -1,25 +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 MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_
-#define MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_
-
-#include "mojo/public/cpp/system/core.h"
-
-namespace mojo {
-
-// Used by RunLoop to notify when a handle is either ready or has become
-// invalid.
-class RunLoopHandler {
- public:
-  virtual void OnHandleReady(const Handle& handle) = 0;
-  virtual void OnHandleError(const Handle& handle, MojoResult result) = 0;
-
- protected:
-  virtual ~RunLoopHandler() {}
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_PUBLIC_CPP_UTILITY_RUN_LOOP_HANDLER_H_
diff --git a/mojo/public/cpp/utility/tests/BUILD.gn b/mojo/public/cpp/utility/tests/BUILD.gn
deleted file mode 100644
index b5a92196..0000000
--- a/mojo/public/cpp/utility/tests/BUILD.gn
+++ /dev/null
@@ -1,26 +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.
-
-source_set("tests") {
-  testonly = true
-
-  sources = [
-    "run_loop_unittest.cc",
-  ]
-
-  deps = [
-    "//mojo/public/cpp/system",
-    "//mojo/public/cpp/test_support:test_utils",
-    "//mojo/public/cpp/utility",
-    "//testing/gtest",
-  ]
-
-  # crbug.com/342893
-  if (!is_win) {
-    sources += [
-      "mutex_unittest.cc",
-      "thread_unittest.cc",
-    ]
-  }
-}
diff --git a/mojo/public/cpp/utility/tests/mutex_unittest.cc b/mojo/public/cpp/utility/tests/mutex_unittest.cc
deleted file mode 100644
index 1604c8d..0000000
--- a/mojo/public/cpp/utility/tests/mutex_unittest.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/mutex.h"
-
-#include <stddef.h>
-#include <stdlib.h>  // For |rand()|.
-#include <time.h>  // For |nanosleep()| (defined by POSIX).
-
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "mojo/public/cpp/system/macros.h"
-#include "mojo/public/cpp/utility/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace {
-
-TEST(MutexTest, TrivialSingleThreaded) {
-  Mutex mutex;
-
-  mutex.Lock();
-  mutex.AssertHeld();
-  mutex.Unlock();
-
-  EXPECT_TRUE(mutex.TryLock());
-  mutex.AssertHeld();
-  mutex.Unlock();
-
-  {
-    MutexLock lock(&mutex);
-    mutex.AssertHeld();
-  }
-
-  EXPECT_TRUE(mutex.TryLock());
-  mutex.Unlock();
-}
-
-class Fiddler {
- public:
-  enum Type { kTypeLock, kTypeTry };
-  Fiddler(size_t times_to_lock,
-          Type type,
-          bool should_sleep,
-          Mutex* mutex,
-          int* shared_value)
-      : times_to_lock_(times_to_lock),
-        type_(type),
-        should_sleep_(should_sleep),
-        mutex_(mutex),
-        shared_value_(shared_value) {
-  }
-
-  ~Fiddler() {
-  }
-
-  void Fiddle() {
-    for (size_t i = 0; i < times_to_lock_;) {
-      switch (type_) {
-        case kTypeLock: {
-          mutex_->Lock();
-          int old_shared_value = *shared_value_;
-          if (should_sleep_)
-            SleepALittle();
-          *shared_value_ = old_shared_value + 1;
-          mutex_->Unlock();
-          i++;
-          break;
-        }
-        case kTypeTry:
-          if (mutex_->TryLock()) {
-            int old_shared_value = *shared_value_;
-            if (should_sleep_)
-              SleepALittle();
-            *shared_value_ = old_shared_value + 1;
-            mutex_->Unlock();
-            i++;
-          } else {
-            SleepALittle();  // Don't spin.
-          }
-          break;
-      }
-    }
-  }
-
- private:
-  static void SleepALittle() {
-    static const long kNanosPerMilli = 1000000;
-    struct timespec req = {
-      0,  // Seconds.
-      (rand() % 10) * kNanosPerMilli // Nanoseconds.
-    };
-    int rv = nanosleep(&req, nullptr);
-    ALLOW_UNUSED_LOCAL(rv);
-    assert(rv == 0);
-  }
-
-  const size_t times_to_lock_;
-  const Type type_;
-  const bool should_sleep_;
-  Mutex* const mutex_;
-  int* const shared_value_;
-
-  DISALLOW_COPY_AND_ASSIGN(Fiddler);
-};
-
-class FiddlerThread : public Thread {
- public:
-  // Takes ownership of |fiddler|.
-  FiddlerThread(Fiddler* fiddler)
-      : fiddler_(fiddler) {
-  }
-
-  ~FiddlerThread() override { delete fiddler_; }
-
-  void Run() override { fiddler_->Fiddle(); }
-
- private:
-  Fiddler* const fiddler_;
-
-  DISALLOW_COPY_AND_ASSIGN(FiddlerThread);
-};
-
-// This does a stress test (that also checks exclusion).
-TEST(MutexTest, ThreadedStress) {
-  static const size_t kNumThreads = 20;
-  static const int kTimesToLockEach = 20;
-  assert(kNumThreads % 4 == 0);
-
-  Mutex mutex;
-  int shared_value = 0;
-
-  std::vector<FiddlerThread*> fiddler_threads;
-
-  for (size_t i = 0; i < kNumThreads; i += 4) {
-    fiddler_threads.push_back(new FiddlerThread(new Fiddler(
-        kTimesToLockEach, Fiddler::kTypeLock, false, &mutex, &shared_value)));
-    fiddler_threads.push_back(new FiddlerThread(new Fiddler(
-        kTimesToLockEach, Fiddler::kTypeTry, false, &mutex, &shared_value)));
-    fiddler_threads.push_back(new FiddlerThread(new Fiddler(
-        kTimesToLockEach, Fiddler::kTypeLock, true, &mutex, &shared_value)));
-    fiddler_threads.push_back(new FiddlerThread(new Fiddler(
-        kTimesToLockEach, Fiddler::kTypeTry, true, &mutex, &shared_value)));
-  }
-
-  for (size_t i = 0; i < kNumThreads; i++)
-    fiddler_threads[i]->Start();
-
-  // Do some fiddling ourselves.
-  Fiddler(kTimesToLockEach, Fiddler::kTypeLock, true, &mutex, &shared_value)
-      .Fiddle();
-
-  // Join.
-  for (size_t i = 0; i < kNumThreads; i++)
-    fiddler_threads[i]->Join();
-
-  EXPECT_EQ(static_cast<int>(kNumThreads + 1) * kTimesToLockEach, shared_value);
-
-  // Delete.
-  for (size_t i = 0; i < kNumThreads; i++)
-    delete fiddler_threads[i];
-  fiddler_threads.clear();
-}
-
-class TryThread : public Thread {
- public:
-  explicit TryThread(Mutex* mutex) : mutex_(mutex), try_lock_succeeded_() {}
-  ~TryThread() override {}
-
-  void Run() override {
-    try_lock_succeeded_ = mutex_->TryLock();
-    if (try_lock_succeeded_)
-      mutex_->Unlock();
-  }
-
-  bool try_lock_succeeded() const { return try_lock_succeeded_; }
-
- private:
-  Mutex* const mutex_;
-  bool try_lock_succeeded_;
-
-  DISALLOW_COPY_AND_ASSIGN(TryThread);
-};
-
-TEST(MutexTest, TryLock) {
-  Mutex mutex;
-
-  // |TryLock()| should succeed -- we don't have the lock.
-  {
-    TryThread thread(&mutex);
-    thread.Start();
-    thread.Join();
-    EXPECT_TRUE(thread.try_lock_succeeded());
-  }
-
-  // Take the lock.
-  ASSERT_TRUE(mutex.TryLock());
-
-  // Now it should fail.
-  {
-    TryThread thread(&mutex);
-    thread.Start();
-    thread.Join();
-    EXPECT_FALSE(thread.try_lock_succeeded());
-  }
-
-  // Release the lock.
-  mutex.Unlock();
-
-  // It should succeed again.
-  {
-    TryThread thread(&mutex);
-    thread.Start();
-    thread.Join();
-    EXPECT_TRUE(thread.try_lock_succeeded());
-  }
-}
-
-
-// Tests of assertions for Debug builds.
-#if !defined(NDEBUG)
-// Test |AssertHeld()| (which is an actual user API).
-TEST(MutexTest, DebugAssertHeldFailure) {
-  Mutex mutex;
-  EXPECT_DEATH_IF_SUPPORTED(mutex.AssertHeld(), "");
-}
-
-// Test other consistency checks.
-TEST(MutexTest, DebugAssertionFailures) {
-  // Unlock without lock held.
-  EXPECT_DEATH_IF_SUPPORTED({
-    Mutex mutex;
-    mutex.Unlock();
-  }, "");
-
-  // Lock with lock held (on same thread).
-  EXPECT_DEATH_IF_SUPPORTED({
-    Mutex mutex;
-    mutex.Lock();
-    mutex.Lock();
-  }, "");
-
-  // Try lock with lock held.
-  EXPECT_DEATH_IF_SUPPORTED({
-    Mutex mutex;
-    mutex.Lock();
-    mutex.TryLock();
-  }, "");
-
-  // Destroy lock with lock held.
-  EXPECT_DEATH_IF_SUPPORTED({
-    Mutex mutex;
-    mutex.Lock();
-  }, "");
-}
-#endif  // !defined(NDEBUG)
-
-}  // namespace
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/tests/run_loop_unittest.cc b/mojo/public/cpp/utility/tests/run_loop_unittest.cc
deleted file mode 100644
index a49fd77..0000000
--- a/mojo/public/cpp/utility/tests/run_loop_unittest.cc
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/run_loop.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-
-#include "mojo/public/cpp/system/core.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "mojo/public/cpp/utility/run_loop_handler.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace {
-
-class TestRunLoopHandler : public RunLoopHandler {
- public:
-  TestRunLoopHandler()
-      : ready_count_(0),
-        error_count_(0),
-        last_error_result_(MOJO_RESULT_OK) {
-  }
-  ~TestRunLoopHandler() override {}
-
-  void clear_ready_count() { ready_count_ = 0; }
-  int ready_count() const { return ready_count_; }
-
-  void clear_error_count() { error_count_ = 0; }
-  int error_count() const { return error_count_; }
-
-  MojoResult last_error_result() const { return last_error_result_; }
-
-  // RunLoopHandler:
-  void OnHandleReady(const Handle& handle) override { ready_count_++; }
-  void OnHandleError(const Handle& handle, MojoResult result) override {
-    error_count_++;
-    last_error_result_ = result;
-  }
-
- private:
-  int ready_count_;
-  int error_count_;
-  MojoResult last_error_result_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestRunLoopHandler);
-};
-
-class RunLoopTest : public testing::Test {
- public:
-  RunLoopTest() {}
-
-  void SetUp() override {
-    Test::SetUp();
-    RunLoop::SetUp();
-  }
-  void TearDown() override {
-    RunLoop::TearDown();
-    Test::TearDown();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(RunLoopTest);
-};
-
-// Trivial test to verify Run() with no added handles returns.
-TEST_F(RunLoopTest, ExitsWithNoHandles) {
-  RunLoop run_loop;
-  run_loop.Run();
-}
-
-class RemoveOnReadyRunLoopHandler : public TestRunLoopHandler {
- public:
-  RemoveOnReadyRunLoopHandler() : run_loop_(nullptr) {}
-  ~RemoveOnReadyRunLoopHandler() override {}
-
-  void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
-
-  // RunLoopHandler:
-  void OnHandleReady(const Handle& handle) override {
-    run_loop_->RemoveHandler(handle);
-    TestRunLoopHandler::OnHandleReady(handle);
-  }
-
- private:
-  RunLoop* run_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(RemoveOnReadyRunLoopHandler);
-};
-
-// Verifies RunLoop quits when no more handles (handle is removed when ready).
-TEST_F(RunLoopTest, HandleReady) {
-  RemoveOnReadyRunLoopHandler handler;
-  MessagePipe test_pipe;
-  EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string()));
-
-  RunLoop run_loop;
-  handler.set_run_loop(&run_loop);
-  run_loop.AddHandler(&handler, test_pipe.handle0.get(),
-                      MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE);
-  run_loop.Run();
-  EXPECT_EQ(1, handler.ready_count());
-  EXPECT_EQ(0, handler.error_count());
-  EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get()));
-}
-
-class QuitOnReadyRunLoopHandler : public TestRunLoopHandler {
- public:
-  QuitOnReadyRunLoopHandler() : run_loop_(nullptr) {}
-  ~QuitOnReadyRunLoopHandler() override {}
-
-  void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
-
-  // RunLoopHandler:
-  void OnHandleReady(const Handle& handle) override {
-    run_loop_->Quit();
-    TestRunLoopHandler::OnHandleReady(handle);
-  }
-
- private:
-  RunLoop* run_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(QuitOnReadyRunLoopHandler);
-};
-
-// Verifies Quit() from OnHandleReady() quits the loop.
-TEST_F(RunLoopTest, QuitFromReady) {
-  QuitOnReadyRunLoopHandler handler;
-  MessagePipe test_pipe;
-  EXPECT_TRUE(test::WriteTextMessage(test_pipe.handle1.get(), std::string()));
-
-  RunLoop run_loop;
-  handler.set_run_loop(&run_loop);
-  run_loop.AddHandler(&handler, test_pipe.handle0.get(),
-                      MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE);
-  run_loop.Run();
-  EXPECT_EQ(1, handler.ready_count());
-  EXPECT_EQ(0, handler.error_count());
-  EXPECT_TRUE(run_loop.HasHandler(test_pipe.handle0.get()));
-}
-
-class QuitOnErrorRunLoopHandler : public TestRunLoopHandler {
- public:
-  QuitOnErrorRunLoopHandler() : run_loop_(nullptr) {}
-  ~QuitOnErrorRunLoopHandler() override {}
-
-  void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
-
-  // RunLoopHandler:
-  void OnHandleError(const Handle& handle, MojoResult result) override {
-    run_loop_->Quit();
-    TestRunLoopHandler::OnHandleError(handle, result);
-  }
-
- private:
-  RunLoop* run_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(QuitOnErrorRunLoopHandler);
-};
-
-// Verifies Quit() when the deadline is reached works.
-TEST_F(RunLoopTest, QuitWhenDeadlineExpired) {
-  QuitOnErrorRunLoopHandler handler;
-  MessagePipe test_pipe;
-  RunLoop run_loop;
-  handler.set_run_loop(&run_loop);
-  run_loop.AddHandler(&handler, test_pipe.handle0.get(),
-                      MOJO_HANDLE_SIGNAL_READABLE,
-                      static_cast<MojoDeadline>(10000));
-  run_loop.Run();
-  EXPECT_EQ(0, handler.ready_count());
-  EXPECT_EQ(1, handler.error_count());
-  EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, handler.last_error_result());
-  EXPECT_FALSE(run_loop.HasHandler(test_pipe.handle0.get()));
-}
-
-// Test that handlers are notified of loop destruction.
-TEST_F(RunLoopTest, Destruction) {
-  TestRunLoopHandler handler;
-  MessagePipe test_pipe;
-  {
-    RunLoop run_loop;
-    run_loop.AddHandler(&handler,
-                        test_pipe.handle0.get(),
-                        MOJO_HANDLE_SIGNAL_READABLE,
-                        MOJO_DEADLINE_INDEFINITE);
-  }
-  EXPECT_EQ(1, handler.error_count());
-  EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result());
-}
-
-class RemoveManyRunLoopHandler : public TestRunLoopHandler {
- public:
-  RemoveManyRunLoopHandler() : run_loop_(nullptr) {}
-  ~RemoveManyRunLoopHandler() override {}
-
-  void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
-  void add_handle(const Handle& handle) { handles_.push_back(handle); }
-
-  // RunLoopHandler:
-  void OnHandleError(const Handle& handle, MojoResult result) override {
-    for (size_t i = 0; i < handles_.size(); i++)
-      run_loop_->RemoveHandler(handles_[i]);
-    TestRunLoopHandler::OnHandleError(handle, result);
-  }
-
- private:
-  std::vector<Handle> handles_;
-  RunLoop* run_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(RemoveManyRunLoopHandler);
-};
-
-// Test that handlers are notified of loop destruction.
-TEST_F(RunLoopTest, MultipleHandleDestruction) {
-  RemoveManyRunLoopHandler odd_handler;
-  TestRunLoopHandler even_handler;
-  MessagePipe test_pipe1, test_pipe2, test_pipe3;
-  {
-    RunLoop run_loop;
-    odd_handler.set_run_loop(&run_loop);
-    odd_handler.add_handle(test_pipe1.handle0.get());
-    odd_handler.add_handle(test_pipe3.handle0.get());
-    run_loop.AddHandler(&odd_handler,
-                        test_pipe1.handle0.get(),
-                        MOJO_HANDLE_SIGNAL_READABLE,
-                        MOJO_DEADLINE_INDEFINITE);
-    run_loop.AddHandler(&even_handler,
-                        test_pipe2.handle0.get(),
-                        MOJO_HANDLE_SIGNAL_READABLE,
-                        MOJO_DEADLINE_INDEFINITE);
-    run_loop.AddHandler(&odd_handler,
-                        test_pipe3.handle0.get(),
-                        MOJO_HANDLE_SIGNAL_READABLE,
-                        MOJO_DEADLINE_INDEFINITE);
-  }
-  EXPECT_EQ(1, odd_handler.error_count());
-  EXPECT_EQ(1, even_handler.error_count());
-  EXPECT_EQ(MOJO_RESULT_ABORTED, odd_handler.last_error_result());
-  EXPECT_EQ(MOJO_RESULT_ABORTED, even_handler.last_error_result());
-}
-
-class AddHandlerOnErrorHandler : public TestRunLoopHandler {
- public:
-  AddHandlerOnErrorHandler() : run_loop_(nullptr) {}
-  ~AddHandlerOnErrorHandler() override {}
-
-  void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
-
-  // RunLoopHandler:
-  void OnHandleError(const Handle& handle, MojoResult result) override {
-    run_loop_->AddHandler(this, handle,
-                          MOJO_HANDLE_SIGNAL_READABLE,
-                          MOJO_DEADLINE_INDEFINITE);
-    TestRunLoopHandler::OnHandleError(handle, result);
-  }
-
- private:
-  RunLoop* run_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(AddHandlerOnErrorHandler);
-};
-
-TEST_F(RunLoopTest, AddHandlerOnError) {
-  AddHandlerOnErrorHandler handler;
-  MessagePipe test_pipe;
-  {
-    RunLoop run_loop;
-    handler.set_run_loop(&run_loop);
-    run_loop.AddHandler(&handler,
-                        test_pipe.handle0.get(),
-                        MOJO_HANDLE_SIGNAL_READABLE,
-                        MOJO_DEADLINE_INDEFINITE);
-  }
-  EXPECT_EQ(1, handler.error_count());
-  EXPECT_EQ(MOJO_RESULT_ABORTED, handler.last_error_result());
-}
-
-TEST_F(RunLoopTest, Current) {
-  EXPECT_TRUE(RunLoop::current() == nullptr);
-  {
-    RunLoop run_loop;
-    EXPECT_EQ(&run_loop, RunLoop::current());
-  }
-  EXPECT_TRUE(RunLoop::current() == nullptr);
-}
-
-class NestingRunLoopHandler : public TestRunLoopHandler {
- public:
-  static const size_t kDepthLimit;
-  static const char kSignalMagic;
-
-  NestingRunLoopHandler()
-      : run_loop_(nullptr),
-        pipe_(nullptr),
-        depth_(0),
-        reached_depth_limit_(false) {}
-
-  ~NestingRunLoopHandler() override {}
-
-  void set_run_loop(RunLoop* run_loop) { run_loop_ = run_loop; }
-  void set_pipe(MessagePipe* pipe) { pipe_ = pipe; }
-  bool reached_depth_limit() const { return reached_depth_limit_; }
-
-  // RunLoopHandler:
-  void OnHandleReady(const Handle& handle) override {
-    TestRunLoopHandler::OnHandleReady(handle);
-    EXPECT_EQ(handle.value(), pipe_->handle0.get().value());
-
-    ReadSignal();
-    size_t current_depth = ++depth_;
-    if (current_depth < kDepthLimit) {
-      WriteSignal();
-      run_loop_->Run();
-      if (current_depth == kDepthLimit - 1) {
-        // The topmost loop Quit()-ed, so its parent takes back the
-        // control without exeeding deadline.
-        EXPECT_EQ(error_count(), 0);
-      } else {
-        EXPECT_EQ(error_count(), 1);
-      }
-
-    } else {
-      EXPECT_EQ(current_depth, kDepthLimit);
-      reached_depth_limit_ = true;
-      run_loop_->Quit();
-    }
-    --depth_;
-  }
-
-  void WriteSignal() {
-    char write_byte = kSignalMagic;
-    MojoResult write_result =
-        WriteMessageRaw(pipe_->handle1.get(), &write_byte, 1, nullptr, 0,
-                        MOJO_WRITE_MESSAGE_FLAG_NONE);
-    EXPECT_EQ(write_result, MOJO_RESULT_OK);
-  }
-
-  void ReadSignal() {
-    char read_byte = 0;
-    uint32_t bytes_read = 1;
-    uint32_t handles_read = 0;
-    MojoResult read_result =
-        ReadMessageRaw(pipe_->handle0.get(), &read_byte, &bytes_read, nullptr,
-                       &handles_read, MOJO_READ_MESSAGE_FLAG_NONE);
-    EXPECT_EQ(read_result, MOJO_RESULT_OK);
-    EXPECT_EQ(read_byte, kSignalMagic);
-  }
-
- private:
-  RunLoop* run_loop_;
-  MessagePipe* pipe_;
-  size_t depth_;
-  bool reached_depth_limit_;
-
-  DISALLOW_COPY_AND_ASSIGN(NestingRunLoopHandler);
-};
-
-const size_t NestingRunLoopHandler::kDepthLimit = 10;
-const char NestingRunLoopHandler::kSignalMagic = 'X';
-
-TEST_F(RunLoopTest, NestedRun) {
-  NestingRunLoopHandler handler;
-  MessagePipe test_pipe;
-  RunLoop run_loop;
-  handler.set_run_loop(&run_loop);
-  handler.set_pipe(&test_pipe);
-  run_loop.AddHandler(&handler, test_pipe.handle0.get(),
-                      MOJO_HANDLE_SIGNAL_READABLE,
-                      static_cast<MojoDeadline>(10000));
-  handler.WriteSignal();
-  run_loop.Run();
-
-  EXPECT_TRUE(handler.reached_depth_limit());
-  // Got MOJO_RESULT_DEADLINE_EXCEEDED once then removed from the
-  // RunLoop's handler list.
-  EXPECT_EQ(handler.error_count(), 1);
-  EXPECT_EQ(handler.last_error_result(), MOJO_RESULT_DEADLINE_EXCEEDED);
-}
-
-struct Task {
-  Task(int num, std::vector<int>* sequence) : num(num), sequence(sequence) {}
-
-  void Run() const { sequence->push_back(num); }
-
-  int num;
-  std::vector<int>* sequence;
-};
-
-TEST_F(RunLoopTest, DelayedTaskOrder) {
-  std::vector<int> sequence;
-  RunLoop run_loop;
-  run_loop.PostDelayedTask(Closure(Task(1, &sequence)), 0);
-  run_loop.PostDelayedTask(Closure(Task(2, &sequence)), 0);
-  run_loop.PostDelayedTask(Closure(Task(3, &sequence)), 0);
-  run_loop.RunUntilIdle();
-
-  ASSERT_EQ(3u, sequence.size());
-  EXPECT_EQ(1, sequence[0]);
-  EXPECT_EQ(2, sequence[1]);
-  EXPECT_EQ(3, sequence[2]);
-}
-
-struct QuittingTask {
-  explicit QuittingTask(RunLoop* run_loop) : run_loop(run_loop) {}
-
-  void Run() const { run_loop->Quit(); }
-
-  RunLoop* run_loop;
-};
-
-TEST_F(RunLoopTest, QuitFromDelayedTask) {
-  TestRunLoopHandler handler;
-  MessagePipe test_pipe;
-  RunLoop run_loop;
-  run_loop.AddHandler(&handler,
-                      test_pipe.handle0.get(),
-                      MOJO_HANDLE_SIGNAL_READABLE,
-                      MOJO_DEADLINE_INDEFINITE);
-  run_loop.PostDelayedTask(Closure(QuittingTask(&run_loop)), 0);
-  run_loop.Run();
-}
-
-}  // namespace
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/tests/thread_unittest.cc b/mojo/public/cpp/utility/tests/thread_unittest.cc
deleted file mode 100644
index 54ba0f6..0000000
--- a/mojo/public/cpp/utility/tests/thread_unittest.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/public/cpp/utility/thread.h"
-
-#include <stddef.h>
-
-#include "mojo/public/cpp/system/macros.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace {
-
-class SetIntThread : public Thread {
- public:
-  SetIntThread(int* int_to_set, int value)
-      : int_to_set_(int_to_set),
-        value_(value) {
-  }
-  SetIntThread(const Options& options, int* int_to_set, int value)
-      : Thread(options),
-        int_to_set_(int_to_set),
-        value_(value) {
-  }
-
-  ~SetIntThread() override {}
-
-  void Run() override { *int_to_set_ = value_; }
-
- private:
-  int* const int_to_set_;
-  const int value_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetIntThread);
-};
-
-TEST(ThreadTest, CreateAndJoin) {
-  int value = 0;
-
-  // Not starting the thread should result in a no-op.
-  {
-    SetIntThread thread(&value, 1234567);
-  }
-  EXPECT_EQ(0, value);
-
-  // Start and join.
-  {
-    SetIntThread thread(&value, 12345678);
-    thread.Start();
-    thread.Join();
-    EXPECT_EQ(12345678, value);
-  }
-
-  // Ditto, with non-default (but reasonable) stack size.
-  {
-    Thread::Options options;
-    options.set_stack_size(1024 * 1024);  // 1 MB.
-    SetIntThread thread(options, &value, 12345678);
-    thread.Start();
-    thread.Join();
-    EXPECT_EQ(12345678, value);
-  }
-}
-
-// Tests of assertions for Debug builds.
-// Note: It's okay to create threads, despite gtest having to fork. (The threads
-// are in the child process.)
-#if !defined(NDEBUG)
-TEST(ThreadTest, DebugAssertionFailures) {
-  // Can only start once.
-  EXPECT_DEATH_IF_SUPPORTED({
-    int value = 0;
-    SetIntThread thread(&value, 1);
-    thread.Start();
-    thread.Start();
-  }, "");
-
-  // Must join (if you start).
-  EXPECT_DEATH_IF_SUPPORTED({
-    int value = 0;
-    SetIntThread thread(&value, 2);
-    thread.Start();
-  }, "");
-
-  // Can only join once.
-  EXPECT_DEATH_IF_SUPPORTED({
-    int value = 0;
-    SetIntThread thread(&value, 3);
-    thread.Start();
-    thread.Join();
-    thread.Join();
-  }, "");
-
-  // Stack too big (we're making certain assumptions here).
-  EXPECT_DEATH_IF_SUPPORTED({
-    int value = 0;
-    Thread::Options options;
-    options.set_stack_size(static_cast<size_t>(-1));
-    SetIntThread thread(options, &value, 4);
-    thread.Start();
-    thread.Join();
-  }, "");
-}
-#endif  // !defined(NDEBUG)
-
-}  // namespace
-}  // namespace mojo
diff --git a/mojo/public/cpp/utility/thread.h b/mojo/public/cpp/utility/thread.h
deleted file mode 100644
index c3fb372..0000000
--- a/mojo/public/cpp/utility/thread.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MOJO_PUBLIC_CPP_UTILITY_THREAD_H_
-#define MOJO_PUBLIC_CPP_UTILITY_THREAD_H_
-
-#ifdef _WIN32
-#error "Not implemented: See crbug.com/342893."
-#endif
-
-#include <pthread.h>
-#include <stddef.h>
-
-#include "base/macros.h"
-
-namespace mojo {
-
-// This class is thread-friendly, not thread-safe (e.g., you mustn't call
-// |Join()| from multiple threads and/or simultaneously try to destroy the
-// object).
-class Thread {
- public:
-  // TODO(vtl): Support non-joinable? priority?
-  class Options {
-   public:
-    Options() : stack_size_(0) {}
-
-    // A stack size of 0 means the default.
-    size_t stack_size() const { return stack_size_; }
-    void set_stack_size(size_t stack_size) { stack_size_ = stack_size; }
-
-   private:
-    size_t stack_size_;
-
-    // Copy and assign allowed.
-  };
-
-  // TODO(vtl): Add name or name prefix?
-  Thread();
-  explicit Thread(const Options& options);
-  virtual ~Thread();
-
-  void Start();
-  void Join();
-
-  virtual void Run() = 0;
-
- private:
-  static void* ThreadRunTrampoline(void* arg);
-
-  const Options options_;
-  pthread_t thread_;
-  bool started_;
-  bool joined_;
-
-  DISALLOW_COPY_AND_ASSIGN(Thread);
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_PUBLIC_CPP_UTILITY_THREAD_H_
diff --git a/mojo/public/mojo_application.gni b/mojo/public/mojo_application.gni
index e71dd29..7ceb2d5 100644
--- a/mojo/public/mojo_application.gni
+++ b/mojo/public/mojo_application.gni
@@ -25,6 +25,8 @@
     mojo_deps += invoker.deps
   }
 
+  mojo_data_deps = []
+
   if (defined(invoker.resources)) {
     copy_step_name = "${base_target_name}__copy_resources"
     copy(copy_step_name) {
@@ -37,7 +39,7 @@
       }
       deps = mojo_deps
     }
-    mojo_deps += [ ":$copy_step_name" ]
+    mojo_data_deps += [ ":$copy_step_name" ]
   }
 
   output = base_target_name + ".mojo"
@@ -85,6 +87,7 @@
     if (defined(invoker.data_deps)) {
       data_deps += invoker.data_deps
     }
+    data_deps += mojo_data_deps
 
     deps = [
       "//mojo/platform_handle:for_shared_library",
@@ -183,7 +186,7 @@
       base_target_name = invoker.output_name
     }
 
-    mojo_deps = []
+    mojo_data_deps = []
     if (defined(invoker.resources)) {
       copy_step_name = "${base_target_name}__copy_resources"
       copy(copy_step_name) {
@@ -198,7 +201,7 @@
           deps = invoker.deps
         }
       }
-      mojo_deps += [ ":$copy_step_name" ]
+      mojo_data_deps += [ ":$copy_step_name" ]
     }
 
     zip_action_name = "${target_name}_zip"
@@ -242,7 +245,7 @@
         "--line=#!mojo mojo:android_handler",
       ]
 
-      deps = mojo_deps
+      data_deps = mojo_data_deps
 
       public_deps = [
         ":$zip_action_name",
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
index b22f8530..8c9c0fb 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
@@ -28,6 +28,7 @@
 #include "base/trace_event/trace_event.h"
 #include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
 #include "mojo/public/cpp/bindings/lib/bounds_checker.h"
+#include "mojo/public/cpp/bindings/lib/macros.h"
 #include "mojo/public/cpp/bindings/lib/map_data_internal.h"
 #include "mojo/public/cpp/bindings/lib/message_builder.h"
 #include "mojo/public/cpp/bindings/lib/validate_params.h"
diff --git a/mojo/shell/public/cpp/application_test_base.h b/mojo/shell/public/cpp/application_test_base.h
index 4358c6fd..54d073ad 100644
--- a/mojo/shell/public/cpp/application_test_base.h
+++ b/mojo/shell/public/cpp/application_test_base.h
@@ -5,10 +5,10 @@
 #ifndef MOJO_SHELL_PUBLIC_CPP_APPLICATION_TEST_BASE_H_
 #define MOJO_SHELL_PUBLIC_CPP_APPLICATION_TEST_BASE_H_
 
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "mojo/public/cpp/bindings/array.h"
 #include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/shell/public/cpp/connector.h"
 #include "mojo/shell/public/cpp/shell_client.h"
 #include "mojo/shell/public/cpp/shell_connection.h"
diff --git a/mojo/shell/public/cpp/shell_client.h b/mojo/shell/public/cpp/shell_client.h
index 5f60316..d6fca12 100644
--- a/mojo/shell/public/cpp/shell_client.h
+++ b/mojo/shell/public/cpp/shell_client.h
@@ -8,7 +8,7 @@
 #include <stdint.h>
 #include <string>
 
-#include "mojo/public/cpp/system/macros.h"
+#include "base/macros.h"
 #include "mojo/shell/public/cpp/connection.h"
 #include "mojo/shell/public/cpp/identity.h"
 
diff --git a/mojo/shell/public/cpp/shell_test.h b/mojo/shell/public/cpp/shell_test.h
index c3ed59a..9157b676 100644
--- a/mojo/shell/public/cpp/shell_test.h
+++ b/mojo/shell/public/cpp/shell_test.h
@@ -5,8 +5,8 @@
 #ifndef MOJO_SHELL_PUBLIC_CPP_SHELL_TEST_H_
 #define MOJO_SHELL_PUBLIC_CPP_SHELL_TEST_H_
 
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
-#include "mojo/public/cpp/system/macros.h"
 #include "mojo/shell/public/cpp/connector.h"
 #include "mojo/shell/public/cpp/shell_client.h"
 #include "mojo/shell/public/cpp/shell_connection.h"
diff --git a/net/base/address_list_unittest.cc b/net/base/address_list_unittest.cc
index da1480a7..1e2fa42 100644
--- a/net/base/address_list_unittest.cc
+++ b/net/base/address_list_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/strings/string_util.h"
 #include "base/sys_byteorder.h"
+#include "net/base/ip_address.h"
 #include "net/base/sockaddr_storage.h"
 #include "net/base/sys_addrinfo.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -122,9 +123,9 @@
   // Construct a list of ip addresses.
   IPAddressList ip_list;
   for (size_t i = 0; i < arraysize(tests); ++i) {
-    IPAddressNumber ip_number;
-    ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number));
-    ip_list.push_back(ip_number);
+    IPAddress ip_address;
+    ASSERT_TRUE(ip_address.AssignFromIPLiteral(tests[i].ip_address));
+    ip_list.push_back(ip_address);
   }
 
   AddressList test_list = AddressList::CreateFromIPAddressList(ip_list,
diff --git a/net/base/ip_address.h b/net/base/ip_address.h
index 00038d07..93f594d 100644
--- a/net/base/ip_address.h
+++ b/net/base/ip_address.h
@@ -105,6 +105,8 @@
   // This class is copyable and assignable.
 };
 
+using IPAddressList = std::vector<IPAddress>;
+
 // TODO(Martijnc): These utility functions currently forward the calls to
 // the IPAddressNumber implementations. Move the implementations over when
 // the IPAddressNumber migration is complete. https://crbug.com/496258.
diff --git a/net/base/ip_address_number.h b/net/base/ip_address_number.h
index 4434fa05..80c524c 100644
--- a/net/base/ip_address_number.h
+++ b/net/base/ip_address_number.h
@@ -26,7 +26,6 @@
 // IPAddress instead and existing code should be switched over.
 // https://crbug.com/496258
 typedef std::vector<unsigned char> IPAddressNumber;
-typedef std::vector<IPAddressNumber> IPAddressList;
 
 static const size_t kIPv4AddressSize = 4;
 static const size_t kIPv6AddressSize = 16;
diff --git a/net/cert/cert_verify_proc_nss.cc b/net/cert/cert_verify_proc_nss.cc
index ca8e811..cad20b9 100644
--- a/net/cert/cert_verify_proc_nss.cc
+++ b/net/cert/cert_verify_proc_nss.cc
@@ -279,7 +279,7 @@
 //       that some EV sites would otherwise take the hit of an OCSP lookup for
 //       no reason.
 //   kCRLSetOk: otherwise.
-CRLSetResult CheckRevocationWithCRLSet(CERTCertList* cert_list,
+CRLSetResult CheckRevocationWithCRLSet(const CERTCertList* cert_list,
                                        CERTCertificate* root,
                                        CRLSet* crl_set) {
   std::vector<CERTCertificate*> certs;
@@ -352,6 +352,50 @@
   return kCRLSetOk;
 }
 
+// Arguments for CheckChainRevocationWithCRLSet that are curried within the
+// CERTChainVerifyCallback's isChainValidArg.
+struct CheckChainRevocationArgs {
+  // The CRLSet to evaluate against.
+  CRLSet* crl_set = nullptr;
+
+  // The next callback to invoke, if the CRLSet does not report any errors.
+  CERTChainVerifyCallback* next_callback = nullptr;
+
+  // Indicates that the application callback failure was due to a CRLSet
+  // revocation, rather than due to |next_callback| rejecting it. This is
+  // used to map the error back to the proper caller-visible error code.
+  bool was_revoked = false;
+};
+
+SECStatus CheckChainRevocationWithCRLSet(void* is_chain_valid_arg,
+                                         const CERTCertList* current_chain,
+                                         PRBool* chain_ok) {
+  CHECK(is_chain_valid_arg);
+
+  CheckChainRevocationArgs* args =
+      static_cast<CheckChainRevocationArgs*>(is_chain_valid_arg);
+
+  CRLSetResult crlset_result = kCRLSetUnknown;
+  if (args->crl_set) {
+    crlset_result =
+        CheckRevocationWithCRLSet(current_chain, nullptr, args->crl_set);
+  }
+
+  if (crlset_result == kCRLSetRevoked) {
+    args->was_revoked = true;
+    *chain_ok = PR_FALSE;
+    return SECSuccess;
+  }
+  args->was_revoked = false;
+
+  *chain_ok = PR_TRUE;
+  if (!args->next_callback || !args->next_callback->isChainValid)
+    return SECSuccess;
+
+  return (*args->next_callback->isChainValid)(
+      args->next_callback->isChainValidArg, current_chain, chain_ok);
+}
+
 // Forward declarations.
 SECStatus RetryPKIXVerifyCertWithWorkarounds(
     CERTCertificate* cert_handle, int num_policy_oids,
@@ -825,6 +869,22 @@
     verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
   }
 
+  // Setup a callback to call into CheckChainRevocationWithCRLSet with the
+  // current CRLSet. If the CRLSet revokes a given chain, |was_revoked|
+  // will be set to true.
+  // The same callback and args are used for every invocation of
+  // PKIXVerifyCert, as CheckChainRevocationWithCRLSet handles resetting
+  // |was_revoked| as necessary.
+  CheckChainRevocationArgs check_chain_revocation_args;
+  check_chain_revocation_args.crl_set = crl_set;
+  check_chain_revocation_args.next_callback = chain_verify_callback;
+
+  CERTChainVerifyCallback crlset_callback;
+  memset(&crlset_callback, 0, sizeof(crlset_callback));
+  crlset_callback.isChainValid = &CheckChainRevocationWithCRLSet;
+  crlset_callback.isChainValidArg =
+      static_cast<void*>(&check_chain_revocation_args);
+
   // Make sure that the cert is valid now.
   SECCertTimeValidity validity = CERT_CheckCertValidTimes(
       cert_handle, PR_Now(), PR_TRUE);
@@ -862,15 +922,9 @@
         CertificateListToCERTCertList(additional_trust_anchors));
   }
 
-  SECStatus status = PKIXVerifyCert(cert_handle,
-                                    check_revocation,
-                                    false,
-                                    cert_io_enabled,
-                                    NULL,
-                                    0,
-                                    trust_anchors.get(),
-                                    chain_verify_callback,
-                                    cvout);
+  SECStatus status =
+      PKIXVerifyCert(cert_handle, check_revocation, false, cert_io_enabled,
+                     NULL, 0, trust_anchors.get(), &crlset_callback, cvout);
 
   if (status == SECSuccess &&
       (flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) &&
@@ -880,15 +934,8 @@
     // NSS tests for that feature.
     scoped_cvout.Clear();
     verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
-    status = PKIXVerifyCert(cert_handle,
-                            true,
-                            true,
-                            cert_io_enabled,
-                            NULL,
-                            0,
-                            trust_anchors.get(),
-                            chain_verify_callback,
-                            cvout);
+    status = PKIXVerifyCert(cert_handle, true, true, cert_io_enabled, NULL, 0,
+                            trust_anchors.get(), &crlset_callback, cvout);
   }
 
   if (status == SECSuccess) {
@@ -910,13 +957,25 @@
 
   CRLSetResult crl_set_result = kCRLSetUnknown;
   if (crl_set) {
-    crl_set_result = CheckRevocationWithCRLSet(
-        cvout[cvout_cert_list_index].value.pointer.chain,
-        cvout[cvout_trust_anchor_index].value.pointer.cert,
-        crl_set);
-    if (crl_set_result == kCRLSetRevoked) {
+    if (status == SECSuccess) {
+      // Reverify the returned chain; NSS should have already called
+      // CheckChainRevocationWithCRLSet prior to returning, but given the
+      // edge cases (self-signed certs that are trusted; cached chains;
+      // unreadable code), this is more about defense in depth than
+      // functional necessity.
+      crl_set_result = CheckRevocationWithCRLSet(
+          cvout[cvout_cert_list_index].value.pointer.chain,
+          cvout[cvout_trust_anchor_index].value.pointer.cert, crl_set);
+      if (crl_set_result == kCRLSetRevoked) {
+        PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
+        status = SECFailure;
+      }
+    } else if (PORT_GetError() == SEC_ERROR_APPLICATION_CALLBACK_ERROR &&
+               check_chain_revocation_args.was_revoked) {
+      // If a CRLSet was supplied, and the error was an application callback
+      // error, then it was directed through the CRLSet code and that
+      // particular chain was revoked.
       PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
-      status = SECFailure;
     }
   }
 
@@ -949,14 +1008,8 @@
     if (check_revocation)
       verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
 
-    if (VerifyEV(cert_handle,
-                 flags,
-                 crl_set,
-                 check_revocation,
-                 metadata,
-                 ev_policy_oid,
-                 trust_anchors.get(),
-                 chain_verify_callback)) {
+    if (VerifyEV(cert_handle, flags, crl_set, check_revocation, metadata,
+                 ev_policy_oid, trust_anchors.get(), &crlset_callback)) {
       verify_result->cert_status |= CERT_STATUS_IS_EV;
     }
   }
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc
index be9868d3..be7f4d1 100644
--- a/net/cert/cert_verify_proc_unittest.cc
+++ b/net/cert/cert_verify_proc_unittest.cc
@@ -143,7 +143,7 @@
   // into all platforms, this is a temporary, test-only flag to centralize the
   // conditionals in tests.
   bool SupportsCRLSetsInPathBuilding() {
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(USE_NSS_CERTS)
     return true;
 #else
     return false;
@@ -1279,210 +1279,117 @@
   EXPECT_EQ(ERR_CERT_REVOKED, error);
 }
 
-// Tests that revocation by CRLSet functions properly with the certificate
-// immediately before the trust anchor is revoked by that trust anchor, but
-// another version to a different trust anchor exists.
+// Tests that CRLSets participate in path building functions, and that as
+// long as a valid path exists within the verification graph, verification
+// succeeds.
 //
-// The two possible paths are:
+// In this test, there are two roots (D and E), and three possible paths
+// to validate a leaf (A):
 // 1. A(B) -> B(C) -> C(D) -> D(D)
 // 2. A(B) -> B(C) -> C(E) -> E(E)
+// 3. A(B) -> B(F) -> F(E) -> E(E)
 //
-// In this test, C(E) is revoked by CRLSet. It is configured to be the more
-// preferable version compared to C(D), once revoked, it should be ignored.
-TEST_F(CertVerifyProcTest, CRLSetRevokedIntermediateSameName) {
+// Each permutation of revocation is tried:
+// 1. Revoking E by SPKI, so that only Path 1 is valid (as E is in Paths 2 & 3)
+// 2. Revoking C(D) and F(E) by serial, so that only Path 2 is valid.
+// 3. Revoking C by SPKI, so that only Path 3 is valid (as C is in Paths 1 & 2)
+TEST_F(CertVerifyProcTest, CRLSetDuringPathBuilding) {
   if (!SupportsCRLSetsInPathBuilding()) {
     LOG(INFO) << "Skipping this test on this platform.";
     return;
   }
 
-  const char* const kCertificatesToLoad[] = {
+  const char* const kPath1Files[] = {
       "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-D.pem",
-      "multi-root-D-by-D.pem", "multi-root-C-by-E.pem", "multi-root-E-by-E.pem",
-  };
-  CertificateList certs;
-  ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kCertificatesToLoad, &certs));
+      "multi-root-D-by-D.pem"};
+  const char* const kPath2Files[] = {
+      "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-E.pem",
+      "multi-root-E-by-E.pem"};
+  const char* const kPath3Files[] = {
+      "multi-root-A-by-B.pem", "multi-root-B-by-F.pem", "multi-root-F-by-E.pem",
+      "multi-root-E-by-E.pem"};
 
-  // Add D and E as trust anchors
-  ScopedTestRoot test_root_D(certs[3].get());  // D-by-D
-  ScopedTestRoot test_root_F(certs[5].get());  // E-by-E
+  CertificateList path_1_certs;
+  ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath1Files, &path_1_certs));
 
-  // Create a chain that sends A(B), B(C), C(E), C(D). The reason that
-  // both C(E) and C(D) are sent are to ensure both certificates are available
-  // for path building. The test
-  // CertVerifyProcTest.VerifyReturnChainFiltersUnrelatedCerts ensures this is
-  // safe to do.
+  CertificateList path_2_certs;
+  ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath2Files, &path_2_certs));
+
+  CertificateList path_3_certs;
+  ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath3Files, &path_3_certs));
+
+  // Add D and E as trust anchors.
+  ScopedTestRoot test_root_D(path_1_certs[3].get());  // D-by-D
+  ScopedTestRoot test_root_E(path_2_certs[3].get());  // E-by-E
+
+  // Create a chain that contains all the certificate paths possible.
+  // CertVerifyProcTest.VerifyReturnChainFiltersUnrelatedCerts already
+  // ensures that it's safe to send additional certificates as inputs, and
+  // that they're ignored if not necessary.
+  // This is to avoid relying on AIA or internal object caches when
+  // interacting with the underlying library.
   X509Certificate::OSCertHandles intermediates;
-  intermediates.push_back(certs[1]->os_cert_handle());  // B-by-C
-  intermediates.push_back(certs[4]->os_cert_handle());  // C-by-E
-  intermediates.push_back(certs[2]->os_cert_handle());  // C-by-D
+  intermediates.push_back(path_1_certs[1]->os_cert_handle());  // B-by-C
+  intermediates.push_back(path_1_certs[2]->os_cert_handle());  // C-by-D
+  intermediates.push_back(path_2_certs[2]->os_cert_handle());  // C-by-E
+  intermediates.push_back(path_3_certs[1]->os_cert_handle());  // B-by-F
+  intermediates.push_back(path_3_certs[2]->os_cert_handle());  // F-by-E
   scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
-      certs[0]->os_cert_handle(), intermediates);
+      path_1_certs[0]->os_cert_handle(), intermediates);
   ASSERT_TRUE(cert);
 
-  // Sanity check: Ensure that, without any revocation status, the to-be-revoked
-  // path is preferred.
-  int flags = 0;
-  CertVerifyResult verify_result;
-  int error = Verify(cert.get(), "127.0.0.1", flags, nullptr, empty_cert_list_,
-                     &verify_result);
-  ASSERT_EQ(OK, error);
-  ASSERT_EQ(0U, verify_result.cert_status);
-  ASSERT_TRUE(verify_result.verified_cert.get());
+  struct TestPermutations {
+    const char* crlset;
+    bool expect_valid;
+    scoped_refptr<X509Certificate> expected_intermediate;
+  } kTests[] = {
+      {"multi-root-crlset-D-and-E.raw", false, nullptr},
+      {"multi-root-crlset-E.raw", true, path_1_certs[2].get()},
+      {"multi-root-crlset-CD-and-FE.raw", true, path_2_certs[2].get()},
+      {"multi-root-crlset-C.raw", true, path_3_certs[2].get()},
+      {"multi-root-crlset-unrelated.raw", true, nullptr}};
 
-  // The expected path is A(B) -> B(C) -> C(E) -> E(E).
-  const X509Certificate::OSCertHandles& verified_intermediates =
-      verify_result.verified_cert->GetIntermediateCertificates();
-  ASSERT_EQ(3U, verified_intermediates.size());
-  scoped_refptr<X509Certificate> verified_root =
-      X509Certificate::CreateFromHandle(verified_intermediates[2],
-                                        X509Certificate::OSCertHandles());
-  ASSERT_TRUE(verified_root.get());
-  EXPECT_EQ("E Root CA", verified_root->subject().common_name);
+  for (const auto& testcase : kTests) {
+    SCOPED_TRACE(testcase.crlset);
+    scoped_refptr<CRLSet> crl_set;
+    std::string crl_set_bytes;
+    EXPECT_TRUE(base::ReadFileToString(
+        GetTestCertsDirectory().AppendASCII(testcase.crlset), &crl_set_bytes));
+    ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
 
-  // Load a CRLSet that blocks C-by-E.
-  scoped_refptr<CRLSet> crl_set;
-  std::string crl_set_bytes;
-  EXPECT_TRUE(base::ReadFileToString(
-      GetTestCertsDirectory().AppendASCII("multi-root-crlset-C-by-E.raw"),
-      &crl_set_bytes));
-  ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
+    int flags = 0;
+    CertVerifyResult verify_result;
+    int error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
+                       empty_cert_list_, &verify_result);
 
-  // Verify with the CRLSet. Because C-by-E is revoked, the expected path is
-  // A(B) -> B(C) -> C(D) -> D(D).
-  error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
-                 empty_cert_list_, &verify_result);
-  ASSERT_EQ(OK, error);
-  ASSERT_EQ(0U, verify_result.cert_status);
-  ASSERT_TRUE(verify_result.verified_cert.get());
+    if (!testcase.expect_valid) {
+      EXPECT_NE(OK, error);
+      EXPECT_NE(0U, verify_result.cert_status);
+      continue;
+    }
 
-  const X509Certificate::OSCertHandles& new_verified_intermediates =
-      verify_result.verified_cert->GetIntermediateCertificates();
-  ASSERT_EQ(3U, new_verified_intermediates.size());
-  verified_root = X509Certificate::CreateFromHandle(
-      new_verified_intermediates[2], X509Certificate::OSCertHandles());
-  ASSERT_TRUE(verified_root.get());
-  EXPECT_EQ("D Root CA", verified_root->subject().common_name);
+    ASSERT_EQ(OK, error);
+    ASSERT_EQ(0U, verify_result.cert_status);
+    ASSERT_TRUE(verify_result.verified_cert.get());
 
-  // Reverify without the CRLSet, to ensure that CRLSets do not persist between
-  // separate calls. As in the first verification, the expected path is
-  // A(B) -> B(C) -> C(E) -> E(E).
-  error = Verify(cert.get(), "127.0.0.1", flags, nullptr, empty_cert_list_,
-                 &verify_result);
-  ASSERT_EQ(OK, error);
-  ASSERT_EQ(0U, verify_result.cert_status);
-  ASSERT_TRUE(verify_result.verified_cert.get());
+    if (!testcase.expected_intermediate)
+      continue;
 
-  const X509Certificate::OSCertHandles& final_verified_intermediates =
-      verify_result.verified_cert->GetIntermediateCertificates();
-  ASSERT_EQ(3U, final_verified_intermediates.size());
-  verified_root = X509Certificate::CreateFromHandle(
-      final_verified_intermediates[2], X509Certificate::OSCertHandles());
-  ASSERT_TRUE(verified_root.get());
-  EXPECT_EQ("E Root CA", verified_root->subject().common_name);
-}
+    const X509Certificate::OSCertHandles& verified_intermediates =
+        verify_result.verified_cert->GetIntermediateCertificates();
+    ASSERT_EQ(3U, verified_intermediates.size());
 
-// Tests that revocation by CRLSet functions properly when an intermediate is
-// revoked by SPKI. In this case, path building should ignore all certificates
-// with that SPKI, and search for alternatively keyed versions.
-//
-// The two possible paths are:
-// 1. A(B) -> B(C) -> C(D) -> D(D)
-// 2. A(B) -> B(F) -> F(E) -> E(E)
-//
-// The path building algorithm needs to explore B(C) once it discovers that
-// F(E) is revoked, and that there are no valid paths with B(F).
-TEST_F(CertVerifyProcTest, CRLSetRevokedIntermediateCrossIntermediates) {
-  if (!SupportsCRLSetsInPathBuilding()) {
-    LOG(INFO) << "Skipping this test on this platform.";
-    return;
+    scoped_refptr<X509Certificate> intermediate =
+        X509Certificate::CreateFromHandle(verified_intermediates[1],
+                                          X509Certificate::OSCertHandles());
+    ASSERT_TRUE(intermediate);
+
+    EXPECT_TRUE(testcase.expected_intermediate->Equals(intermediate.get()))
+        << "Expected: " << testcase.expected_intermediate->subject().common_name
+        << " issued by " << testcase.expected_intermediate->issuer().common_name
+        << "; Got: " << intermediate->subject().common_name << " issued by "
+        << intermediate->issuer().common_name;
   }
-
-  const char* const kCertificatesToLoad[] = {
-      "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-D.pem",
-      "multi-root-D-by-D.pem", "multi-root-B-by-F.pem", "multi-root-F-by-E.pem",
-      "multi-root-E-by-E.pem",
-  };
-  CertificateList certs;
-  ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kCertificatesToLoad, &certs));
-
-  // Add D and E as trust anchors
-  ScopedTestRoot test_root_D(certs[3].get());  // D-by-D
-  ScopedTestRoot test_root_F(certs[6].get());  // E-by-E
-
-  // Create a chain that sends A(B), B(F), F(E), B(C), C(D). The reason that
-  // both B(C) and C(D) are sent are to ensure both certificates are available
-  // for path building. The test
-  // CertVerifyProcTest.VerifyReturnChainFiltersUnrelatedCerts ensures this is
-  // safe to do.
-  X509Certificate::OSCertHandles intermediates;
-  intermediates.push_back(certs[4]->os_cert_handle());  // B-by-F
-  intermediates.push_back(certs[5]->os_cert_handle());  // F-by-E
-  intermediates.push_back(certs[1]->os_cert_handle());  // B-by-C
-  intermediates.push_back(certs[2]->os_cert_handle());  // C-by-D
-  scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
-      certs[0]->os_cert_handle(), intermediates);
-  ASSERT_TRUE(cert);
-
-  // Sanity check: Ensure that, without any revocation status, the to-be-revoked
-  // path is preferred.
-  int flags = 0;
-  CertVerifyResult verify_result;
-  int error = Verify(cert.get(), "127.0.0.1", flags, nullptr, empty_cert_list_,
-                     &verify_result);
-  ASSERT_EQ(OK, error);
-  ASSERT_EQ(0U, verify_result.cert_status);
-  ASSERT_TRUE(verify_result.verified_cert.get());
-
-  // The expected path is A(B) -> B(F) -> F(E) -> E(E).
-  const X509Certificate::OSCertHandles& verified_intermediates =
-      verify_result.verified_cert->GetIntermediateCertificates();
-  ASSERT_EQ(3U, verified_intermediates.size());
-  scoped_refptr<X509Certificate> verified_root =
-      X509Certificate::CreateFromHandle(verified_intermediates[2],
-                                        X509Certificate::OSCertHandles());
-  ASSERT_TRUE(verified_root.get());
-  EXPECT_EQ("E Root CA", verified_root->subject().common_name);
-
-  // Load a CRLSet that blocks F.
-  scoped_refptr<CRLSet> crl_set;
-  std::string crl_set_bytes;
-  EXPECT_TRUE(base::ReadFileToString(
-      GetTestCertsDirectory().AppendASCII("multi-root-crlset-F.raw"),
-      &crl_set_bytes));
-  ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
-
-  // Verify with the CRLSet. Because F is revoked, the expected path is
-  // A(B) -> B(C) -> C(D) -> D(D).
-  error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
-                 empty_cert_list_, &verify_result);
-  ASSERT_EQ(OK, error);
-  ASSERT_EQ(0U, verify_result.cert_status);
-  ASSERT_TRUE(verify_result.verified_cert.get());
-
-  const X509Certificate::OSCertHandles& new_verified_intermediates =
-      verify_result.verified_cert->GetIntermediateCertificates();
-  ASSERT_EQ(3U, new_verified_intermediates.size());
-  verified_root = X509Certificate::CreateFromHandle(
-      new_verified_intermediates[2], X509Certificate::OSCertHandles());
-  ASSERT_TRUE(verified_root.get());
-  EXPECT_EQ("D Root CA", verified_root->subject().common_name);
-
-  // Reverify without the CRLSet, to ensure that CRLSets do not persist between
-  // separate calls. As in the first verification, the expected path is
-  // A(B) -> B(F) -> F(E) -> E(E).
-  error = Verify(cert.get(), "127.0.0.1", flags, nullptr, empty_cert_list_,
-                 &verify_result);
-  ASSERT_EQ(OK, error);
-  ASSERT_EQ(0U, verify_result.cert_status);
-  ASSERT_TRUE(verify_result.verified_cert.get());
-
-  const X509Certificate::OSCertHandles& final_verified_intermediates =
-      verify_result.verified_cert->GetIntermediateCertificates();
-  ASSERT_EQ(3U, final_verified_intermediates.size());
-  verified_root = X509Certificate::CreateFromHandle(
-      final_verified_intermediates[2], X509Certificate::OSCertHandles());
-  ASSERT_TRUE(verified_root.get());
-  EXPECT_EQ("E Root CA", verified_root->subject().common_name);
 }
 
 #endif
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index c73e74a..19a2d6ac7 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -162,13 +162,10 @@
 
 bool LRACookieSorter(const CookieMonster::CookieMap::iterator& it1,
                      const CookieMonster::CookieMap::iterator& it2) {
-  // Cookies accessed less recently should be deleted first.
   if (it1->second->LastAccessDate() != it2->second->LastAccessDate())
     return it1->second->LastAccessDate() < it2->second->LastAccessDate();
 
-  // In rare cases we might have two cookies with identical last access times.
-  // To preserve the stability of the sort, in these cases prefer to delete
-  // older cookies over newer ones.  CreationDate() is guaranteed to be unique.
+  // Ensure stability for == last access times by falling back to creation.
   return it1->second->CreationDate() < it2->second->CreationDate();
 }
 
@@ -250,29 +247,6 @@
   }
 }
 
-// Predicate to support PartitionCookieByPriority().
-struct CookiePriorityEqualsTo {
-  explicit CookiePriorityEqualsTo(CookiePriority priority)
-      : priority_(priority) {}
-
-  bool operator()(const CookieMonster::CookieMap::iterator it) const {
-    return it->second->Priority() == priority_;
-  }
-
-  const CookiePriority priority_;
-};
-
-// For a CookieItVector iterator range [|it_begin|, |it_end|),
-// moves all cookies with a given |priority| to the beginning of the list.
-// Returns: An iterator in [it_begin, it_end) to the first element with
-// priority != |priority|, or |it_end| if all have priority == |priority|.
-CookieMonster::CookieItVector::iterator PartitionCookieByPriority(
-    CookieMonster::CookieItVector::iterator it_begin,
-    CookieMonster::CookieItVector::iterator it_end,
-    CookiePriority priority) {
-  return std::partition(it_begin, it_end, CookiePriorityEqualsTo(priority));
-}
-
 bool LowerBoundAccessDateComparator(const CookieMonster::CookieMap::iterator it,
                                     const Time& access_date) {
   return it->second->LastAccessDate() < access_date;
@@ -1898,6 +1872,7 @@
     num_deleted +=
         GarbageCollectExpired(current, cookies_.equal_range(key), cookie_its);
 
+    // TODO(mkwst): Soften this.
     CookieItVector secure_cookie_its;
     if (enforce_strict_secure && cookie_its->size() > kDomainMaxCookies) {
       VLOG(kVlogGarbageCollection) << "Garbage collecting non-Secure cookies.";
@@ -1912,56 +1887,28 @@
           cookie_its->size() - (kDomainMaxCookies - kDomainPurgeCookies);
       DCHECK(purge_goal > kDomainPurgeCookies);
 
-      // Boundary iterators into |cookie_its| for different priorities.
-      CookieItVector::iterator it_bdd[4];
-      // Intialize |it_bdd| while sorting |cookie_its| by priorities.
-      // Schematic: [MLLHMHHLMM] => [LLL|MMMM|HHH], with 4 boundaries.
-      it_bdd[0] = cookie_its->begin();
-      it_bdd[3] = cookie_its->end();
-      it_bdd[1] =
-          PartitionCookieByPriority(it_bdd[0], it_bdd[3], COOKIE_PRIORITY_LOW);
-      it_bdd[2] = PartitionCookieByPriority(it_bdd[1], it_bdd[3],
-                                            COOKIE_PRIORITY_MEDIUM);
-      size_t quota[3] = {kDomainCookiesQuotaLow,
-                         kDomainCookiesQuotaMedium,
-                         kDomainCookiesQuotaHigh};
+      // Sort the cookies by access date, from least-recent to most-recent.
+      std::sort(cookie_its->begin(), cookie_its->end(), LRACookieSorter);
 
-      // Purge domain cookies in 3 rounds.
-      // Round 1: consider low-priority cookies only: evict least-recently
-      //   accessed, while protecting quota[0] of these from deletion.
-      // Round 2: consider {low, medium}-priority cookies, evict least-recently
-      //   accessed, while protecting quota[0] + quota[1].
-      // Round 3: consider all cookies, evict least-recently accessed.
-      size_t accumulated_quota = 0;
-      CookieItVector::iterator it_purge_begin = it_bdd[0];
-      for (int i = 0; i < 3 && purge_goal > 0; ++i) {
-        accumulated_quota += quota[i];
-
-        size_t num_considered = it_bdd[i + 1] - it_purge_begin;
-        if (num_considered <= accumulated_quota)
-          continue;
-
-        // Number of cookies that will be purged in this round.
-        size_t round_goal =
-            std::min(purge_goal, num_considered - accumulated_quota);
-        purge_goal -= round_goal;
-
-        SortLeastRecentlyAccessed(it_purge_begin, it_bdd[i + 1], round_goal);
-        // Cookies accessed on or after |safe_date| would have been safe from
-        // global purge, and we want to keep track of this.
-        CookieItVector::iterator it_purge_end = it_purge_begin + round_goal;
-        CookieItVector::iterator it_purge_middle =
-            LowerBoundAccessDate(it_purge_begin, it_purge_end, safe_date);
-        // Delete cookies accessed before |safe_date|.
-        num_deleted += GarbageCollectDeleteRange(
-            current, DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE, it_purge_begin,
-            it_purge_middle);
-        // Delete cookies accessed on or after |safe_date|.
-        num_deleted += GarbageCollectDeleteRange(
-            current, DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE, it_purge_middle,
-            it_purge_end);
-        it_purge_begin = it_purge_end;
+      // Remove all but the kDomainCookiesQuotaLow most-recently accessed
+      // cookies with low-priority. Then, if cookies still need to be removed,
+      // bump the quota and remove low- and medium-priority. Then, if cookies
+      // _still_ need to be removed, bump the quota and remove cookies with
+      // any priority.
+      const size_t kQuotas[3] = {kDomainCookiesQuotaLow,
+                                 kDomainCookiesQuotaMedium,
+                                 kDomainCookiesQuotaHigh};
+      size_t quota = 0;
+      for (size_t i = 0; i < arraysize(kQuotas) && purge_goal > 0; i++) {
+        quota += kQuotas[i];
+        size_t just_deleted =
+            PurgeLeastRecentMatches(cookie_its, static_cast<CookiePriority>(i),
+                                    quota, purge_goal, safe_date);
+        DCHECK_LE(just_deleted, purge_goal);
+        purge_goal -= just_deleted;
+        num_deleted += just_deleted;
       }
+
       DCHECK_EQ(0U, purge_goal);
     }
   }
@@ -2009,6 +1956,49 @@
   return num_deleted;
 }
 
+size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies,
+                                              CookiePriority priority,
+                                              size_t to_protect,
+                                              size_t purge_goal,
+                                              const base::Time& safe_date) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // Find the first protected cookie by walking down from the end of the list
+  // cookie list (most-recently accessed) until |to_protect| cookies that match
+  // |priority| are found.
+  size_t protection_boundary = cookies->size();
+  while (to_protect > 0 && protection_boundary > 0) {
+    protection_boundary--;
+    if (cookies->at(protection_boundary)->second->Priority() <= priority)
+      to_protect--;
+  }
+
+  // Now, walk up from the beginning of the list (least-recently accessed) until
+  // |purge_goal| cookies are removed, or the iterator hits
+  // |protection_boundary|.
+  size_t removed = 0;
+  size_t current = 0;
+  while (removed < purge_goal && current < protection_boundary) {
+    if (cookies->at(current)->second->Priority() <= priority) {
+      InternalDeleteCookie(
+          cookies->at(current), true,
+          cookies->at(current)->second->LastAccessDate() > safe_date
+              ? DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE
+              : DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE);
+      cookies->erase(cookies->begin() + current);
+      removed++;
+
+      // The call to 'erase' above shifts the contents of the vector, but
+      // doesn't shift |protection_boundary|. Decrement that here to ensure that
+      // the correct set of cookies is protected.
+      protection_boundary--;
+    } else {
+      current++;
+    }
+  }
+  return removed;
+}
+
 size_t CookieMonster::GarbageCollectExpired(const Time& current,
                                             const CookieMapItPair& itpair,
                                             CookieItVector* cookie_its) {
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 8ad7395..421e7d0 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -541,6 +541,21 @@
                         const std::string& key,
                         bool enforce_strict_secure);
 
+  // Helper for GarbageCollect(). Deletes up to |purge_goal| cookies with a
+  // priority less than or equal to |priority| from |cookies|, while ensuring
+  // that at least the |to_protect| most-recent cookies are retained.
+  //
+  // |cookies| must be sorted from least-recent to most-recent.
+  //
+  // |safe_date| is only used to determine the deletion cause for histograms.
+  //
+  // Returns the number of cookies deleted.
+  size_t PurgeLeastRecentMatches(CookieItVector* cookies,
+                                 CookiePriority priority,
+                                 size_t to_protect,
+                                 size_t purge_goal,
+                                 const base::Time& safe_date);
+
   // Helper for GarbageCollect(); can be called directly as well.  Deletes all
   // expired cookies in |itpair|.  If |cookie_its| is non-NULL, all the
   // non-expired cookies from |itpair| are appended to |cookie_its|.
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 08a57ff..5a48d7d 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -361,6 +361,7 @@
                               size_t expected_low_count,
                               size_t expected_medium_count,
                               size_t expected_high_count) {
+    SCOPED_TRACE(coded_priority_str);
     this->DeleteAll(cm);
     int next_cookie_id = 0;
     std::vector<CookiePriority> priority_list;
diff --git a/net/data/ssl/certificates/multi-root-A-by-B.pem b/net/data/ssl/certificates/multi-root-A-by-B.pem
index 15adab26..01f99c2 100644
--- a/net/data/ssl/certificates/multi-root-A-by-B.pem
+++ b/net/data/ssl/certificates/multi-root-A-by-B.pem
@@ -1,106 +1,107 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAymw91u/myNSjqFLh+F33Tneso2Rvi9Q+zRiMOfIQZPfzYRrO
-j9gyGsH2iFEKEgfViFz1RVbQn4cXeN5N0P36YYHvoGs4Ajs9ik4fJXTwBcMbEPOk
-Um1og6+DaRZU1PlCgpiekkyCMzQpsS9g0/IAOtabIMwnV77aKbR096r28FpFDoXa
-AtTBloEmoKR3pVS0JHr1n+YIQqzYrAD3/IpDDcm2t6NN5lDZM/oYKLJ33aP1+jAy
-+b8lLJeRH2kmXB7pKyQmXZCRsY5cByq8OaQHtiiE3XWHIFATq7Q8USPl1+qJ8qn9
-2oew0poUIK7P+RYbeLiilFAvhkwgJwjQRICjeQIDAQABAoIBAFZhkJYrdCHZ1Ckd
-jX7Oop2iplJnps5V+aLOSfDkYqijwwF6ThHGYcNXaFxNsO122GHDwYsgfBDHtnWG
-8FAyQengaCDeAF27aAygP9xdJZxf4Sn/vuzJ8aLYgEyVEgh8gix28pxd9+Xf6bbK
-EBkCGaUCNdruJA/myvSnJI8YLx7rs7dMlwtQG1q9UD0cEJro9FkTBIsAUeXTyY+4
-qyhSyCvDeAO99ytHyrm9PjrR5cOHeTI/ADUMyQ5pXzHlNLLGCAUYeGvj6G7nqPGl
-gMRRxwM/oT9/uEtkBQwAjGw8o2rFQsX6q6e1r65MHAm+RPX8YPsEJ1QxGERl9AmD
-largQp0CgYEA97N6RqA4+ithhEEPgBNiglJVvzDfd4JlAwGX2czryZ8430e9yqj/
-J/QNTLkBmlsXC70yFu8iY6P0Me9wiJ0+DBSwm4j32o7qx9RSC5dqGSzYhs1LgBVd
-MMJiFZigU1Isvz/IQc/rVYDIIDrEuHmHA+siaeSAKf0GaRkiOBnh80sCgYEA0TRp
-/hAKjzdq7FcQ9K/a5W72Vx8GJ4mp5zoTMZnY/4vOSsC22SKU6FTcEj05xWCGMIgb
-CkFln2OLLq4FuAHzGX3PT+CvfJceRpdZcP1yULDQUBZ4qMJbhIcpMab06nw3Iv4c
-jNB2tEZe7yFiAdtSNh9k3KAZ3nkdNyC5X6zUxcsCgYAJ5ReLXrcn9zesCtVNrniO
-8C8QtikXIxRZ7GRehPseUMf602jXgay/sdYeLH3N5rmi9Gnd1KuxA0mr/P6n1nA2
-F1V+wRf1mSPz251zbRcF7m6v49+SPEg+vGUiq7gr2+qBsVCUoHOsNLrJ3s8g92nX
-VDtJs6ETDFKHPEPLre0CxQKBgA2hap6BEQ8Pv0myyooGwy5bsnUuskn1MDq+j+2V
-ZowP4dsA/2jaVfVlQgl2L8NqbJPQ6mIarLJb2/+omvrINbydc9pyezyU5AYZalxw
-Rvh27LurGyVztF7IJ6jyhdaZTUZcZCPQmUtZomnWNPqF/a9FEF9HlyfloD+tRCa1
-rg9NAoGAdTxat47SXzJFcF3JB8iMhnXUlXxLXSCKhGLN8dXUWQLnAOcy7QHuU627
-efEpl3V2P7klamc+VDJC2eGwW3wZdKkSnsngHOpWDvp5kN1pS1TeGSuaNxeIamwK
-y8MhHC/HzHdpCxLrNt22AA/li19PdXAxkbDg4p70ru6XTILQx9k=
+MIIEowIBAAKCAQEAyCccGYHApzCTAxz4IbgviiK0iQ/asUCV39xGU/xvNiZmWlNt
+RXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU5QzsXgMMF8U1Knurhuu/6GIKj7Al
+snD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuPc2pAd+szYKy+xSf9sU+ISxWvmP0y
+U66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC5vRJV+aRMS6+kqGt+HExZHQQM9Cn
+DO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1oYCRFm7bpggjZnNR+KX0r2a5Xf2Jq
+VpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJEQIDAQABAoIBAHadrupy2fB7OfSz
+W13oYMwVazZ7HdjD9M45JbiqNmI5+Zh4Lp7oRPo+KeWPgS2L8NxgimCGogunpAA6
+6ryYF1VzBjVkyurfZXWq2ulXl2Cpkaa79ms8xA/FHIfhmCyWa/0MKGTvhODdPkMW
+Uv1uGbKFenVW/xjA50HCRHerMZOE1yBaBzrAOGqLm4E/7snbZJ3K5Sx88mu9vAnA
+LBHMiqYwf4E9TJW+2AzDtlTI02/UbcQc4MDgRJc1YQSPz4pdtKbA3IvdDhXdsDCr
+Tum2gCpeUZS4zmXW6NcOBAHvrLdU8sEsodALCZ58hwkTU9YlqKyYE+DbuDd+3H5a
+3WIQbb0CgYEA6ZoLha/chlExbXr/5VcmiDfX/IRjAebG7uHMGC+QlSMxNxUGCuge
+kvw5+AkSsKdwHeSgr426SF3gPAwafK5KiTO4NoaD2pXFOvu5Z0Mpw4iT3kdTk/iO
+o2zTz4abEA0kQaqlhIbD5RrI5zU3K49BH8CkS+Kr5mCqtPu2b1aDac8CgYEA21gH
+/R1eTo4/0lBt+P4+4w8RMtt5Ky6rsZzSC87zJKznAKoGmo2rWCQKcxbZntznsuW3
+LN5MPYXXKqugp3fXebnRJYwBBE9HO39Cl5vb3l2EIYVRwspVeUs9KeTlt2FaiqQ1
+yE+s75bXFh9e3ztj4vOAWKGXi/KI2PHTdfo4tx8CgYEA5eX3BQDIdWAe1vJAOYMF
+pvXemOPpVIu8qIiMBhl5n2zdGKqWIdHDlUCqBFNZk4WVr7W79knzVRkef7ohrycQ
+r+q4luDXjx3q11u5YckVpxwY+p8TwALUzj1iT1DX9noYfo/lCYJf9G/h3Lngq/v2
+SbubdhuEtdvY5Pj82KI5/r0CgYAKDBxBkejR/F4cCicfcrX6vKPzCm6gdcDTn/VX
+KSGmGm1ycFdhGQAyR2RbJT7OshvC7BbZ7UzcvJbAk6AGS80I/GQCLkmVovQGW6v3
+OeJ2ax40UuEN5SrJJZMlqiCDp+f31dHI3S10xBoSH1m/K/9FVBYa+Tvx4yg1l84x
+50ZVzQKBgB6sEgCK7Q4HwOrSVyLvGjABZC41fuZSl58DB1bKdTtXq2ASP1igzmbR
+KEvawdUFqysM1TSz2F+QL4X393VVlSKi69w3LeORcMdOtbew2Rn7msBAHR4JO9sP
+dIdM/ccKebf1tgaTgI+c12yg+e+w7dey1Og0iPtcuMg3TumFX5q3
 -----END RSA PRIVATE KEY-----
 Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=B CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=B CA - Multi-root
         Validity
-            Not Before: Feb  8 23:34:58 2016 GMT
-            Not After : Feb  5 23:34:58 2026 GMT
+            Not Before: Mar 11 01:37:16 2016 GMT
+            Not After : Mar  9 01:37:16 2026 GMT
         Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:ca:6c:3d:d6:ef:e6:c8:d4:a3:a8:52:e1:f8:5d:
-                    f7:4e:77:ac:a3:64:6f:8b:d4:3e:cd:18:8c:39:f2:
-                    10:64:f7:f3:61:1a:ce:8f:d8:32:1a:c1:f6:88:51:
-                    0a:12:07:d5:88:5c:f5:45:56:d0:9f:87:17:78:de:
-                    4d:d0:fd:fa:61:81:ef:a0:6b:38:02:3b:3d:8a:4e:
-                    1f:25:74:f0:05:c3:1b:10:f3:a4:52:6d:68:83:af:
-                    83:69:16:54:d4:f9:42:82:98:9e:92:4c:82:33:34:
-                    29:b1:2f:60:d3:f2:00:3a:d6:9b:20:cc:27:57:be:
-                    da:29:b4:74:f7:aa:f6:f0:5a:45:0e:85:da:02:d4:
-                    c1:96:81:26:a0:a4:77:a5:54:b4:24:7a:f5:9f:e6:
-                    08:42:ac:d8:ac:00:f7:fc:8a:43:0d:c9:b6:b7:a3:
-                    4d:e6:50:d9:33:fa:18:28:b2:77:dd:a3:f5:fa:30:
-                    32:f9:bf:25:2c:97:91:1f:69:26:5c:1e:e9:2b:24:
-                    26:5d:90:91:b1:8e:5c:07:2a:bc:39:a4:07:b6:28:
-                    84:dd:75:87:20:50:13:ab:b4:3c:51:23:e5:d7:ea:
-                    89:f2:a9:fd:da:87:b0:d2:9a:14:20:ae:cf:f9:16:
-                    1b:78:b8:a2:94:50:2f:86:4c:20:27:08:d0:44:80:
-                    a3:79
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c8:27:1c:19:81:c0:a7:30:93:03:1c:f8:21:b8:
+                    2f:8a:22:b4:89:0f:da:b1:40:95:df:dc:46:53:fc:
+                    6f:36:26:66:5a:53:6d:45:78:c2:39:16:9a:3f:82:
+                    8b:ba:c5:b0:78:a8:18:bc:d5:a7:92:a5:e6:ac:e2:
+                    0c:81:d0:94:e5:0c:ec:5e:03:0c:17:c5:35:2a:7b:
+                    ab:86:eb:bf:e8:62:0a:8f:b0:25:b2:70:f5:11:8c:
+                    16:4f:c1:76:44:e5:75:e8:93:4f:e9:e7:c4:e4:42:
+                    0a:08:be:73:2c:cb:8f:73:6a:40:77:eb:33:60:ac:
+                    be:c5:27:fd:b1:4f:88:4b:15:af:98:fd:32:53:ae:
+                    b0:2a:0c:b2:f5:05:f3:3a:06:0d:6e:5c:fe:83:fc:
+                    e3:60:ae:99:8e:a1:21:c2:72:02:e6:f4:49:57:e6:
+                    91:31:2e:be:92:a1:ad:f8:71:31:64:74:10:33:d0:
+                    a7:0c:ed:18:c7:b2:50:71:fc:b9:b6:ae:95:a0:8d:
+                    ac:1f:3c:d5:79:a7:a9:88:50:b6:02:cd:68:60:24:
+                    45:9b:b6:e9:82:08:d9:9c:d4:7e:29:7d:2b:d9:ae:
+                    57:7f:62:6a:56:96:8b:4a:33:9e:5f:93:82:b0:d1:
+                    05:03:26:cd:15:f4:87:7f:6a:9a:df:e9:01:b5:d4:
+                    c9:11
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:FALSE
             X509v3 Subject Key Identifier: 
-                78:36:93:58:1F:73:7C:93:CA:AE:BB:9A:4E:A7:37:F1:83:03:4B:CF
+                FB:91:A9:5F:BC:27:81:98:55:30:BF:57:32:4D:B9:DA:56:DD:52:2C
             X509v3 Authority Key Identifier: 
-                keyid:0D:AF:BC:C3:31:09:C6:9D:F8:44:D2:51:E8:13:FF:24:78:9D:83:76
+                keyid:90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
 
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-        5e:87:35:21:15:89:4e:ac:9a:8e:db:d2:dc:83:6e:9e:64:b9:
-        30:f8:91:f7:9f:c4:de:b4:92:bf:05:4a:1b:e3:12:0f:b0:0d:
-        d8:8f:fd:f9:e6:e8:2c:24:e0:88:cc:58:5d:3b:a3:23:95:86:
-        b2:1f:0f:fb:02:95:c4:16:04:24:05:bb:65:e4:48:80:6e:64:
-        33:ed:a0:71:7d:21:f5:6f:70:72:07:54:b2:e7:79:98:8d:b5:
-        2b:0d:68:8e:3a:be:e3:91:f8:6a:60:d1:51:20:08:83:43:18:
-        5a:49:e2:66:21:aa:df:d2:b1:90:96:5a:99:6f:64:a0:96:7f:
-        e5:9b:3f:82:d5:42:8c:7d:fa:9f:b1:62:6c:e6:42:f6:1d:ab:
-        aa:e2:a4:05:33:99:4e:67:18:46:14:16:23:b8:46:db:d1:28:
-        a3:2c:2a:97:32:c3:02:e8:a0:9f:4f:e9:e6:c9:7e:c8:63:0d:
-        ff:de:95:f4:4d:f0:ca:57:49:9a:07:4b:5a:13:96:bc:49:10:
-        5c:3c:92:ce:1e:dd:10:d6:dc:6b:07:f0:ae:3e:0c:d0:05:1f:
-        00:08:79:0c:2a:e5:03:96:7d:1e:cb:3f:b7:f6:30:07:39:66:
-        8b:9a:b4:80:1c:e2:d2:7d:e8:bc:91:26:c5:9a:ec:a1:25:26:
-        56:0a:7b:39
+         b9:31:7a:95:b2:ba:3a:b4:f1:16:76:df:eb:d5:b9:af:67:b1:
+         9d:8a:27:04:9b:61:6f:42:3f:c2:b3:cd:65:c4:86:cb:90:fb:
+         9d:3a:ed:fc:b8:74:da:d7:6a:6c:2f:17:68:d1:73:58:f1:a2:
+         bb:8f:d6:b0:a8:7f:b6:a8:b0:74:d1:ea:c4:62:ed:bc:1e:ef:
+         02:6b:d5:e8:2d:15:78:16:1e:90:fa:f4:29:5a:a8:43:ad:d2:
+         58:40:b4:1c:60:4e:cd:bc:6f:1a:39:e4:46:b2:58:93:96:5a:
+         a8:a4:c4:31:73:ed:89:c4:81:27:e1:4c:66:20:7c:27:c4:f9:
+         61:ff:d1:d5:a5:02:93:4c:06:fa:15:33:7a:1f:5f:eb:29:b2:
+         b5:6a:cd:7e:d6:d7:b7:51:a7:01:2f:22:9f:9e:7e:81:98:c4:
+         72:11:36:2c:e7:c6:d0:f0:7d:98:36:ea:b7:a0:aa:13:8f:6e:
+         ae:41:59:9b:e6:c9:bc:9c:e8:93:f5:0c:4e:ca:b4:dd:e3:01:
+         fe:23:6e:fb:fa:b3:61:66:58:f5:fc:07:16:1d:a9:52:ec:a0:
+         29:61:a4:39:ed:41:50:a3:a2:33:72:0e:3c:03:e1:0a:1a:1a:
+         cf:22:73:09:d7:ea:e8:15:fc:73:3c:d4:4e:34:6c:b4:18:94:
+         c4:d3:6e:12
 -----BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD
-QTAeFw0xNjAyMDgyMzM0NThaFw0yNjAyMDUyMzM0NThaMGAxCzAJBgNVBAYTAlVT
-MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAw
-DgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQDKbD3W7+bI1KOoUuH4XfdOd6yjZG+L1D7NGIw5
-8hBk9/NhGs6P2DIawfaIUQoSB9WIXPVFVtCfhxd43k3Q/fphge+gazgCOz2KTh8l
-dPAFwxsQ86RSbWiDr4NpFlTU+UKCmJ6STIIzNCmxL2DT8gA61psgzCdXvtoptHT3
-qvbwWkUOhdoC1MGWgSagpHelVLQkevWf5ghCrNisAPf8ikMNyba3o03mUNkz+hgo
-snfdo/X6MDL5vyUsl5EfaSZcHukrJCZdkJGxjlwHKrw5pAe2KITddYcgUBOrtDxR
-I+XX6onyqf3ah7DSmhQgrs/5Fht4uKKUUC+GTCAnCNBEgKN5AgMBAAGjbzBtMAwG
-A1UdEwEB/wQCMAAwHQYDVR0OBBYEFHg2k1gfc3yTyq67mk6nN/GDA0vPMB8GA1Ud
-IwQYMBaAFA2vvMMxCcad+ETSUegT/yR4nYN2MB0GA1UdJQQWMBQGCCsGAQUFBwMB
-BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAXoc1IRWJTqyajtvS3INunmS5
-MPiR95/E3rSSvwVKG+MSD7AN2I/9+eboLCTgiMxYXTujI5WGsh8P+wKVxBYEJAW7
-ZeRIgG5kM+2gcX0h9W9wcgdUsud5mI21Kw1ojjq+45H4amDRUSAIg0MYWkniZiGq
-39KxkJZamW9koJZ/5Zs/gtVCjH36n7FibOZC9h2rquKkBTOZTmcYRhQWI7hG29Eo
-oywqlzLDAuign0/p5sl+yGMN/96V9E3wyldJmgdLWhOWvEkQXDySzh7dENbcawfw
-rj4M0AUfAAh5DCrlA5Z9Hss/t/YwBzlmi5q0gBzi0n3ovJEmxZrsoSUmVgp7OQ==
+MIIDZzCCAk+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
+QSAtIE11bHRpLXJvb3QwHhcNMTYwMzExMDEzNzE2WhcNMjYwMzA5MDEzNzE2WjBg
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4x
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCccGYHApzCTAxz4Ibgv
+iiK0iQ/asUCV39xGU/xvNiZmWlNtRXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU
+5QzsXgMMF8U1Knurhuu/6GIKj7AlsnD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuP
+c2pAd+szYKy+xSf9sU+ISxWvmP0yU66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC
+5vRJV+aRMS6+kqGt+HExZHQQM9CnDO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1o
+YCRFm7bpggjZnNR+KX0r2a5Xf2JqVpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJ
+EQIDAQABo28wbTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBT7kalfvCeBmFUwv1cy
+TbnaVt1SLDAfBgNVHSMEGDAWgBSQy1PuNgpasJM4yRG3rP0ncZncgTAdBgNVHSUE
+FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBALkxepWy
+ujq08RZ23+vVua9nsZ2KJwSbYW9CP8KzzWXEhsuQ+5067fy4dNrXamwvF2jRc1jx
+oruP1rCof7aosHTR6sRi7bwe7wJr1egtFXgWHpD69ClaqEOt0lhAtBxgTs28bxo5
+5EayWJOWWqikxDFz7YnEgSfhTGYgfCfE+WH/0dWlApNMBvoVM3ofX+spsrVqzX7W
+17dRpwEvIp+efoGYxHIRNiznxtDwfZg26regqhOPbq5BWZvmybyc6JP1DE7KtN3j
+Af4jbvv6s2FmWPX8BxYdqVLsoClhpDntQVCjojNyDjwD4QoaGs8icwnX6ugV/HM8
+1E40bLQYlMTTbhI=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-B-by-C.pem b/net/data/ssl/certificates/multi-root-B-by-C.pem
index 2769104..5731bb1 100644
--- a/net/data/ssl/certificates/multi-root-B-by-C.pem
+++ b/net/data/ssl/certificates/multi-root-B-by-C.pem
@@ -2,73 +2,73 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=C CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=C CA - Multi-root
         Validity
             Not Before: Jan  4 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=B CA
+        Subject: CN=B CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:a2:a0:93:17:1e:ee:f0:fb:87:1f:71:ca:6b:b9:
-                    bd:2d:67:38:2a:24:c7:c3:c2:88:4d:ca:f2:50:33:
-                    60:1d:6f:61:a5:61:02:a4:a7:76:2b:89:43:78:a7:
-                    0a:27:04:dc:a5:5b:6e:a8:4c:29:f2:25:c6:c0:32:
-                    20:e0:01:8d:a1:16:15:c9:b5:d8:17:7d:e0:e8:90:
-                    89:a3:f5:96:1f:90:c6:e3:10:1a:f9:f5:6a:d5:41:
-                    ce:cd:a8:fc:36:77:2f:a2:d7:8e:39:50:36:65:4d:
-                    a7:83:6c:e1:a4:cc:f6:6b:c0:7b:c8:98:f4:01:3f:
-                    94:d3:d6:11:1d:b3:ef:95:c8:ea:07:d9:5e:fd:82:
-                    4f:23:4d:08:89:fb:68:2d:82:12:98:e0:87:f2:7a:
-                    c7:76:98:4c:ca:1d:3e:e8:bc:72:dd:b0:b7:41:84:
-                    6e:39:cd:a9:35:e8:ee:2a:d1:54:cd:21:ed:6f:a4:
-                    ab:e9:d8:c9:d2:e9:11:66:66:78:33:ae:d8:78:75:
-                    ac:1e:ad:0e:23:82:35:13:96:ed:eb:3e:58:eb:27:
-                    fb:1b:fd:27:6e:f0:c3:ff:88:cc:cc:63:35:23:3d:
-                    ce:4d:2e:2d:dc:b3:91:8e:d8:d8:5b:6a:92:28:c5:
-                    e9:a4:02:76:34:e0:6d:41:61:43:71:e1:59:b3:c2:
-                    ce:f7
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
+                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
+                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
+                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
+                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
+                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
+                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
+                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
+                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
+                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
+                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
+                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
+                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
+                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
+                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
+                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
+                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
+                    34:69
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                0D:AF:BC:C3:31:09:C6:9D:F8:44:D2:51:E8:13:FF:24:78:9D:83:76
+                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        28:52:54:55:5c:5b:4f:af:4c:66:cc:c3:71:dd:3e:60:48:76:
-        c3:f0:c0:40:30:f6:44:06:73:2f:c5:b1:1c:6a:e9:6f:fd:92:
-        8d:40:38:eb:46:de:58:cd:68:0f:cd:7f:28:a2:79:29:92:ae:
-        68:f2:ba:0a:f1:e6:17:58:a4:3b:ee:61:6c:d6:5d:2a:07:61:
-        b0:31:c9:9b:dc:08:32:b8:d8:ac:14:9c:1a:ec:21:7d:46:63:
-        75:67:46:36:ec:25:f0:e6:ed:3f:5d:b7:fd:06:67:46:80:a0:
-        b9:a8:25:e7:05:0a:f9:a7:20:48:d4:71:b4:3f:0b:1c:4d:f4:
-        73:8b:cc:9f:67:cf:36:43:e2:82:d5:d5:4e:4c:71:74:5c:db:
-        ba:35:bf:1e:9e:63:46:d0:c7:b9:f4:2a:92:23:c7:59:af:5d:
-        b1:24:7c:ff:1c:08:0d:2a:50:79:57:1c:a2:45:38:a5:3e:d7:
-        c8:5c:91:f2:69:70:d1:47:4a:55:bc:84:dc:9b:9f:ae:f2:94:
-        1c:22:65:11:4c:7c:e1:3c:ae:d4:e6:11:fc:3f:d8:53:6b:65:
-        4a:7c:44:bf:91:bd:b0:3e:df:b5:f5:c5:8e:1f:a5:19:83:2a:
-        8d:4e:13:3d:58:45:8e:11:b6:9e:96:7a:7a:6e:0b:e5:1a:66:
-        7a:00:0e:75
+         97:cd:ae:5a:26:f4:25:f6:c0:8b:08:d8:df:82:35:d8:76:f3:
+         5d:cc:99:bd:ac:70:c9:41:e0:24:c8:fd:e6:4e:41:2c:d4:69:
+         8d:08:25:fd:f3:32:3a:58:0b:d3:58:9c:81:51:bf:97:a4:bc:
+         00:18:1c:4f:1c:54:04:63:e3:72:87:f4:dc:9e:7b:dc:da:5d:
+         e1:ef:59:6b:f0:1f:3d:0c:11:55:1e:9a:1a:d8:8d:bc:7b:18:
+         b7:4f:92:1c:68:73:82:ec:f3:69:48:0a:86:40:4a:a5:6f:ae:
+         8f:10:2e:12:0b:e8:7e:b9:bc:d7:26:f0:cf:f4:0f:5b:77:f2:
+         ff:77:28:b4:5f:5e:ef:65:08:21:b8:f9:1e:56:b9:69:3b:c4:
+         7f:01:88:c9:7c:ca:d0:e2:df:e5:5e:8d:e9:2e:7d:4a:78:04:
+         8b:c1:dc:d4:58:ac:90:fc:5c:8e:48:2b:60:99:63:37:3f:e5:
+         61:da:8f:58:9f:4d:0a:ee:6c:8d:bc:1f:7e:c4:be:0f:32:4b:
+         11:7a:28:bf:dd:d0:a0:40:42:a8:43:4d:0b:2f:01:0e:73:de:
+         1b:a6:df:49:57:58:89:57:c0:23:76:83:f0:9a:0e:83:d9:9b:
+         cb:eb:ac:3f:89:d1:e8:3c:3e:f1:d5:80:0c:38:18:02:5c:5f:
+         e5:68:5e:cf
 -----BEGIN CERTIFICATE-----
-MIIC3DCCAcSgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQyBD
-QTAeFw0xNjAxMDQwMDAwMDBaFw0yNjAxMDIwMDAwMDBaMA8xDTALBgNVBAMMBEIg
-Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCioJMXHu7w+4cfccpr
-ub0tZzgqJMfDwohNyvJQM2Adb2GlYQKkp3YriUN4pwonBNylW26oTCnyJcbAMiDg
-AY2hFhXJtdgXfeDokImj9ZYfkMbjEBr59WrVQc7NqPw2dy+i1445UDZlTaeDbOGk
-zPZrwHvImPQBP5TT1hEds++VyOoH2V79gk8jTQiJ+2gtghKY4Ifyesd2mEzKHT7o
-vHLdsLdBhG45zak16O4q0VTNIe1vpKvp2MnS6RFmZngzrth4dawerQ4jgjUTlu3r
-PljrJ/sb/Sdu8MP/iMzMYzUjPc5NLi3cs5GO2NhbapIoxemkAnY04G1BYUNx4Vmz
-ws73AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA2vvMMxCcad
-+ETSUegT/yR4nYN2MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
-KFJUVVxbT69MZszDcd0+YEh2w/DAQDD2RAZzL8WxHGrpb/2SjUA460beWM1oD81/
-KKJ5KZKuaPK6CvHmF1ikO+5hbNZdKgdhsDHJm9wIMrjYrBScGuwhfUZjdWdGNuwl
-8ObtP123/QZnRoCguagl5wUK+acgSNRxtD8LHE30c4vMn2fPNkPigtXVTkxxdFzb
-ujW/Hp5jRtDHufQqkiPHWa9dsSR8/xwIDSpQeVccokU4pT7XyFyR8mlw0UdKVbyE
-3JufrvKUHCJlEUx84Tyu1OYR/D/YU2tlSnxEv5G9sD7ftfXFjh+lGYMqjU4TPVhF
-jhG2npZ6em4L5RpmegAOdQ==
+MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQyBD
+QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA0MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
+MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
+HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
+dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
+jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
+CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
+vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCXza5aJvQl9sCLCNjfgjXYdvNdzJm9
+rHDJQeAkyP3mTkEs1GmNCCX98zI6WAvTWJyBUb+XpLwAGBxPHFQEY+Nyh/Tcnnvc
+2l3h71lr8B89DBFVHpoa2I28exi3T5IcaHOC7PNpSAqGQEqlb66PEC4SC+h+ubzX
+JvDP9A9bd/L/dyi0X17vZQghuPkeVrlpO8R/AYjJfMrQ4t/lXo3pLn1KeASLwdzU
+WKyQ/FyOSCtgmWM3P+Vh2o9Yn00K7myNvB9+xL4PMksReii/3dCgQEKoQ00LLwEO
+c94bpt9JV1iJV8AjdoPwmg6D2ZvL66w/idHoPD7x1YAMOBgCXF/laF7P
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-B-by-F.pem b/net/data/ssl/certificates/multi-root-B-by-F.pem
index 8915a0d..d760580 100644
--- a/net/data/ssl/certificates/multi-root-B-by-F.pem
+++ b/net/data/ssl/certificates/multi-root-B-by-F.pem
@@ -2,73 +2,73 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=F CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=F CA - Multi-root
         Validity
             Not Before: Jan  5 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=B CA
+        Subject: CN=B CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:a2:a0:93:17:1e:ee:f0:fb:87:1f:71:ca:6b:b9:
-                    bd:2d:67:38:2a:24:c7:c3:c2:88:4d:ca:f2:50:33:
-                    60:1d:6f:61:a5:61:02:a4:a7:76:2b:89:43:78:a7:
-                    0a:27:04:dc:a5:5b:6e:a8:4c:29:f2:25:c6:c0:32:
-                    20:e0:01:8d:a1:16:15:c9:b5:d8:17:7d:e0:e8:90:
-                    89:a3:f5:96:1f:90:c6:e3:10:1a:f9:f5:6a:d5:41:
-                    ce:cd:a8:fc:36:77:2f:a2:d7:8e:39:50:36:65:4d:
-                    a7:83:6c:e1:a4:cc:f6:6b:c0:7b:c8:98:f4:01:3f:
-                    94:d3:d6:11:1d:b3:ef:95:c8:ea:07:d9:5e:fd:82:
-                    4f:23:4d:08:89:fb:68:2d:82:12:98:e0:87:f2:7a:
-                    c7:76:98:4c:ca:1d:3e:e8:bc:72:dd:b0:b7:41:84:
-                    6e:39:cd:a9:35:e8:ee:2a:d1:54:cd:21:ed:6f:a4:
-                    ab:e9:d8:c9:d2:e9:11:66:66:78:33:ae:d8:78:75:
-                    ac:1e:ad:0e:23:82:35:13:96:ed:eb:3e:58:eb:27:
-                    fb:1b:fd:27:6e:f0:c3:ff:88:cc:cc:63:35:23:3d:
-                    ce:4d:2e:2d:dc:b3:91:8e:d8:d8:5b:6a:92:28:c5:
-                    e9:a4:02:76:34:e0:6d:41:61:43:71:e1:59:b3:c2:
-                    ce:f7
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
+                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
+                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
+                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
+                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
+                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
+                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
+                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
+                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
+                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
+                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
+                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
+                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
+                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
+                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
+                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
+                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
+                    34:69
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                0D:AF:BC:C3:31:09:C6:9D:F8:44:D2:51:E8:13:FF:24:78:9D:83:76
+                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        97:0b:58:06:81:05:d1:e6:dd:04:fd:36:f6:e5:97:70:1f:b0:
-        81:e5:9e:1e:d7:c2:47:31:0d:a2:0d:f8:f3:b3:db:71:7a:30:
-        9f:4f:de:ba:e8:de:d1:b8:e8:a5:34:79:89:1d:46:b1:8e:ad:
-        ff:5c:79:00:e9:08:b7:55:20:26:3e:cd:c3:18:b0:dc:c9:74:
-        0b:2a:3c:90:3a:53:36:f4:33:b8:92:38:01:5a:7c:ab:ea:b2:
-        33:bf:5b:8b:58:92:05:9f:0f:d6:ed:06:21:7d:71:b1:c8:a4:
-        13:61:ef:59:09:d1:0a:c3:d1:91:5c:d7:87:59:a6:50:9c:66:
-        bd:b7:24:d2:5f:a5:24:93:51:62:6e:57:35:d7:76:96:58:e2:
-        44:4a:2a:03:37:25:7f:aa:c6:c8:5d:68:77:4a:f4:be:b8:be:
-        fc:33:5f:86:71:32:09:24:38:7c:38:59:4d:dc:f2:23:17:22:
-        0e:a5:44:b3:f6:e0:67:d1:f1:98:83:aa:6e:48:dd:d3:99:99:
-        40:4f:18:3d:71:84:2c:58:e6:25:38:8f:14:de:54:3a:d3:8b:
-        99:d6:aa:20:80:a2:50:27:a1:fa:28:6e:47:80:a7:33:c9:0c:
-        4a:65:b7:6f:3c:97:b7:69:c7:20:16:01:ed:cb:eb:a5:82:f1:
-        94:e6:8a:d7
+         64:09:43:15:ae:ac:dc:ad:23:99:24:cb:3a:39:4b:ad:2b:83:
+         f2:69:c3:f8:7e:e8:79:1e:8f:b1:09:0c:17:e6:44:5f:47:33:
+         14:fa:d4:f2:d8:d2:94:a9:75:58:4e:a8:44:8f:71:d0:53:c0:
+         76:5d:8e:39:1c:23:95:3d:89:c7:18:0a:0e:80:37:3d:8d:a6:
+         6d:60:c9:ad:08:a3:7a:8a:e8:00:3e:bf:67:e0:b6:09:b2:3b:
+         55:a6:b8:36:24:00:5e:8d:89:89:53:df:ea:2d:a9:f8:d2:60:
+         5a:e1:7b:f6:6c:a1:29:95:13:75:fe:62:57:cd:b4:0e:50:dc:
+         b5:41:3d:e9:19:0b:33:62:43:af:14:4d:40:c2:48:eb:72:88:
+         65:d3:89:11:f4:98:e8:f7:13:b4:7a:11:8e:39:01:80:a5:2e:
+         27:4a:98:3c:c8:d4:4f:31:70:3f:c2:de:e0:69:6b:59:54:d7:
+         66:07:68:74:72:9c:c2:1c:1c:0c:0d:b9:65:90:47:41:93:2c:
+         ec:d1:f0:51:b7:69:7b:e6:88:d8:f7:f7:0f:f1:4e:8c:e1:e9:
+         50:5d:7a:c3:62:1d:32:76:8e:df:7f:87:34:e4:57:bf:9c:1d:
+         45:4b:3b:07:f2:d1:8b:d6:d0:e6:72:de:7b:4b:23:bf:ee:1b:
+         c7:40:d0:a7
 -----BEGIN CERTIFICATE-----
-MIIC3DCCAcSgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwERiBD
-QTAeFw0xNjAxMDUwMDAwMDBaFw0yNjAxMDIwMDAwMDBaMA8xDTALBgNVBAMMBEIg
-Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCioJMXHu7w+4cfccpr
-ub0tZzgqJMfDwohNyvJQM2Adb2GlYQKkp3YriUN4pwonBNylW26oTCnyJcbAMiDg
-AY2hFhXJtdgXfeDokImj9ZYfkMbjEBr59WrVQc7NqPw2dy+i1445UDZlTaeDbOGk
-zPZrwHvImPQBP5TT1hEds++VyOoH2V79gk8jTQiJ+2gtghKY4Ifyesd2mEzKHT7o
-vHLdsLdBhG45zak16O4q0VTNIe1vpKvp2MnS6RFmZngzrth4dawerQ4jgjUTlu3r
-PljrJ/sb/Sdu8MP/iMzMYzUjPc5NLi3cs5GO2NhbapIoxemkAnY04G1BYUNx4Vmz
-ws73AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA2vvMMxCcad
-+ETSUegT/yR4nYN2MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
-lwtYBoEF0ebdBP029uWXcB+wgeWeHtfCRzENog3487PbcXown0/euuje0bjopTR5
-iR1GsY6t/1x5AOkIt1UgJj7Nwxiw3Ml0Cyo8kDpTNvQzuJI4AVp8q+qyM79bi1iS
-BZ8P1u0GIX1xscikE2HvWQnRCsPRkVzXh1mmUJxmvbck0l+lJJNRYm5XNdd2llji
-REoqAzclf6rGyF1od0r0vri+/DNfhnEyCSQ4fDhZTdzyIxciDqVEs/bgZ9HxmIOq
-bkjd05mZQE8YPXGELFjmJTiPFN5UOtOLmdaqIICiUCeh+ihuR4CnM8kMSmW3bzyX
-t2nHIBYB7cvrpYLxlOaK1w==
+MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRRiBD
+QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA1MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
+MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
+HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
+dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
+jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
+CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
+vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBkCUMVrqzcrSOZJMs6OUutK4PyacP4
+fuh5Ho+xCQwX5kRfRzMU+tTy2NKUqXVYTqhEj3HQU8B2XY45HCOVPYnHGAoOgDc9
+jaZtYMmtCKN6iugAPr9n4LYJsjtVprg2JABejYmJU9/qLan40mBa4Xv2bKEplRN1
+/mJXzbQOUNy1QT3pGQszYkOvFE1Awkjrcohl04kR9Jjo9xO0ehGOOQGApS4nSpg8
+yNRPMXA/wt7gaWtZVNdmB2h0cpzCHBwMDbllkEdBkyzs0fBRt2l75ojY9/cP8U6M
+4elQXXrDYh0ydo7ff4c05Fe/nB1FSzsH8tGL1tDmct57SyO/7hvHQNCn
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-C-by-D.pem b/net/data/ssl/certificates/multi-root-C-by-D.pem
index 67f31b8..bab6142 100644
--- a/net/data/ssl/certificates/multi-root-C-by-D.pem
+++ b/net/data/ssl/certificates/multi-root-C-by-D.pem
@@ -2,73 +2,73 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4097 (0x1001)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=D Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=D Root CA - Multi-root
         Validity
             Not Before: Jan  3 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=C CA
+        Subject: CN=C CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:c2:21:aa:d2:67:ec:f5:95:9e:c9:00:f2:ee:83:
-                    26:6c:3c:30:d4:a8:78:dd:0a:a5:d6:81:f0:54:25:
-                    de:8f:9a:0e:8f:5c:06:96:b0:83:b7:13:56:33:9e:
-                    d1:6a:7d:45:40:d8:e5:21:1d:c5:6d:31:34:6f:45:
-                    22:cf:6f:01:b4:f8:6c:ce:70:d0:e9:0e:ed:04:d9:
-                    34:7a:91:db:6f:90:94:66:95:26:0b:29:26:4c:6c:
-                    8b:e3:13:a1:42:29:59:a0:2c:fe:83:a5:3c:3d:e8:
-                    32:ac:37:a7:ae:b2:79:d3:12:98:5f:c7:fd:4c:49:
-                    6b:e4:32:40:76:7b:78:ae:a1:61:b1:0a:d1:5c:f3:
-                    96:13:5f:95:5a:a2:35:c5:63:1b:25:05:8d:3c:08:
-                    d0:b0:28:2a:f3:f6:34:ab:a5:cd:e7:82:2c:35:38:
-                    8b:f5:41:6c:71:32:c4:13:67:ef:9b:8f:32:ab:7c:
-                    da:e1:6a:92:4b:5b:9e:39:7e:6b:00:f8:8d:e2:b3:
-                    3b:ad:2f:11:3f:80:d5:19:0e:cc:d4:c1:21:42:46:
-                    42:2d:d0:5e:ae:63:d1:0a:3e:66:fb:eb:0b:9b:e4:
-                    fe:7a:ca:43:5c:cc:98:6a:e1:fd:32:18:4c:63:4c:
-                    cd:98:9b:be:fa:5b:2d:c4:76:cc:8d:e5:6d:aa:bb:
-                    5a:37
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
+                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
+                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
+                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
+                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
+                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
+                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
+                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
+                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
+                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
+                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
+                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
+                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
+                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
+                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
+                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
+                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
+                    4b:11
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                34:19:53:D9:DA:11:B1:FF:00:35:2B:37:00:91:1F:91:C0:F7:2E:0A
+                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        5a:aa:0a:cb:92:8a:cd:ca:49:b4:5e:34:32:46:0a:9e:fd:71:
-        30:dd:af:b8:9a:6c:82:87:59:27:ed:df:11:1f:13:fa:c9:d9:
-        fb:8a:e8:ba:7c:67:33:7e:ea:42:f3:1c:34:91:5c:5f:ed:68:
-        d7:dc:06:8d:6a:75:38:42:4f:eb:52:55:84:c6:74:9d:53:87:
-        d6:34:64:19:19:4c:6d:b7:3a:f9:e8:8a:14:4d:00:ec:07:71:
-        00:6c:05:80:94:4b:4f:e7:a4:db:26:ee:e1:2b:98:d6:ad:ca:
-        32:ab:d6:3a:23:83:30:e8:33:82:82:7d:a5:1e:00:97:be:a8:
-        0f:68:d7:ae:8a:4a:52:be:d7:b5:0a:49:4d:a8:f1:25:e3:de:
-        41:37:6a:53:1c:b5:0e:b0:fd:b6:db:25:b6:a2:cb:ff:d8:7f:
-        98:30:84:15:f0:27:b5:fd:a3:71:35:ad:4c:83:8c:d1:da:49:
-        a5:97:b3:7d:80:6f:03:40:fe:a3:22:38:58:70:6d:43:01:63:
-        db:fb:ca:b6:5f:fc:f0:45:b3:57:5a:a6:cc:b9:d0:99:a8:f6:
-        a4:4f:c6:20:a5:6e:dd:e0:3b:e7:b2:0a:8b:6f:4d:6f:67:57:
-        e7:c4:58:80:26:5d:1d:27:f9:3e:22:ed:00:bc:fa:8d:8d:eb:
-        bb:ab:91:a9
+         67:11:95:f4:b9:cb:47:e6:50:da:fd:a0:13:78:d7:e1:be:59:
+         ec:86:32:e5:56:3e:9b:8f:db:b0:3b:93:fb:d0:6e:b3:de:7e:
+         10:5b:b4:30:f7:02:e8:3f:ff:4e:91:3a:e8:b8:4a:94:5e:14:
+         7b:f8:84:e5:1f:63:2c:b4:7f:4f:ee:b1:d5:ee:92:79:7d:63:
+         87:a0:e9:57:14:57:11:59:18:54:8b:e3:d1:51:80:a7:2f:51:
+         f2:6f:43:d2:87:e1:59:23:2c:fe:83:38:e1:25:da:b5:34:af:
+         33:17:64:80:08:b6:bd:5f:92:05:2c:81:b0:c3:d3:80:cd:e1:
+         5c:95:d2:ea:1e:d3:af:d9:93:c2:f4:23:ae:51:b0:a4:82:49:
+         2d:ec:fe:d1:18:e3:a3:53:9f:63:4b:38:dc:54:25:ce:4c:90:
+         37:02:e4:67:41:31:ba:7a:13:1a:68:1e:ed:34:0c:3d:66:ba:
+         a3:3a:71:76:5f:5f:89:a1:cd:95:50:f6:5d:1f:c0:91:31:93:
+         5b:58:af:e7:9b:21:e6:57:b1:f4:d7:dd:c1:84:25:5b:83:f7:
+         5f:c9:89:17:5b:6f:54:f2:8b:ed:47:de:27:57:9e:e9:8c:b3:
+         58:2c:c2:77:25:e1:eb:22:06:d1:f6:c5:f4:d7:1a:3d:00:1c:
+         2e:85:e9:70
 -----BEGIN CERTIFICATE-----
-MIIC4TCCAcmgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRCBS
-b290IENBMB4XDTE2MDEwMzAwMDAwMFoXDTI2MDEwMjAwMDAwMFowDzENMAsGA1UE
-AwwEQyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIhqtJn7PWV
-nskA8u6DJmw8MNSoeN0KpdaB8FQl3o+aDo9cBpawg7cTVjOe0Wp9RUDY5SEdxW0x
-NG9FIs9vAbT4bM5w0OkO7QTZNHqR22+QlGaVJgspJkxsi+MToUIpWaAs/oOlPD3o
-Mqw3p66yedMSmF/H/UxJa+QyQHZ7eK6hYbEK0VzzlhNflVqiNcVjGyUFjTwI0LAo
-KvP2NKulzeeCLDU4i/VBbHEyxBNn75uPMqt82uFqkktbnjl+awD4jeKzO60vET+A
-1RkOzNTBIUJGQi3QXq5j0Qo+ZvvrC5vk/nrKQ1zMmGrh/TIYTGNMzZibvvpbLcR2
-zI3lbaq7WjcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNBlT
-2doRsf8ANSs3AJEfkcD3LgowDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUA
-A4IBAQBaqgrLkorNykm0XjQyRgqe/XEw3a+4mmyCh1kn7d8RHxP6ydn7iui6fGcz
-fupC8xw0kVxf7WjX3AaNanU4Qk/rUlWExnSdU4fWNGQZGUxttzr56IoUTQDsB3EA
-bAWAlEtP56TbJu7hK5jWrcoyq9Y6I4Mw6DOCgn2lHgCXvqgPaNeuikpSvte1CklN
-qPEl495BN2pTHLUOsP222yW2osv/2H+YMIQV8Ce1/aNxNa1Mg4zR2kmll7N9gG8D
-QP6jIjhYcG1DAWPb+8q2X/zwRbNXWqbMudCZqPakT8YgpW7d4DvnsgqLb01vZ1fn
-xFiAJl0dJ/k+Iu0AvPqNjeu7q5Gp
+MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDMwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
+FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
+O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
+l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
+wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
+BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAGcRlfS5y0fmUNr9oBN41+G+
+WeyGMuVWPpuP27A7k/vQbrPefhBbtDD3Aug//06ROui4SpReFHv4hOUfYyy0f0/u
+sdXuknl9Y4eg6VcUVxFZGFSL49FRgKcvUfJvQ9KH4VkjLP6DOOEl2rU0rzMXZIAI
+tr1fkgUsgbDD04DN4VyV0uoe06/Zk8L0I65RsKSCSS3s/tEY46NTn2NLONxUJc5M
+kDcC5GdBMbp6ExpoHu00DD1muqM6cXZfX4mhzZVQ9l0fwJExk1tYr+ebIeZXsfTX
+3cGEJVuD91/JiRdbb1Tyi+1H3idXnumMs1gswncl4esiBtH2xfTXGj0AHC6F6XA=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-C-by-E.pem b/net/data/ssl/certificates/multi-root-C-by-E.pem
index 2ef8f1a..5ecc8b262 100644
--- a/net/data/ssl/certificates/multi-root-C-by-E.pem
+++ b/net/data/ssl/certificates/multi-root-C-by-E.pem
@@ -2,73 +2,73 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4097 (0x1001)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=E Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=E Root CA - Multi-root
         Validity
             Not Before: Jan  5 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=C CA
+        Subject: CN=C CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:c2:21:aa:d2:67:ec:f5:95:9e:c9:00:f2:ee:83:
-                    26:6c:3c:30:d4:a8:78:dd:0a:a5:d6:81:f0:54:25:
-                    de:8f:9a:0e:8f:5c:06:96:b0:83:b7:13:56:33:9e:
-                    d1:6a:7d:45:40:d8:e5:21:1d:c5:6d:31:34:6f:45:
-                    22:cf:6f:01:b4:f8:6c:ce:70:d0:e9:0e:ed:04:d9:
-                    34:7a:91:db:6f:90:94:66:95:26:0b:29:26:4c:6c:
-                    8b:e3:13:a1:42:29:59:a0:2c:fe:83:a5:3c:3d:e8:
-                    32:ac:37:a7:ae:b2:79:d3:12:98:5f:c7:fd:4c:49:
-                    6b:e4:32:40:76:7b:78:ae:a1:61:b1:0a:d1:5c:f3:
-                    96:13:5f:95:5a:a2:35:c5:63:1b:25:05:8d:3c:08:
-                    d0:b0:28:2a:f3:f6:34:ab:a5:cd:e7:82:2c:35:38:
-                    8b:f5:41:6c:71:32:c4:13:67:ef:9b:8f:32:ab:7c:
-                    da:e1:6a:92:4b:5b:9e:39:7e:6b:00:f8:8d:e2:b3:
-                    3b:ad:2f:11:3f:80:d5:19:0e:cc:d4:c1:21:42:46:
-                    42:2d:d0:5e:ae:63:d1:0a:3e:66:fb:eb:0b:9b:e4:
-                    fe:7a:ca:43:5c:cc:98:6a:e1:fd:32:18:4c:63:4c:
-                    cd:98:9b:be:fa:5b:2d:c4:76:cc:8d:e5:6d:aa:bb:
-                    5a:37
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
+                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
+                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
+                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
+                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
+                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
+                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
+                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
+                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
+                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
+                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
+                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
+                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
+                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
+                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
+                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
+                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
+                    4b:11
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                34:19:53:D9:DA:11:B1:FF:00:35:2B:37:00:91:1F:91:C0:F7:2E:0A
+                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        57:6d:1c:44:40:54:a1:e5:3c:a0:e1:e1:d0:72:41:61:93:91:
-        38:65:8b:cc:35:d9:4c:04:80:12:4a:fd:84:71:9f:06:4f:de:
-        06:1c:0d:93:51:b2:2d:d7:c8:f5:0d:4f:fd:14:58:9e:d2:c2:
-        ac:5d:bf:f7:67:5f:68:2d:a2:cf:12:86:79:26:70:11:2d:3f:
-        0c:5f:65:fc:44:fd:6e:87:5e:56:3a:dc:be:da:95:e2:45:aa:
-        07:28:ff:46:1e:4b:bf:03:92:84:53:9b:c9:7a:dd:e7:5e:e9:
-        57:ba:18:c2:23:12:26:27:74:b6:93:44:4c:1e:6a:e2:20:62:
-        e5:33:db:86:14:41:7e:7c:76:5a:e5:d1:7f:fc:f4:f9:a3:23:
-        c9:06:ec:cb:b5:62:1e:bc:7b:1c:70:57:a5:d3:1d:d6:0f:79:
-        6a:f2:05:58:63:11:91:fb:b4:44:6a:b2:97:18:cf:ee:de:5d:
-        ac:d4:d8:63:e2:4f:42:25:fa:44:a4:47:b1:e4:f7:7f:55:a0:
-        e0:f7:09:f8:43:5c:54:1f:6a:e4:87:96:91:a0:8b:72:57:53:
-        52:22:31:d1:26:d4:5f:38:43:17:2a:48:91:37:b6:d8:d2:b3:
-        54:fc:f7:61:4e:c6:bc:39:89:e2:d8:3c:c0:d4:50:33:0b:de:
-        3d:02:70:5d
+         43:35:08:cc:aa:f8:10:9f:9e:fa:ab:24:dc:c6:e6:9a:23:52:
+         c9:4c:81:33:ba:64:b2:86:a8:29:f4:1f:5a:fa:5a:c4:91:56:
+         16:d1:f9:84:96:89:8c:ac:1f:b6:ea:2f:cb:12:f4:92:ed:3b:
+         85:09:eb:f3:7a:2e:09:39:ec:ee:09:4b:fa:86:3e:62:40:0e:
+         57:72:07:de:fa:53:45:ac:40:1c:0d:0b:4a:67:9a:f7:39:ce:
+         33:5e:d0:17:0b:8a:83:ae:33:6f:96:c0:f0:7a:ac:07:36:c5:
+         86:a9:db:93:aa:2e:fa:71:d1:1a:dd:82:2a:f8:1c:30:2a:b9:
+         7d:29:fa:75:62:76:7c:15:15:75:af:78:6c:7c:53:ae:2e:80:
+         14:0d:0b:eb:0f:b1:6d:fa:df:72:0b:6f:f0:90:96:18:71:df:
+         76:1d:8c:f1:d5:c0:4f:ab:38:1a:eb:e6:a1:dd:1d:dc:60:d4:
+         da:7f:40:db:17:fc:4a:56:65:3a:86:60:83:87:b3:f6:3b:a8:
+         85:ac:2b:14:c2:26:77:8f:ee:a4:6f:11:f2:27:08:3f:bf:86:
+         4a:e3:bd:ef:6b:51:ec:72:a7:51:08:47:16:f8:d3:d7:b1:8d:
+         a1:b1:ca:d3:cd:fd:56:0a:2c:2f:62:27:8c:e1:ff:88:83:ff:
+         83:ab:87:70
 -----BEGIN CERTIFICATE-----
-MIIC4TCCAcmgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRSBS
-b290IENBMB4XDTE2MDEwNTAwMDAwMFoXDTI2MDEwMjAwMDAwMFowDzENMAsGA1UE
-AwwEQyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIhqtJn7PWV
-nskA8u6DJmw8MNSoeN0KpdaB8FQl3o+aDo9cBpawg7cTVjOe0Wp9RUDY5SEdxW0x
-NG9FIs9vAbT4bM5w0OkO7QTZNHqR22+QlGaVJgspJkxsi+MToUIpWaAs/oOlPD3o
-Mqw3p66yedMSmF/H/UxJa+QyQHZ7eK6hYbEK0VzzlhNflVqiNcVjGyUFjTwI0LAo
-KvP2NKulzeeCLDU4i/VBbHEyxBNn75uPMqt82uFqkktbnjl+awD4jeKzO60vET+A
-1RkOzNTBIUJGQi3QXq5j0Qo+ZvvrC5vk/nrKQ1zMmGrh/TIYTGNMzZibvvpbLcR2
-zI3lbaq7WjcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNBlT
-2doRsf8ANSs3AJEfkcD3LgowDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUA
-A4IBAQBXbRxEQFSh5Tyg4eHQckFhk5E4ZYvMNdlMBIASSv2EcZ8GT94GHA2TUbIt
-18j1DU/9FFie0sKsXb/3Z19oLaLPEoZ5JnARLT8MX2X8RP1uh15WOty+2pXiRaoH
-KP9GHku/A5KEU5vJet3nXulXuhjCIxImJ3S2k0RMHmriIGLlM9uGFEF+fHZa5dF/
-/PT5oyPJBuzLtWIevHsccFel0x3WD3lq8gVYYxGR+7REarKXGM/u3l2s1Nhj4k9C
-JfpEpEex5Pd/VaDg9wn4Q1xUH2rkh5aRoItyV1NSIjHRJtRfOEMXKkiRN7bY0rNU
-/PdhTsa8OYni2DzA1FAzC949AnBd
+MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDUwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
+FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
+O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
+l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
+wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
+BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAEM1CMyq+BCfnvqrJNzG5poj
+UslMgTO6ZLKGqCn0H1r6WsSRVhbR+YSWiYysH7bqL8sS9JLtO4UJ6/N6Lgk57O4J
+S/qGPmJADldyB976U0WsQBwNC0pnmvc5zjNe0BcLioOuM2+WwPB6rAc2xYap25Oq
+Lvpx0Rrdgir4HDAquX0p+nVidnwVFXWveGx8U64ugBQNC+sPsW3633ILb/CQlhhx
+33YdjPHVwE+rOBrr5qHdHdxg1Np/QNsX/EpWZTqGYIOHs/Y7qIWsKxTCJneP7qRv
+EfInCD+/hkrjve9rUexyp1EIRxb409exjaGxytPN/VYKLC9iJ4zh/4iD/4Orh3A=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-D-by-D.pem b/net/data/ssl/certificates/multi-root-D-by-D.pem
index e9a1c0fe..3030167 100644
--- a/net/data/ssl/certificates/multi-root-D-by-D.pem
+++ b/net/data/ssl/certificates/multi-root-D-by-D.pem
@@ -2,73 +2,74 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=D Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=D Root CA - Multi-root
         Validity
             Not Before: Jan  2 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=D Root CA
+        Subject: CN=D Root CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:e4:63:48:86:4d:1f:34:4d:c9:b2:f3:14:af:d3:
-                    ec:68:bd:ac:b6:ac:e4:11:fd:81:d3:4c:7c:dd:03:
-                    d7:4e:44:30:9d:53:7a:4d:cf:25:29:ef:b5:f5:83:
-                    b3:30:10:3b:97:f2:63:8c:40:41:fd:18:88:81:c5:
-                    53:26:90:f7:77:b1:01:5f:d7:7a:04:73:85:9a:b3:
-                    e8:6e:40:7b:6a:2b:1c:b4:0f:52:83:ad:08:cb:58:
-                    c2:71:87:85:b3:81:8c:21:88:aa:d5:4f:0b:84:c8:
-                    52:b0:cf:c4:cf:c7:72:8f:6a:2f:07:a2:2b:33:3d:
-                    6c:aa:00:1f:ef:c9:61:f6:58:8d:3a:8f:23:6b:75:
-                    a0:cf:86:9d:02:0f:ca:2b:d2:75:f3:b6:fe:14:26:
-                    31:d4:31:28:e4:d1:cf:f7:4d:12:58:d8:ac:f8:d3:
-                    f2:ae:d6:6e:72:dc:07:b8:d2:f2:76:0d:bf:a3:c1:
-                    18:63:58:55:84:4f:a5:82:d3:8f:17:8d:e1:0f:5a:
-                    9e:7f:69:01:4c:da:90:a1:33:b2:36:4f:91:3d:1f:
-                    0b:ea:8c:0d:ca:ff:e7:d1:0c:e0:ce:5b:54:6a:b9:
-                    ed:46:38:8c:80:d4:24:9c:71:48:23:80:61:b8:71:
-                    d4:8f:0d:96:b2:c1:f0:29:fc:c7:dd:9d:87:7a:f4:
-                    16:0d
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:cd:cf:d9:70:03:4f:4f:f1:9f:93:a1:2c:6e:cb:
+                    2f:20:d7:67:29:ce:99:02:4e:db:7d:6b:5e:6a:3a:
+                    a1:d2:7f:cd:f9:58:bd:34:fe:af:8d:8a:05:34:a2:
+                    67:16:ae:94:88:3b:77:3f:f2:a0:a5:46:2e:05:2e:
+                    b8:a7:2f:ff:e0:df:1d:b8:1e:31:6f:57:f9:aa:55:
+                    9c:83:aa:04:94:cd:e4:0f:99:f4:74:c1:38:8d:4c:
+                    90:67:ba:7e:92:42:59:ff:14:d6:4e:22:31:78:04:
+                    89:63:7d:84:fa:60:e7:d2:0d:61:0b:d8:a5:20:b3:
+                    8a:ce:f1:ef:b7:b0:b5:a6:81:d0:47:50:fb:5a:09:
+                    34:e1:a0:e3:6b:cf:e8:26:38:4d:cb:70:ae:4c:96:
+                    2c:9e:46:18:0c:e3:11:9f:8d:8a:65:c5:b1:03:5c:
+                    61:d9:35:a8:5d:29:08:7c:45:2e:38:13:dc:b0:72:
+                    a6:e6:29:04:85:6a:6d:fd:74:af:60:6c:24:51:e2:
+                    3a:58:38:c1:0f:b2:4e:ac:8e:63:81:36:01:9f:02:
+                    04:de:54:53:4c:fa:5f:67:44:db:f0:ed:ce:3f:f0:
+                    5b:e7:75:b3:72:d5:e8:76:9c:24:73:2b:0c:d9:7c:
+                    dd:85:a8:61:b9:42:d1:69:35:04:88:03:8a:c2:aa:
+                    10:cb
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                B4:73:D6:1A:33:13:BC:9C:23:5D:F6:4B:A2:29:BD:F8:DC:73:49:11
+                FA:45:82:63:D1:67:F2:93:F4:6A:6B:44:44:74:1A:D2:B0:CD:12:F6
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        6d:f2:9a:c2:eb:36:2b:45:ad:58:b5:59:68:e9:64:ad:75:18:
-        c0:73:b3:42:a4:ff:c3:25:02:f6:91:9b:a4:4d:0d:3d:49:3e:
-        d2:6b:c5:75:89:48:7b:fa:34:40:4d:06:4e:a6:cf:c5:3c:d5:
-        c2:a8:0e:77:2e:66:f1:fb:28:80:15:06:68:cb:9e:8e:27:1b:
-        22:02:9f:c2:6b:fc:48:b0:20:25:4b:32:6a:db:99:53:89:4e:
-        86:b7:a7:48:ed:1a:3a:f3:87:54:c6:e8:59:a3:95:49:31:39:
-        01:54:56:ee:a8:6a:ba:f2:34:30:e1:75:84:1a:a6:4e:14:e0:
-        25:58:8a:88:dc:2a:58:1e:22:c6:00:62:57:6d:d8:c3:2e:a6:
-        19:05:8f:b9:b9:f3:e9:3e:39:4f:0a:1a:cc:59:ca:b6:89:29:
-        59:b3:ad:92:86:8f:c0:ba:7d:7f:55:27:c6:db:aa:b0:0c:45:
-        73:cc:18:6e:4d:0e:16:61:ad:d9:96:b6:d5:3e:29:e1:59:8c:
-        4e:c9:6c:7a:63:0b:9b:37:0d:d6:31:bf:8c:90:33:97:60:f5:
-        3b:24:1a:ad:eb:d0:8b:3c:0f:1c:0a:52:4b:83:ec:35:96:c6:
-        bb:67:3b:d7:19:78:dc:49:25:c8:b2:44:f5:26:e7:5d:35:4f:
-        6a:bd:00:0f
+         ac:1c:7c:de:1a:4a:31:54:77:c5:94:7d:6a:0b:9d:c2:c9:d4:
+         3b:2d:71:e4:99:df:ca:02:5c:a0:1c:1c:22:7d:f2:a5:0e:97:
+         7c:91:20:12:c5:b7:f5:56:15:8c:1b:44:b2:32:94:8b:e5:b1:
+         c0:0b:f6:c0:b8:b4:cf:b9:27:d8:49:52:fc:81:9f:48:2a:08:
+         b8:94:a1:3f:78:fe:20:66:f5:ed:3f:61:f6:f7:23:5c:4c:36:
+         49:48:10:07:de:40:62:eb:3b:bb:6b:4b:8e:e4:a7:b3:75:33:
+         2f:4d:11:58:76:1e:1c:d9:b9:dc:1c:33:da:82:2b:5f:fc:51:
+         f1:26:35:7d:5e:eb:67:ba:da:2c:f2:d7:6e:88:b6:a1:34:ed:
+         07:d2:a5:e4:ac:d6:9b:7c:6c:6e:77:aa:11:4e:d0:60:fa:86:
+         94:a0:74:00:60:8b:1c:0b:3e:5d:05:c9:b9:8c:b4:6f:a5:e7:
+         82:c0:6a:ef:60:73:de:1f:74:20:aa:67:c7:d9:c2:81:c7:4c:
+         d7:c9:57:e4:7d:db:80:bd:7d:4f:39:a4:77:d3:2e:65:79:87:
+         ae:05:f7:9c:28:ed:e8:4e:f6:ac:38:3f:8f:36:bb:ae:5e:42:
+         71:d5:a9:5b:a7:df:42:9f:6b:e0:ec:3e:3b:6e:36:11:9b:34:
+         a8:66:ff:d5
 -----BEGIN CERTIFICATE-----
-MIIC5jCCAc6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRCBS
-b290IENBMB4XDTE2MDEwMjAwMDAwMFoXDTI2MDEwMjAwMDAwMFowFDESMBAGA1UE
-AwwJRCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5GNI
-hk0fNE3JsvMUr9PsaL2stqzkEf2B00x83QPXTkQwnVN6Tc8lKe+19YOzMBA7l/Jj
-jEBB/RiIgcVTJpD3d7EBX9d6BHOFmrPobkB7aisctA9Sg60Iy1jCcYeFs4GMIYiq
-1U8LhMhSsM/Ez8dyj2ovB6IrMz1sqgAf78lh9liNOo8ja3Wgz4adAg/KK9J187b+
-FCYx1DEo5NHP900SWNis+NPyrtZuctwHuNLydg2/o8EYY1hVhE+lgtOPF43hD1qe
-f2kBTNqQoTOyNk+RPR8L6owNyv/n0QzgzltUarntRjiMgNQknHFII4BhuHHUjw2W
-ssHwKfzH3Z2HevQWDQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBS0c9YaMxO8nCNd9kuiKb343HNJETAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcN
-AQELBQADggEBAG3ymsLrNitFrVi1WWjpZK11GMBzs0Kk/8MlAvaRm6RNDT1JPtJr
-xXWJSHv6NEBNBk6mz8U81cKoDncuZvH7KIAVBmjLno4nGyICn8Jr/EiwICVLMmrb
-mVOJToa3p0jtGjrzh1TG6FmjlUkxOQFUVu6oarryNDDhdYQapk4U4CVYiojcKlge
-IsYAYldt2MMuphkFj7m58+k+OU8KGsxZyraJKVmzrZKGj8C6fX9VJ8bbqrAMRXPM
-GG5NDhZhrdmWttU+KeFZjE7JbHpjC5s3DdYxv4yQM5dg9TskGq3r0Is8DxwKUkuD
-7DWWxrtnO9cZeNxJJciyRPUm5101T2q9AA8=
+MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMCExHzAdBgNVBAMMFkQgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNz9lwA09P8Z+ToSxuyy8g12cpzpkCTtt9
+a15qOqHSf835WL00/q+NigU0omcWrpSIO3c/8qClRi4FLrinL//g3x24HjFvV/mq
+VZyDqgSUzeQPmfR0wTiNTJBnun6SQln/FNZOIjF4BIljfYT6YOfSDWEL2KUgs4rO
+8e+3sLWmgdBHUPtaCTThoONrz+gmOE3LcK5MliyeRhgM4xGfjYplxbEDXGHZNahd
+KQh8RS44E9ywcqbmKQSFam39dK9gbCRR4jpYOMEPsk6sjmOBNgGfAgTeVFNM+l9n
+RNvw7c4/8FvndbNy1eh2nCRzKwzZfN2FqGG5QtFpNQSIA4rCqhDLAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPpFgmPRZ/KT9GprRER0GtKwzRL2
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEArBx83hpKMVR3xZR9
+agudwsnUOy1x5JnfygJcoBwcIn3ypQ6XfJEgEsW39VYVjBtEsjKUi+WxwAv2wLi0
+z7kn2ElS/IGfSCoIuJShP3j+IGb17T9h9vcjXEw2SUgQB95AYus7u2tLjuSns3Uz
+L00RWHYeHNm53Bwz2oIrX/xR8SY1fV7rZ7raLPLXboi2oTTtB9Kl5KzWm3xsbneq
+EU7QYPqGlKB0AGCLHAs+XQXJuYy0b6XngsBq72Bz3h90IKpnx9nCgcdM18lX5H3b
+gL19Tzmkd9MuZXmHrgX3nCjt6E72rDg/jza7rl5CcdWpW6ffQp9r4Ow+O242EZs0
+qGb/1Q==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-E-by-E.pem b/net/data/ssl/certificates/multi-root-E-by-E.pem
index d37206fe..15632dd 100644
--- a/net/data/ssl/certificates/multi-root-E-by-E.pem
+++ b/net/data/ssl/certificates/multi-root-E-by-E.pem
@@ -2,73 +2,74 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=E Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=E Root CA - Multi-root
         Validity
             Not Before: Jan  2 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=E Root CA
+        Subject: CN=E Root CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:a4:35:79:08:1a:d9:5a:a6:12:69:98:d6:3f:c7:
-                    fb:31:f6:f1:d6:a4:1b:f3:6a:fb:36:51:04:f1:9d:
-                    3b:94:81:77:35:7d:62:75:b4:b4:04:69:df:44:49:
-                    fc:43:d5:a4:14:af:67:d0:fb:51:21:2b:8b:dc:8c:
-                    89:d1:0b:08:26:17:3d:75:10:08:6f:ba:a4:24:8b:
-                    7e:c3:fa:3d:ab:fb:f6:f5:14:80:f7:9a:45:00:b2:
-                    84:12:e2:7d:c0:b7:40:ca:6f:06:1e:d2:3c:10:6f:
-                    11:f0:52:a2:16:ef:52:91:09:6f:89:28:cf:70:fc:
-                    e7:9e:1c:4b:5d:88:08:2f:2c:9e:75:c6:b9:6b:25:
-                    68:05:01:98:f2:28:53:7d:be:a1:5f:3a:62:0b:4a:
-                    c4:95:17:97:d0:4a:5d:8a:5f:52:07:7a:6a:8b:81:
-                    41:a2:60:08:92:e8:d0:c2:c8:9c:19:b2:3c:c3:c6:
-                    33:7d:5d:90:a6:0b:d3:ca:7b:8b:6f:70:aa:bb:d1:
-                    90:81:6c:db:b8:48:f8:52:d1:47:32:ed:66:9e:67:
-                    dd:e6:bc:9e:5d:60:33:9f:07:d8:b6:3e:d2:48:f5:
-                    a8:4c:12:6f:19:32:32:a7:66:0c:66:00:79:9f:dc:
-                    91:e4:54:bb:ff:b5:22:ad:0c:5f:f7:5d:d6:1a:f0:
-                    82:59
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b5:60:cb:b4:84:ab:6c:ba:59:52:a9:4c:6a:85:
+                    41:f2:41:17:49:40:3f:3e:e8:70:5c:05:df:dd:64:
+                    9e:fc:be:fb:38:ef:5d:67:ab:0e:de:9c:ea:ad:91:
+                    e1:f4:db:8b:f4:c0:e6:d0:ad:e2:83:15:01:aa:49:
+                    42:97:ae:72:7b:78:e3:20:4e:7e:29:ee:b5:35:6b:
+                    c4:af:d4:54:b0:86:2f:a9:09:a7:3b:8c:05:9e:fd:
+                    b4:b8:1f:3a:aa:d5:b5:d2:91:0f:50:e9:d2:1e:62:
+                    1c:c1:30:07:41:aa:bd:c2:11:3f:cc:c8:0f:a9:7e:
+                    81:69:52:96:86:2a:07:63:7b:f0:23:9e:db:27:88:
+                    8c:dc:aa:8c:66:dd:35:3a:08:60:37:36:41:34:f5:
+                    48:69:23:1a:5b:18:a7:ec:df:68:0a:3c:19:fb:92:
+                    b7:fa:53:9b:f3:70:b6:0d:4c:cb:2f:b7:0e:7e:5f:
+                    94:8c:a3:71:66:09:be:0d:af:db:52:f6:82:3f:88:
+                    64:72:cc:19:79:f4:7b:4d:6e:50:dc:93:88:d5:29:
+                    8a:e1:c8:1f:32:71:9f:d9:0e:14:31:f8:94:11:23:
+                    b1:bf:64:eb:27:3a:64:fb:77:ee:40:8c:a7:03:ed:
+                    1d:ec:8f:ee:25:58:f0:26:91:3c:f8:28:a1:7a:45:
+                    9f:13
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                B7:51:AA:C9:B7:3E:03:E5:11:94:49:A2:26:0F:70:81:7B:4E:7A:A7
+                51:68:BC:D9:1B:1D:7F:8E:0D:4A:33:39:2D:A4:1F:14:29:92:70:8E
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        6b:32:6f:7f:a4:6c:9c:21:a9:95:ab:b6:2a:50:59:72:36:1a:
-        ad:86:c4:4e:2f:a2:0a:81:47:b1:37:ed:94:5a:e3:c3:ec:43:
-        46:2b:39:6c:66:ba:61:74:44:a4:e6:f6:63:6c:98:4b:d1:01:
-        74:93:77:81:fe:92:5c:4a:bf:a4:d2:0b:aa:c8:00:7b:df:74:
-        75:6e:d7:1a:7d:3b:f4:07:99:bb:04:63:93:97:9f:1d:b0:f0:
-        81:23:94:70:8b:c6:c1:24:c1:05:01:80:c6:4e:cc:ec:7f:05:
-        c8:93:c4:9b:57:bb:ac:8e:b6:7f:ed:41:e6:49:2d:1b:bb:ec:
-        74:47:ce:63:57:a2:e9:42:b5:f6:73:8d:f5:64:a5:53:f0:86:
-        4b:34:29:80:0b:63:16:c6:98:af:d6:cb:17:52:8e:75:fc:95:
-        03:ca:03:1d:a8:d3:83:f4:32:94:b1:6d:2e:f0:1c:87:81:b5:
-        6a:f0:19:20:76:62:e1:da:39:9c:f7:ee:d3:f7:d3:14:39:89:
-        a2:a9:eb:2f:8e:e6:0f:70:e5:63:d1:43:ff:d8:f0:68:13:55:
-        c5:02:ab:f9:a5:d8:ae:7f:4c:c5:e4:1b:c2:ba:4a:e9:d7:d3:
-        6e:69:80:39:d0:ad:0c:9d:2a:e6:6c:e6:e9:f7:49:eb:4b:4d:
-        73:0d:d5:51
+         2d:d4:56:d9:90:bb:62:64:66:78:6d:cd:73:26:cc:42:ce:37:
+         f4:bf:e8:8f:e7:1e:00:cb:c2:bd:54:33:0b:a8:e2:04:e1:5f:
+         59:2a:1a:41:70:0f:d6:32:5f:d0:14:86:fa:e2:a7:19:29:49:
+         77:56:b9:d7:e6:eb:39:61:e4:25:67:22:eb:f8:46:86:b7:6b:
+         7d:44:01:0b:18:cb:ba:e5:af:76:ab:c6:fe:43:6c:d8:f6:33:
+         f7:86:0b:22:da:27:78:91:07:55:3f:b2:c5:1e:10:88:09:b3:
+         cf:22:c6:7e:8f:c6:d0:c5:ec:67:90:72:8b:2b:c4:46:81:2c:
+         82:d1:5c:57:4e:d5:af:c4:d2:d8:b2:a7:91:1a:42:b3:57:bc:
+         4e:81:5e:cf:91:af:da:f1:53:29:de:31:6b:d3:69:a4:4d:a9:
+         14:15:96:51:7d:0d:bd:28:11:03:71:d2:85:11:92:1d:96:1a:
+         12:33:0c:4b:cf:c4:40:19:fb:eb:6a:fe:9b:e7:2d:cd:f7:75:
+         a3:66:4e:a6:7d:8e:8c:2e:5d:b8:2c:a8:5e:d7:42:1b:97:00:
+         ba:12:41:8c:9b:f1:ed:91:49:63:5a:11:0d:e4:7d:f0:dc:36:
+         23:0b:1b:e8:5f:be:1f:6d:a7:aa:bb:30:76:e2:36:b2:5a:68:
+         80:f5:75:7e
 -----BEGIN CERTIFICATE-----
-MIIC5jCCAc6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRSBS
-b290IENBMB4XDTE2MDEwMjAwMDAwMFoXDTI2MDEwMjAwMDAwMFowFDESMBAGA1UE
-AwwJRSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApDV5
-CBrZWqYSaZjWP8f7Mfbx1qQb82r7NlEE8Z07lIF3NX1idbS0BGnfREn8Q9WkFK9n
-0PtRISuL3IyJ0QsIJhc9dRAIb7qkJIt+w/o9q/v29RSA95pFALKEEuJ9wLdAym8G
-HtI8EG8R8FKiFu9SkQlviSjPcPznnhxLXYgILyyedca5ayVoBQGY8ihTfb6hXzpi
-C0rElReX0Epdil9SB3pqi4FBomAIkujQwsicGbI8w8YzfV2QpgvTynuLb3Cqu9GQ
-gWzbuEj4UtFHMu1mnmfd5ryeXWAznwfYtj7SSPWoTBJvGTIyp2YMZgB5n9yR5FS7
-/7UirQxf913WGvCCWQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBS3UarJtz4D5RGUSaImD3CBe056pzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcN
-AQELBQADggEBAGsyb3+kbJwhqZWrtipQWXI2Gq2GxE4vogqBR7E37ZRa48PsQ0Yr
-OWxmumF0RKTm9mNsmEvRAXSTd4H+klxKv6TSC6rIAHvfdHVu1xp9O/QHmbsEY5OX
-nx2w8IEjlHCLxsEkwQUBgMZOzOx/BciTxJtXu6yOtn/tQeZJLRu77HRHzmNXoulC
-tfZzjfVkpVPwhks0KYALYxbGmK/WyxdSjnX8lQPKAx2o04P0MpSxbS7wHIeBtWrw
-GSB2YuHaOZz37tP30xQ5iaKp6y+O5g9w5WPRQ//Y8GgTVcUCq/ml2K5/TMXkG8K6
-SunX025pgDnQrQydKuZs5un3SetLTXMN1VE=
+MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMCExHzAdBgNVBAMMFkUgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1YMu0hKtsullSqUxqhUHyQRdJQD8+6HBc
+Bd/dZJ78vvs4711nqw7enOqtkeH024v0wObQreKDFQGqSUKXrnJ7eOMgTn4p7rU1
+a8Sv1FSwhi+pCac7jAWe/bS4Hzqq1bXSkQ9Q6dIeYhzBMAdBqr3CET/MyA+pfoFp
+UpaGKgdje/AjntsniIzcqoxm3TU6CGA3NkE09UhpIxpbGKfs32gKPBn7krf6U5vz
+cLYNTMsvtw5+X5SMo3FmCb4Nr9tS9oI/iGRyzBl59HtNblDck4jVKYrhyB8ycZ/Z
+DhQx+JQRI7G/ZOsnOmT7d+5AjKcD7R3sj+4lWPAmkTz4KKF6RZ8TAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFFovNkbHX+ODUozOS2kHxQpknCO
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEALdRW2ZC7YmRmeG3N
+cybMQs439L/oj+ceAMvCvVQzC6jiBOFfWSoaQXAP1jJf0BSG+uKnGSlJd1a51+br
+OWHkJWci6/hGhrdrfUQBCxjLuuWvdqvG/kNs2PYz94YLItoneJEHVT+yxR4QiAmz
+zyLGfo/G0MXsZ5ByiyvERoEsgtFcV07Vr8TS2LKnkRpCs1e8ToFez5Gv2vFTKd4x
+a9NppE2pFBWWUX0NvSgRA3HShRGSHZYaEjMMS8/EQBn762r+m+ctzfd1o2ZOpn2O
+jC5duCyoXtdCG5cAuhJBjJvx7ZFJY1oRDeR98Nw2Iwsb6F++H22nqrswduI2slpo
+gPV1fg==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-F-by-E.pem b/net/data/ssl/certificates/multi-root-F-by-E.pem
index 571a69f5..86b2bae 100644
--- a/net/data/ssl/certificates/multi-root-F-by-E.pem
+++ b/net/data/ssl/certificates/multi-root-F-by-E.pem
@@ -2,73 +2,73 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4098 (0x1002)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=E Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=E Root CA - Multi-root
         Validity
             Not Before: Jan  2 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=F CA
+        Subject: CN=F CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:9c:03:f6:3a:b6:1a:2e:f6:31:c6:97:e8:e8:47:
-                    d2:ed:cf:b1:1d:89:05:55:fe:3a:3c:ca:33:83:c5:
-                    cb:b2:fc:fc:cc:53:98:f4:9a:a1:51:eb:11:5b:74:
-                    6b:d0:1c:b7:59:8f:ba:34:0b:17:9e:43:70:70:c1:
-                    d8:d6:da:31:27:03:81:44:38:3f:b1:34:b8:98:85:
-                    e9:ef:10:05:9d:03:cc:4a:52:af:01:0e:19:02:c4:
-                    89:9a:0c:69:e3:2d:fc:47:12:1e:17:c0:cb:5e:aa:
-                    dd:e1:7f:8b:8f:9e:25:e1:74:4c:bf:90:2b:5e:23:
-                    85:95:11:67:ab:22:87:ac:d1:69:ab:df:96:90:4b:
-                    d4:5a:57:1b:be:23:c5:c6:45:17:48:87:36:8b:ba:
-                    a4:ce:b4:a8:1f:28:9e:b8:4e:c7:86:37:17:90:2a:
-                    02:87:d0:ac:45:e6:ad:32:e3:6c:b9:e2:be:b8:60:
-                    c0:cb:65:e8:b6:59:54:f0:1a:47:76:f2:c0:2c:5c:
-                    bf:2f:76:05:85:90:e4:ab:3b:ea:98:04:70:1d:60:
-                    cf:d1:8b:3d:68:51:aa:8e:d4:3f:b5:fa:db:61:4d:
-                    f8:f8:d9:d7:17:3f:14:2e:6d:af:76:8f:4f:cd:7b:
-                    15:65:34:34:b7:24:51:9f:89:a9:eb:f0:09:cc:3a:
-                    23:b1
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:9d:41:79:88:93:ab:fe:e6:52:28:84:91:9d:c2:
+                    85:a0:2c:97:39:69:25:20:43:85:8c:db:64:8f:41:
+                    f4:b5:25:e6:3e:16:41:fa:40:b7:6c:2c:fc:11:76:
+                    7d:86:b7:47:73:68:ae:e9:2c:7e:5d:8b:21:68:86:
+                    71:11:cd:21:f9:16:a0:20:67:ac:79:40:d0:94:e6:
+                    bf:a2:dd:65:af:da:d3:c5:23:82:0a:a2:1c:a7:bc:
+                    7d:f0:c2:a8:0b:30:ca:20:d6:31:5f:28:c8:74:4b:
+                    09:1e:50:de:d4:51:d9:9c:f5:3d:fe:b0:8d:ee:11:
+                    f2:22:3e:11:09:53:23:77:52:5c:cf:8d:dd:6c:3b:
+                    c4:39:1b:33:c2:00:bc:34:2d:e6:dc:9d:af:e8:36:
+                    ec:ac:c7:e4:73:09:44:ad:59:8d:51:c1:ee:11:60:
+                    5b:b5:c9:d8:cb:48:b0:f9:0a:57:38:d8:e3:be:c5:
+                    4e:38:7e:47:3f:24:66:a1:11:3d:2d:9f:ca:4a:dc:
+                    59:58:fd:cc:56:22:c7:d5:c9:70:2f:ec:66:81:4d:
+                    ee:48:39:97:ef:dd:b6:02:34:b2:90:db:16:a4:60:
+                    9d:18:de:95:87:a1:14:6e:19:ab:88:42:37:57:cf:
+                    20:c4:d8:e3:c6:24:8d:bc:fd:4d:d2:4e:74:06:4a:
+                    c4:3b
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                6C:C0:28:78:3E:A8:BE:06:4C:85:97:F7:D6:F1:AE:44:39:E4:C1:79
+                CA:CF:14:CE:08:5C:4B:71:AD:DE:DA:70:78:A9:D1:D6:7F:25:76:E4
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        45:04:40:0e:a4:a0:6f:35:52:58:b8:b3:70:7f:a4:b5:2d:e0:
-        74:d3:59:93:7a:0a:a4:a4:ee:f9:2e:c3:7f:d0:52:4a:d2:58:
-        9d:22:17:73:3f:e0:6b:a6:2b:ee:11:01:1e:d3:4b:e4:cd:b1:
-        51:fe:c2:0a:60:17:4c:86:e8:9b:62:29:93:97:9a:bf:7b:8b:
-        d2:f6:11:14:68:d2:d4:59:bf:15:03:98:e4:e6:31:b8:8f:aa:
-        b5:98:db:fa:a5:84:54:69:15:80:70:db:43:fd:45:76:19:1d:
-        d5:e5:fc:ff:b0:a4:5d:ed:b1:3a:ac:21:44:5a:00:b8:a1:dc:
-        88:f4:96:82:f1:04:06:5a:16:7d:c9:49:1a:62:92:a4:03:28:
-        32:95:2d:9f:ed:9e:4c:5c:22:5f:dd:7f:1f:90:fc:a4:fd:a3:
-        9c:3b:45:70:eb:f5:29:40:c1:9d:73:86:14:6d:40:70:e5:94:
-        d8:55:79:78:b2:e4:82:61:c7:a2:3d:49:86:23:f5:4e:e9:8b:
-        22:1d:1e:7e:83:3f:f3:d5:ab:f5:91:cd:bd:8c:3f:ef:28:de:
-        66:19:c2:39:68:e9:30:4a:43:2e:d0:c9:50:fb:f1:56:4d:c5:
-        ad:46:e6:db:80:3e:b8:f4:5f:c1:55:9d:de:aa:72:ab:db:65:
-        71:a9:78:47
+         31:f4:da:87:3f:e3:55:1a:c6:e4:fc:71:23:9e:51:de:88:89:
+         f2:c7:b3:7c:8b:f7:c1:71:3a:bc:bd:ff:61:43:2a:3b:4c:6c:
+         2c:eb:7c:f6:00:37:e1:0a:fc:2f:01:73:73:d7:b9:b8:dc:fa:
+         6e:10:fc:55:2b:d6:d3:95:09:27:de:97:28:d5:b6:48:19:a5:
+         0b:13:d3:29:cf:80:86:36:39:41:c1:15:17:74:8c:d7:2f:f6:
+         00:63:06:cb:cb:74:9b:2e:35:1c:b7:d8:38:db:a4:d2:63:c0:
+         f1:97:db:be:1d:10:bc:3b:67:59:99:0d:3e:5f:2d:52:38:ca:
+         80:49:6f:b4:f3:e5:0a:d4:b3:96:ef:45:9c:a4:15:35:af:9c:
+         04:fd:5a:22:0f:44:67:32:0e:79:47:37:87:fb:3c:fb:2f:0a:
+         1d:b3:20:cd:f5:fe:71:f6:c8:f1:0e:f2:ed:8d:a4:8c:c3:af:
+         a0:ce:8e:49:a8:af:ec:55:2c:17:4f:03:7e:6a:a9:ff:ae:46:
+         25:89:0c:54:d7:32:7b:9b:8f:a2:df:ac:44:a8:03:cc:56:9e:
+         d6:cb:f6:af:c9:e4:f8:de:68:4d:0c:11:20:ac:5b:d2:e8:07:
+         b2:29:6f:27:b5:29:a8:fa:09:9d:f1:a1:f7:2c:72:05:07:7d:
+         31:1e:98:d4
 -----BEGIN CERTIFICATE-----
-MIIC4TCCAcmgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRSBS
-b290IENBMB4XDTE2MDEwMjAwMDAwMFoXDTI2MDEwMjAwMDAwMFowDzENMAsGA1UE
-AwwERiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJwD9jq2Gi72
-McaX6OhH0u3PsR2JBVX+OjzKM4PFy7L8/MxTmPSaoVHrEVt0a9Act1mPujQLF55D
-cHDB2NbaMScDgUQ4P7E0uJiF6e8QBZ0DzEpSrwEOGQLEiZoMaeMt/EcSHhfAy16q
-3eF/i4+eJeF0TL+QK14jhZURZ6sih6zRaavflpBL1FpXG74jxcZFF0iHNou6pM60
-qB8onrhOx4Y3F5AqAofQrEXmrTLjbLnivrhgwMtl6LZZVPAaR3bywCxcvy92BYWQ
-5Ks76pgEcB1gz9GLPWhRqo7UP7X622FN+PjZ1xc/FC5tr3aPT817FWU0NLckUZ+J
-qevwCcw6I7ECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUbMAo
-eD6ovgZMhZf31vGuRDnkwXkwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUA
-A4IBAQBFBEAOpKBvNVJYuLNwf6S1LeB001mTegqkpO75LsN/0FJK0lidIhdzP+Br
-pivuEQEe00vkzbFR/sIKYBdMhuibYimTl5q/e4vS9hEUaNLUWb8VA5jk5jG4j6q1
-mNv6pYRUaRWAcNtD/UV2GR3V5fz/sKRd7bE6rCFEWgC4odyI9JaC8QQGWhZ9yUka
-YpKkAygylS2f7Z5MXCJf3X8fkPyk/aOcO0Vw6/UpQMGdc4YUbUBw5ZTYVXl4suSC
-YceiPUmGI/VO6YsiHR5+gz/z1av1kc29jD/vKN5mGcI5aOkwSkMu0MlQ+/FWTcWt
-RubbgD649F/BVZ3eqnKr22VxqXhH
+MIIC+zCCAeOgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMBwxGjAYBgNVBAMMEUYgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAnUF5iJOr/uZSKISRncKFoCyXOWklIEOFjNtkj0H0
+tSXmPhZB+kC3bCz8EXZ9hrdHc2iu6Sx+XYshaIZxEc0h+RagIGeseUDQlOa/ot1l
+r9rTxSOCCqIcp7x98MKoCzDKINYxXyjIdEsJHlDe1FHZnPU9/rCN7hHyIj4RCVMj
+d1Jcz43dbDvEORszwgC8NC3m3J2v6DbsrMfkcwlErVmNUcHuEWBbtcnYy0iw+QpX
+ONjjvsVOOH5HPyRmoRE9LZ/KStxZWP3MViLH1clwL+xmgU3uSDmX7922AjSykNsW
+pGCdGN6Vh6EUbhmriEI3V88gxNjjxiSNvP1N0k50BkrEOwIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTKzxTOCFxLca3e2nB4qdHWfyV25DAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBADH02oc/41UaxuT8cSOeUd6I
+ifLHs3yL98FxOry9/2FDKjtMbCzrfPYAN+EK/C8Bc3PXubjc+m4Q/FUr1tOVCSfe
+lyjVtkgZpQsT0ynPgIY2OUHBFRd0jNcv9gBjBsvLdJsuNRy32DjbpNJjwPGX274d
+ELw7Z1mZDT5fLVI4yoBJb7Tz5QrUs5bvRZykFTWvnAT9WiIPRGcyDnlHN4f7PPsv
+Ch2zIM31/nH2yPEO8u2NpIzDr6DOjkmor+xVLBdPA35qqf+uRiWJDFTXMnubj6Lf
+rESoA8xWntbL9q/J5PjeaE0MESCsW9LoB7Ipbye1Kaj6CZ3xofcscgUHfTEemNQ=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-chain1.pem b/net/data/ssl/certificates/multi-root-chain1.pem
index fada15f..9861944b 100644
--- a/net/data/ssl/certificates/multi-root-chain1.pem
+++ b/net/data/ssl/certificates/multi-root-chain1.pem
@@ -2,300 +2,302 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=B CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=B CA - Multi-root
         Validity
-            Not Before: Feb  8 23:34:58 2016 GMT
-            Not After : Feb  5 23:34:58 2026 GMT
+            Not Before: Mar 11 01:37:16 2016 GMT
+            Not After : Mar  9 01:37:16 2026 GMT
         Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:ca:6c:3d:d6:ef:e6:c8:d4:a3:a8:52:e1:f8:5d:
-                    f7:4e:77:ac:a3:64:6f:8b:d4:3e:cd:18:8c:39:f2:
-                    10:64:f7:f3:61:1a:ce:8f:d8:32:1a:c1:f6:88:51:
-                    0a:12:07:d5:88:5c:f5:45:56:d0:9f:87:17:78:de:
-                    4d:d0:fd:fa:61:81:ef:a0:6b:38:02:3b:3d:8a:4e:
-                    1f:25:74:f0:05:c3:1b:10:f3:a4:52:6d:68:83:af:
-                    83:69:16:54:d4:f9:42:82:98:9e:92:4c:82:33:34:
-                    29:b1:2f:60:d3:f2:00:3a:d6:9b:20:cc:27:57:be:
-                    da:29:b4:74:f7:aa:f6:f0:5a:45:0e:85:da:02:d4:
-                    c1:96:81:26:a0:a4:77:a5:54:b4:24:7a:f5:9f:e6:
-                    08:42:ac:d8:ac:00:f7:fc:8a:43:0d:c9:b6:b7:a3:
-                    4d:e6:50:d9:33:fa:18:28:b2:77:dd:a3:f5:fa:30:
-                    32:f9:bf:25:2c:97:91:1f:69:26:5c:1e:e9:2b:24:
-                    26:5d:90:91:b1:8e:5c:07:2a:bc:39:a4:07:b6:28:
-                    84:dd:75:87:20:50:13:ab:b4:3c:51:23:e5:d7:ea:
-                    89:f2:a9:fd:da:87:b0:d2:9a:14:20:ae:cf:f9:16:
-                    1b:78:b8:a2:94:50:2f:86:4c:20:27:08:d0:44:80:
-                    a3:79
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c8:27:1c:19:81:c0:a7:30:93:03:1c:f8:21:b8:
+                    2f:8a:22:b4:89:0f:da:b1:40:95:df:dc:46:53:fc:
+                    6f:36:26:66:5a:53:6d:45:78:c2:39:16:9a:3f:82:
+                    8b:ba:c5:b0:78:a8:18:bc:d5:a7:92:a5:e6:ac:e2:
+                    0c:81:d0:94:e5:0c:ec:5e:03:0c:17:c5:35:2a:7b:
+                    ab:86:eb:bf:e8:62:0a:8f:b0:25:b2:70:f5:11:8c:
+                    16:4f:c1:76:44:e5:75:e8:93:4f:e9:e7:c4:e4:42:
+                    0a:08:be:73:2c:cb:8f:73:6a:40:77:eb:33:60:ac:
+                    be:c5:27:fd:b1:4f:88:4b:15:af:98:fd:32:53:ae:
+                    b0:2a:0c:b2:f5:05:f3:3a:06:0d:6e:5c:fe:83:fc:
+                    e3:60:ae:99:8e:a1:21:c2:72:02:e6:f4:49:57:e6:
+                    91:31:2e:be:92:a1:ad:f8:71:31:64:74:10:33:d0:
+                    a7:0c:ed:18:c7:b2:50:71:fc:b9:b6:ae:95:a0:8d:
+                    ac:1f:3c:d5:79:a7:a9:88:50:b6:02:cd:68:60:24:
+                    45:9b:b6:e9:82:08:d9:9c:d4:7e:29:7d:2b:d9:ae:
+                    57:7f:62:6a:56:96:8b:4a:33:9e:5f:93:82:b0:d1:
+                    05:03:26:cd:15:f4:87:7f:6a:9a:df:e9:01:b5:d4:
+                    c9:11
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:FALSE
             X509v3 Subject Key Identifier: 
-                78:36:93:58:1F:73:7C:93:CA:AE:BB:9A:4E:A7:37:F1:83:03:4B:CF
+                FB:91:A9:5F:BC:27:81:98:55:30:BF:57:32:4D:B9:DA:56:DD:52:2C
             X509v3 Authority Key Identifier: 
-                keyid:0D:AF:BC:C3:31:09:C6:9D:F8:44:D2:51:E8:13:FF:24:78:9D:83:76
+                keyid:90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
 
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-        5e:87:35:21:15:89:4e:ac:9a:8e:db:d2:dc:83:6e:9e:64:b9:
-        30:f8:91:f7:9f:c4:de:b4:92:bf:05:4a:1b:e3:12:0f:b0:0d:
-        d8:8f:fd:f9:e6:e8:2c:24:e0:88:cc:58:5d:3b:a3:23:95:86:
-        b2:1f:0f:fb:02:95:c4:16:04:24:05:bb:65:e4:48:80:6e:64:
-        33:ed:a0:71:7d:21:f5:6f:70:72:07:54:b2:e7:79:98:8d:b5:
-        2b:0d:68:8e:3a:be:e3:91:f8:6a:60:d1:51:20:08:83:43:18:
-        5a:49:e2:66:21:aa:df:d2:b1:90:96:5a:99:6f:64:a0:96:7f:
-        e5:9b:3f:82:d5:42:8c:7d:fa:9f:b1:62:6c:e6:42:f6:1d:ab:
-        aa:e2:a4:05:33:99:4e:67:18:46:14:16:23:b8:46:db:d1:28:
-        a3:2c:2a:97:32:c3:02:e8:a0:9f:4f:e9:e6:c9:7e:c8:63:0d:
-        ff:de:95:f4:4d:f0:ca:57:49:9a:07:4b:5a:13:96:bc:49:10:
-        5c:3c:92:ce:1e:dd:10:d6:dc:6b:07:f0:ae:3e:0c:d0:05:1f:
-        00:08:79:0c:2a:e5:03:96:7d:1e:cb:3f:b7:f6:30:07:39:66:
-        8b:9a:b4:80:1c:e2:d2:7d:e8:bc:91:26:c5:9a:ec:a1:25:26:
-        56:0a:7b:39
+         b9:31:7a:95:b2:ba:3a:b4:f1:16:76:df:eb:d5:b9:af:67:b1:
+         9d:8a:27:04:9b:61:6f:42:3f:c2:b3:cd:65:c4:86:cb:90:fb:
+         9d:3a:ed:fc:b8:74:da:d7:6a:6c:2f:17:68:d1:73:58:f1:a2:
+         bb:8f:d6:b0:a8:7f:b6:a8:b0:74:d1:ea:c4:62:ed:bc:1e:ef:
+         02:6b:d5:e8:2d:15:78:16:1e:90:fa:f4:29:5a:a8:43:ad:d2:
+         58:40:b4:1c:60:4e:cd:bc:6f:1a:39:e4:46:b2:58:93:96:5a:
+         a8:a4:c4:31:73:ed:89:c4:81:27:e1:4c:66:20:7c:27:c4:f9:
+         61:ff:d1:d5:a5:02:93:4c:06:fa:15:33:7a:1f:5f:eb:29:b2:
+         b5:6a:cd:7e:d6:d7:b7:51:a7:01:2f:22:9f:9e:7e:81:98:c4:
+         72:11:36:2c:e7:c6:d0:f0:7d:98:36:ea:b7:a0:aa:13:8f:6e:
+         ae:41:59:9b:e6:c9:bc:9c:e8:93:f5:0c:4e:ca:b4:dd:e3:01:
+         fe:23:6e:fb:fa:b3:61:66:58:f5:fc:07:16:1d:a9:52:ec:a0:
+         29:61:a4:39:ed:41:50:a3:a2:33:72:0e:3c:03:e1:0a:1a:1a:
+         cf:22:73:09:d7:ea:e8:15:fc:73:3c:d4:4e:34:6c:b4:18:94:
+         c4:d3:6e:12
 -----BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD
-QTAeFw0xNjAyMDgyMzM0NThaFw0yNjAyMDUyMzM0NThaMGAxCzAJBgNVBAYTAlVT
-MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAw
-DgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQDKbD3W7+bI1KOoUuH4XfdOd6yjZG+L1D7NGIw5
-8hBk9/NhGs6P2DIawfaIUQoSB9WIXPVFVtCfhxd43k3Q/fphge+gazgCOz2KTh8l
-dPAFwxsQ86RSbWiDr4NpFlTU+UKCmJ6STIIzNCmxL2DT8gA61psgzCdXvtoptHT3
-qvbwWkUOhdoC1MGWgSagpHelVLQkevWf5ghCrNisAPf8ikMNyba3o03mUNkz+hgo
-snfdo/X6MDL5vyUsl5EfaSZcHukrJCZdkJGxjlwHKrw5pAe2KITddYcgUBOrtDxR
-I+XX6onyqf3ah7DSmhQgrs/5Fht4uKKUUC+GTCAnCNBEgKN5AgMBAAGjbzBtMAwG
-A1UdEwEB/wQCMAAwHQYDVR0OBBYEFHg2k1gfc3yTyq67mk6nN/GDA0vPMB8GA1Ud
-IwQYMBaAFA2vvMMxCcad+ETSUegT/yR4nYN2MB0GA1UdJQQWMBQGCCsGAQUFBwMB
-BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAXoc1IRWJTqyajtvS3INunmS5
-MPiR95/E3rSSvwVKG+MSD7AN2I/9+eboLCTgiMxYXTujI5WGsh8P+wKVxBYEJAW7
-ZeRIgG5kM+2gcX0h9W9wcgdUsud5mI21Kw1ojjq+45H4amDRUSAIg0MYWkniZiGq
-39KxkJZamW9koJZ/5Zs/gtVCjH36n7FibOZC9h2rquKkBTOZTmcYRhQWI7hG29Eo
-oywqlzLDAuign0/p5sl+yGMN/96V9E3wyldJmgdLWhOWvEkQXDySzh7dENbcawfw
-rj4M0AUfAAh5DCrlA5Z9Hss/t/YwBzlmi5q0gBzi0n3ovJEmxZrsoSUmVgp7OQ==
+MIIDZzCCAk+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
+QSAtIE11bHRpLXJvb3QwHhcNMTYwMzExMDEzNzE2WhcNMjYwMzA5MDEzNzE2WjBg
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4x
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCccGYHApzCTAxz4Ibgv
+iiK0iQ/asUCV39xGU/xvNiZmWlNtRXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU
+5QzsXgMMF8U1Knurhuu/6GIKj7AlsnD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuP
+c2pAd+szYKy+xSf9sU+ISxWvmP0yU66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC
+5vRJV+aRMS6+kqGt+HExZHQQM9CnDO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1o
+YCRFm7bpggjZnNR+KX0r2a5Xf2JqVpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJ
+EQIDAQABo28wbTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBT7kalfvCeBmFUwv1cy
+TbnaVt1SLDAfBgNVHSMEGDAWgBSQy1PuNgpasJM4yRG3rP0ncZncgTAdBgNVHSUE
+FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBALkxepWy
+ujq08RZ23+vVua9nsZ2KJwSbYW9CP8KzzWXEhsuQ+5067fy4dNrXamwvF2jRc1jx
+oruP1rCof7aosHTR6sRi7bwe7wJr1egtFXgWHpD69ClaqEOt0lhAtBxgTs28bxo5
+5EayWJOWWqikxDFz7YnEgSfhTGYgfCfE+WH/0dWlApNMBvoVM3ofX+spsrVqzX7W
+17dRpwEvIp+efoGYxHIRNiznxtDwfZg26regqhOPbq5BWZvmybyc6JP1DE7KtN3j
+Af4jbvv6s2FmWPX8BxYdqVLsoClhpDntQVCjojNyDjwD4QoaGs8icwnX6ugV/HM8
+1E40bLQYlMTTbhI=
 -----END CERTIFICATE-----
 Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=C CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=C CA - Multi-root
         Validity
             Not Before: Jan  4 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=B CA
+        Subject: CN=B CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:a2:a0:93:17:1e:ee:f0:fb:87:1f:71:ca:6b:b9:
-                    bd:2d:67:38:2a:24:c7:c3:c2:88:4d:ca:f2:50:33:
-                    60:1d:6f:61:a5:61:02:a4:a7:76:2b:89:43:78:a7:
-                    0a:27:04:dc:a5:5b:6e:a8:4c:29:f2:25:c6:c0:32:
-                    20:e0:01:8d:a1:16:15:c9:b5:d8:17:7d:e0:e8:90:
-                    89:a3:f5:96:1f:90:c6:e3:10:1a:f9:f5:6a:d5:41:
-                    ce:cd:a8:fc:36:77:2f:a2:d7:8e:39:50:36:65:4d:
-                    a7:83:6c:e1:a4:cc:f6:6b:c0:7b:c8:98:f4:01:3f:
-                    94:d3:d6:11:1d:b3:ef:95:c8:ea:07:d9:5e:fd:82:
-                    4f:23:4d:08:89:fb:68:2d:82:12:98:e0:87:f2:7a:
-                    c7:76:98:4c:ca:1d:3e:e8:bc:72:dd:b0:b7:41:84:
-                    6e:39:cd:a9:35:e8:ee:2a:d1:54:cd:21:ed:6f:a4:
-                    ab:e9:d8:c9:d2:e9:11:66:66:78:33:ae:d8:78:75:
-                    ac:1e:ad:0e:23:82:35:13:96:ed:eb:3e:58:eb:27:
-                    fb:1b:fd:27:6e:f0:c3:ff:88:cc:cc:63:35:23:3d:
-                    ce:4d:2e:2d:dc:b3:91:8e:d8:d8:5b:6a:92:28:c5:
-                    e9:a4:02:76:34:e0:6d:41:61:43:71:e1:59:b3:c2:
-                    ce:f7
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
+                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
+                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
+                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
+                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
+                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
+                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
+                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
+                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
+                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
+                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
+                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
+                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
+                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
+                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
+                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
+                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
+                    34:69
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                0D:AF:BC:C3:31:09:C6:9D:F8:44:D2:51:E8:13:FF:24:78:9D:83:76
+                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        28:52:54:55:5c:5b:4f:af:4c:66:cc:c3:71:dd:3e:60:48:76:
-        c3:f0:c0:40:30:f6:44:06:73:2f:c5:b1:1c:6a:e9:6f:fd:92:
-        8d:40:38:eb:46:de:58:cd:68:0f:cd:7f:28:a2:79:29:92:ae:
-        68:f2:ba:0a:f1:e6:17:58:a4:3b:ee:61:6c:d6:5d:2a:07:61:
-        b0:31:c9:9b:dc:08:32:b8:d8:ac:14:9c:1a:ec:21:7d:46:63:
-        75:67:46:36:ec:25:f0:e6:ed:3f:5d:b7:fd:06:67:46:80:a0:
-        b9:a8:25:e7:05:0a:f9:a7:20:48:d4:71:b4:3f:0b:1c:4d:f4:
-        73:8b:cc:9f:67:cf:36:43:e2:82:d5:d5:4e:4c:71:74:5c:db:
-        ba:35:bf:1e:9e:63:46:d0:c7:b9:f4:2a:92:23:c7:59:af:5d:
-        b1:24:7c:ff:1c:08:0d:2a:50:79:57:1c:a2:45:38:a5:3e:d7:
-        c8:5c:91:f2:69:70:d1:47:4a:55:bc:84:dc:9b:9f:ae:f2:94:
-        1c:22:65:11:4c:7c:e1:3c:ae:d4:e6:11:fc:3f:d8:53:6b:65:
-        4a:7c:44:bf:91:bd:b0:3e:df:b5:f5:c5:8e:1f:a5:19:83:2a:
-        8d:4e:13:3d:58:45:8e:11:b6:9e:96:7a:7a:6e:0b:e5:1a:66:
-        7a:00:0e:75
+         97:cd:ae:5a:26:f4:25:f6:c0:8b:08:d8:df:82:35:d8:76:f3:
+         5d:cc:99:bd:ac:70:c9:41:e0:24:c8:fd:e6:4e:41:2c:d4:69:
+         8d:08:25:fd:f3:32:3a:58:0b:d3:58:9c:81:51:bf:97:a4:bc:
+         00:18:1c:4f:1c:54:04:63:e3:72:87:f4:dc:9e:7b:dc:da:5d:
+         e1:ef:59:6b:f0:1f:3d:0c:11:55:1e:9a:1a:d8:8d:bc:7b:18:
+         b7:4f:92:1c:68:73:82:ec:f3:69:48:0a:86:40:4a:a5:6f:ae:
+         8f:10:2e:12:0b:e8:7e:b9:bc:d7:26:f0:cf:f4:0f:5b:77:f2:
+         ff:77:28:b4:5f:5e:ef:65:08:21:b8:f9:1e:56:b9:69:3b:c4:
+         7f:01:88:c9:7c:ca:d0:e2:df:e5:5e:8d:e9:2e:7d:4a:78:04:
+         8b:c1:dc:d4:58:ac:90:fc:5c:8e:48:2b:60:99:63:37:3f:e5:
+         61:da:8f:58:9f:4d:0a:ee:6c:8d:bc:1f:7e:c4:be:0f:32:4b:
+         11:7a:28:bf:dd:d0:a0:40:42:a8:43:4d:0b:2f:01:0e:73:de:
+         1b:a6:df:49:57:58:89:57:c0:23:76:83:f0:9a:0e:83:d9:9b:
+         cb:eb:ac:3f:89:d1:e8:3c:3e:f1:d5:80:0c:38:18:02:5c:5f:
+         e5:68:5e:cf
 -----BEGIN CERTIFICATE-----
-MIIC3DCCAcSgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQyBD
-QTAeFw0xNjAxMDQwMDAwMDBaFw0yNjAxMDIwMDAwMDBaMA8xDTALBgNVBAMMBEIg
-Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCioJMXHu7w+4cfccpr
-ub0tZzgqJMfDwohNyvJQM2Adb2GlYQKkp3YriUN4pwonBNylW26oTCnyJcbAMiDg
-AY2hFhXJtdgXfeDokImj9ZYfkMbjEBr59WrVQc7NqPw2dy+i1445UDZlTaeDbOGk
-zPZrwHvImPQBP5TT1hEds++VyOoH2V79gk8jTQiJ+2gtghKY4Ifyesd2mEzKHT7o
-vHLdsLdBhG45zak16O4q0VTNIe1vpKvp2MnS6RFmZngzrth4dawerQ4jgjUTlu3r
-PljrJ/sb/Sdu8MP/iMzMYzUjPc5NLi3cs5GO2NhbapIoxemkAnY04G1BYUNx4Vmz
-ws73AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA2vvMMxCcad
-+ETSUegT/yR4nYN2MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
-KFJUVVxbT69MZszDcd0+YEh2w/DAQDD2RAZzL8WxHGrpb/2SjUA460beWM1oD81/
-KKJ5KZKuaPK6CvHmF1ikO+5hbNZdKgdhsDHJm9wIMrjYrBScGuwhfUZjdWdGNuwl
-8ObtP123/QZnRoCguagl5wUK+acgSNRxtD8LHE30c4vMn2fPNkPigtXVTkxxdFzb
-ujW/Hp5jRtDHufQqkiPHWa9dsSR8/xwIDSpQeVccokU4pT7XyFyR8mlw0UdKVbyE
-3JufrvKUHCJlEUx84Tyu1OYR/D/YU2tlSnxEv5G9sD7ftfXFjh+lGYMqjU4TPVhF
-jhG2npZ6em4L5RpmegAOdQ==
+MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQyBD
+QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA0MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
+MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
+HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
+dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
+jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
+CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
+vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCXza5aJvQl9sCLCNjfgjXYdvNdzJm9
+rHDJQeAkyP3mTkEs1GmNCCX98zI6WAvTWJyBUb+XpLwAGBxPHFQEY+Nyh/Tcnnvc
+2l3h71lr8B89DBFVHpoa2I28exi3T5IcaHOC7PNpSAqGQEqlb66PEC4SC+h+ubzX
+JvDP9A9bd/L/dyi0X17vZQghuPkeVrlpO8R/AYjJfMrQ4t/lXo3pLn1KeASLwdzU
+WKyQ/FyOSCtgmWM3P+Vh2o9Yn00K7myNvB9+xL4PMksReii/3dCgQEKoQ00LLwEO
+c94bpt9JV1iJV8AjdoPwmg6D2ZvL66w/idHoPD7x1YAMOBgCXF/laF7P
 -----END CERTIFICATE-----
 Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 4097 (0x1001)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=D Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=D Root CA - Multi-root
         Validity
             Not Before: Jan  3 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=C CA
+        Subject: CN=C CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:c2:21:aa:d2:67:ec:f5:95:9e:c9:00:f2:ee:83:
-                    26:6c:3c:30:d4:a8:78:dd:0a:a5:d6:81:f0:54:25:
-                    de:8f:9a:0e:8f:5c:06:96:b0:83:b7:13:56:33:9e:
-                    d1:6a:7d:45:40:d8:e5:21:1d:c5:6d:31:34:6f:45:
-                    22:cf:6f:01:b4:f8:6c:ce:70:d0:e9:0e:ed:04:d9:
-                    34:7a:91:db:6f:90:94:66:95:26:0b:29:26:4c:6c:
-                    8b:e3:13:a1:42:29:59:a0:2c:fe:83:a5:3c:3d:e8:
-                    32:ac:37:a7:ae:b2:79:d3:12:98:5f:c7:fd:4c:49:
-                    6b:e4:32:40:76:7b:78:ae:a1:61:b1:0a:d1:5c:f3:
-                    96:13:5f:95:5a:a2:35:c5:63:1b:25:05:8d:3c:08:
-                    d0:b0:28:2a:f3:f6:34:ab:a5:cd:e7:82:2c:35:38:
-                    8b:f5:41:6c:71:32:c4:13:67:ef:9b:8f:32:ab:7c:
-                    da:e1:6a:92:4b:5b:9e:39:7e:6b:00:f8:8d:e2:b3:
-                    3b:ad:2f:11:3f:80:d5:19:0e:cc:d4:c1:21:42:46:
-                    42:2d:d0:5e:ae:63:d1:0a:3e:66:fb:eb:0b:9b:e4:
-                    fe:7a:ca:43:5c:cc:98:6a:e1:fd:32:18:4c:63:4c:
-                    cd:98:9b:be:fa:5b:2d:c4:76:cc:8d:e5:6d:aa:bb:
-                    5a:37
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
+                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
+                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
+                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
+                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
+                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
+                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
+                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
+                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
+                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
+                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
+                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
+                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
+                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
+                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
+                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
+                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
+                    4b:11
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                34:19:53:D9:DA:11:B1:FF:00:35:2B:37:00:91:1F:91:C0:F7:2E:0A
+                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        5a:aa:0a:cb:92:8a:cd:ca:49:b4:5e:34:32:46:0a:9e:fd:71:
-        30:dd:af:b8:9a:6c:82:87:59:27:ed:df:11:1f:13:fa:c9:d9:
-        fb:8a:e8:ba:7c:67:33:7e:ea:42:f3:1c:34:91:5c:5f:ed:68:
-        d7:dc:06:8d:6a:75:38:42:4f:eb:52:55:84:c6:74:9d:53:87:
-        d6:34:64:19:19:4c:6d:b7:3a:f9:e8:8a:14:4d:00:ec:07:71:
-        00:6c:05:80:94:4b:4f:e7:a4:db:26:ee:e1:2b:98:d6:ad:ca:
-        32:ab:d6:3a:23:83:30:e8:33:82:82:7d:a5:1e:00:97:be:a8:
-        0f:68:d7:ae:8a:4a:52:be:d7:b5:0a:49:4d:a8:f1:25:e3:de:
-        41:37:6a:53:1c:b5:0e:b0:fd:b6:db:25:b6:a2:cb:ff:d8:7f:
-        98:30:84:15:f0:27:b5:fd:a3:71:35:ad:4c:83:8c:d1:da:49:
-        a5:97:b3:7d:80:6f:03:40:fe:a3:22:38:58:70:6d:43:01:63:
-        db:fb:ca:b6:5f:fc:f0:45:b3:57:5a:a6:cc:b9:d0:99:a8:f6:
-        a4:4f:c6:20:a5:6e:dd:e0:3b:e7:b2:0a:8b:6f:4d:6f:67:57:
-        e7:c4:58:80:26:5d:1d:27:f9:3e:22:ed:00:bc:fa:8d:8d:eb:
-        bb:ab:91:a9
+         67:11:95:f4:b9:cb:47:e6:50:da:fd:a0:13:78:d7:e1:be:59:
+         ec:86:32:e5:56:3e:9b:8f:db:b0:3b:93:fb:d0:6e:b3:de:7e:
+         10:5b:b4:30:f7:02:e8:3f:ff:4e:91:3a:e8:b8:4a:94:5e:14:
+         7b:f8:84:e5:1f:63:2c:b4:7f:4f:ee:b1:d5:ee:92:79:7d:63:
+         87:a0:e9:57:14:57:11:59:18:54:8b:e3:d1:51:80:a7:2f:51:
+         f2:6f:43:d2:87:e1:59:23:2c:fe:83:38:e1:25:da:b5:34:af:
+         33:17:64:80:08:b6:bd:5f:92:05:2c:81:b0:c3:d3:80:cd:e1:
+         5c:95:d2:ea:1e:d3:af:d9:93:c2:f4:23:ae:51:b0:a4:82:49:
+         2d:ec:fe:d1:18:e3:a3:53:9f:63:4b:38:dc:54:25:ce:4c:90:
+         37:02:e4:67:41:31:ba:7a:13:1a:68:1e:ed:34:0c:3d:66:ba:
+         a3:3a:71:76:5f:5f:89:a1:cd:95:50:f6:5d:1f:c0:91:31:93:
+         5b:58:af:e7:9b:21:e6:57:b1:f4:d7:dd:c1:84:25:5b:83:f7:
+         5f:c9:89:17:5b:6f:54:f2:8b:ed:47:de:27:57:9e:e9:8c:b3:
+         58:2c:c2:77:25:e1:eb:22:06:d1:f6:c5:f4:d7:1a:3d:00:1c:
+         2e:85:e9:70
 -----BEGIN CERTIFICATE-----
-MIIC4TCCAcmgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRCBS
-b290IENBMB4XDTE2MDEwMzAwMDAwMFoXDTI2MDEwMjAwMDAwMFowDzENMAsGA1UE
-AwwEQyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIhqtJn7PWV
-nskA8u6DJmw8MNSoeN0KpdaB8FQl3o+aDo9cBpawg7cTVjOe0Wp9RUDY5SEdxW0x
-NG9FIs9vAbT4bM5w0OkO7QTZNHqR22+QlGaVJgspJkxsi+MToUIpWaAs/oOlPD3o
-Mqw3p66yedMSmF/H/UxJa+QyQHZ7eK6hYbEK0VzzlhNflVqiNcVjGyUFjTwI0LAo
-KvP2NKulzeeCLDU4i/VBbHEyxBNn75uPMqt82uFqkktbnjl+awD4jeKzO60vET+A
-1RkOzNTBIUJGQi3QXq5j0Qo+ZvvrC5vk/nrKQ1zMmGrh/TIYTGNMzZibvvpbLcR2
-zI3lbaq7WjcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNBlT
-2doRsf8ANSs3AJEfkcD3LgowDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUA
-A4IBAQBaqgrLkorNykm0XjQyRgqe/XEw3a+4mmyCh1kn7d8RHxP6ydn7iui6fGcz
-fupC8xw0kVxf7WjX3AaNanU4Qk/rUlWExnSdU4fWNGQZGUxttzr56IoUTQDsB3EA
-bAWAlEtP56TbJu7hK5jWrcoyq9Y6I4Mw6DOCgn2lHgCXvqgPaNeuikpSvte1CklN
-qPEl495BN2pTHLUOsP222yW2osv/2H+YMIQV8Ce1/aNxNa1Mg4zR2kmll7N9gG8D
-QP6jIjhYcG1DAWPb+8q2X/zwRbNXWqbMudCZqPakT8YgpW7d4DvnsgqLb01vZ1fn
-xFiAJl0dJ/k+Iu0AvPqNjeu7q5Gp
+MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDMwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
+FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
+O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
+l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
+wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
+BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAGcRlfS5y0fmUNr9oBN41+G+
+WeyGMuVWPpuP27A7k/vQbrPefhBbtDD3Aug//06ROui4SpReFHv4hOUfYyy0f0/u
+sdXuknl9Y4eg6VcUVxFZGFSL49FRgKcvUfJvQ9KH4VkjLP6DOOEl2rU0rzMXZIAI
+tr1fkgUsgbDD04DN4VyV0uoe06/Zk8L0I65RsKSCSS3s/tEY46NTn2NLONxUJc5M
+kDcC5GdBMbp6ExpoHu00DD1muqM6cXZfX4mhzZVQ9l0fwJExk1tYr+ebIeZXsfTX
+3cGEJVuD91/JiRdbb1Tyi+1H3idXnumMs1gswncl4esiBtH2xfTXGj0AHC6F6XA=
 -----END CERTIFICATE-----
 Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=D Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=D Root CA - Multi-root
         Validity
             Not Before: Jan  2 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=D Root CA
+        Subject: CN=D Root CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:e4:63:48:86:4d:1f:34:4d:c9:b2:f3:14:af:d3:
-                    ec:68:bd:ac:b6:ac:e4:11:fd:81:d3:4c:7c:dd:03:
-                    d7:4e:44:30:9d:53:7a:4d:cf:25:29:ef:b5:f5:83:
-                    b3:30:10:3b:97:f2:63:8c:40:41:fd:18:88:81:c5:
-                    53:26:90:f7:77:b1:01:5f:d7:7a:04:73:85:9a:b3:
-                    e8:6e:40:7b:6a:2b:1c:b4:0f:52:83:ad:08:cb:58:
-                    c2:71:87:85:b3:81:8c:21:88:aa:d5:4f:0b:84:c8:
-                    52:b0:cf:c4:cf:c7:72:8f:6a:2f:07:a2:2b:33:3d:
-                    6c:aa:00:1f:ef:c9:61:f6:58:8d:3a:8f:23:6b:75:
-                    a0:cf:86:9d:02:0f:ca:2b:d2:75:f3:b6:fe:14:26:
-                    31:d4:31:28:e4:d1:cf:f7:4d:12:58:d8:ac:f8:d3:
-                    f2:ae:d6:6e:72:dc:07:b8:d2:f2:76:0d:bf:a3:c1:
-                    18:63:58:55:84:4f:a5:82:d3:8f:17:8d:e1:0f:5a:
-                    9e:7f:69:01:4c:da:90:a1:33:b2:36:4f:91:3d:1f:
-                    0b:ea:8c:0d:ca:ff:e7:d1:0c:e0:ce:5b:54:6a:b9:
-                    ed:46:38:8c:80:d4:24:9c:71:48:23:80:61:b8:71:
-                    d4:8f:0d:96:b2:c1:f0:29:fc:c7:dd:9d:87:7a:f4:
-                    16:0d
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:cd:cf:d9:70:03:4f:4f:f1:9f:93:a1:2c:6e:cb:
+                    2f:20:d7:67:29:ce:99:02:4e:db:7d:6b:5e:6a:3a:
+                    a1:d2:7f:cd:f9:58:bd:34:fe:af:8d:8a:05:34:a2:
+                    67:16:ae:94:88:3b:77:3f:f2:a0:a5:46:2e:05:2e:
+                    b8:a7:2f:ff:e0:df:1d:b8:1e:31:6f:57:f9:aa:55:
+                    9c:83:aa:04:94:cd:e4:0f:99:f4:74:c1:38:8d:4c:
+                    90:67:ba:7e:92:42:59:ff:14:d6:4e:22:31:78:04:
+                    89:63:7d:84:fa:60:e7:d2:0d:61:0b:d8:a5:20:b3:
+                    8a:ce:f1:ef:b7:b0:b5:a6:81:d0:47:50:fb:5a:09:
+                    34:e1:a0:e3:6b:cf:e8:26:38:4d:cb:70:ae:4c:96:
+                    2c:9e:46:18:0c:e3:11:9f:8d:8a:65:c5:b1:03:5c:
+                    61:d9:35:a8:5d:29:08:7c:45:2e:38:13:dc:b0:72:
+                    a6:e6:29:04:85:6a:6d:fd:74:af:60:6c:24:51:e2:
+                    3a:58:38:c1:0f:b2:4e:ac:8e:63:81:36:01:9f:02:
+                    04:de:54:53:4c:fa:5f:67:44:db:f0:ed:ce:3f:f0:
+                    5b:e7:75:b3:72:d5:e8:76:9c:24:73:2b:0c:d9:7c:
+                    dd:85:a8:61:b9:42:d1:69:35:04:88:03:8a:c2:aa:
+                    10:cb
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                B4:73:D6:1A:33:13:BC:9C:23:5D:F6:4B:A2:29:BD:F8:DC:73:49:11
+                FA:45:82:63:D1:67:F2:93:F4:6A:6B:44:44:74:1A:D2:B0:CD:12:F6
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        6d:f2:9a:c2:eb:36:2b:45:ad:58:b5:59:68:e9:64:ad:75:18:
-        c0:73:b3:42:a4:ff:c3:25:02:f6:91:9b:a4:4d:0d:3d:49:3e:
-        d2:6b:c5:75:89:48:7b:fa:34:40:4d:06:4e:a6:cf:c5:3c:d5:
-        c2:a8:0e:77:2e:66:f1:fb:28:80:15:06:68:cb:9e:8e:27:1b:
-        22:02:9f:c2:6b:fc:48:b0:20:25:4b:32:6a:db:99:53:89:4e:
-        86:b7:a7:48:ed:1a:3a:f3:87:54:c6:e8:59:a3:95:49:31:39:
-        01:54:56:ee:a8:6a:ba:f2:34:30:e1:75:84:1a:a6:4e:14:e0:
-        25:58:8a:88:dc:2a:58:1e:22:c6:00:62:57:6d:d8:c3:2e:a6:
-        19:05:8f:b9:b9:f3:e9:3e:39:4f:0a:1a:cc:59:ca:b6:89:29:
-        59:b3:ad:92:86:8f:c0:ba:7d:7f:55:27:c6:db:aa:b0:0c:45:
-        73:cc:18:6e:4d:0e:16:61:ad:d9:96:b6:d5:3e:29:e1:59:8c:
-        4e:c9:6c:7a:63:0b:9b:37:0d:d6:31:bf:8c:90:33:97:60:f5:
-        3b:24:1a:ad:eb:d0:8b:3c:0f:1c:0a:52:4b:83:ec:35:96:c6:
-        bb:67:3b:d7:19:78:dc:49:25:c8:b2:44:f5:26:e7:5d:35:4f:
-        6a:bd:00:0f
+         ac:1c:7c:de:1a:4a:31:54:77:c5:94:7d:6a:0b:9d:c2:c9:d4:
+         3b:2d:71:e4:99:df:ca:02:5c:a0:1c:1c:22:7d:f2:a5:0e:97:
+         7c:91:20:12:c5:b7:f5:56:15:8c:1b:44:b2:32:94:8b:e5:b1:
+         c0:0b:f6:c0:b8:b4:cf:b9:27:d8:49:52:fc:81:9f:48:2a:08:
+         b8:94:a1:3f:78:fe:20:66:f5:ed:3f:61:f6:f7:23:5c:4c:36:
+         49:48:10:07:de:40:62:eb:3b:bb:6b:4b:8e:e4:a7:b3:75:33:
+         2f:4d:11:58:76:1e:1c:d9:b9:dc:1c:33:da:82:2b:5f:fc:51:
+         f1:26:35:7d:5e:eb:67:ba:da:2c:f2:d7:6e:88:b6:a1:34:ed:
+         07:d2:a5:e4:ac:d6:9b:7c:6c:6e:77:aa:11:4e:d0:60:fa:86:
+         94:a0:74:00:60:8b:1c:0b:3e:5d:05:c9:b9:8c:b4:6f:a5:e7:
+         82:c0:6a:ef:60:73:de:1f:74:20:aa:67:c7:d9:c2:81:c7:4c:
+         d7:c9:57:e4:7d:db:80:bd:7d:4f:39:a4:77:d3:2e:65:79:87:
+         ae:05:f7:9c:28:ed:e8:4e:f6:ac:38:3f:8f:36:bb:ae:5e:42:
+         71:d5:a9:5b:a7:df:42:9f:6b:e0:ec:3e:3b:6e:36:11:9b:34:
+         a8:66:ff:d5
 -----BEGIN CERTIFICATE-----
-MIIC5jCCAc6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRCBS
-b290IENBMB4XDTE2MDEwMjAwMDAwMFoXDTI2MDEwMjAwMDAwMFowFDESMBAGA1UE
-AwwJRCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5GNI
-hk0fNE3JsvMUr9PsaL2stqzkEf2B00x83QPXTkQwnVN6Tc8lKe+19YOzMBA7l/Jj
-jEBB/RiIgcVTJpD3d7EBX9d6BHOFmrPobkB7aisctA9Sg60Iy1jCcYeFs4GMIYiq
-1U8LhMhSsM/Ez8dyj2ovB6IrMz1sqgAf78lh9liNOo8ja3Wgz4adAg/KK9J187b+
-FCYx1DEo5NHP900SWNis+NPyrtZuctwHuNLydg2/o8EYY1hVhE+lgtOPF43hD1qe
-f2kBTNqQoTOyNk+RPR8L6owNyv/n0QzgzltUarntRjiMgNQknHFII4BhuHHUjw2W
-ssHwKfzH3Z2HevQWDQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBS0c9YaMxO8nCNd9kuiKb343HNJETAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcN
-AQELBQADggEBAG3ymsLrNitFrVi1WWjpZK11GMBzs0Kk/8MlAvaRm6RNDT1JPtJr
-xXWJSHv6NEBNBk6mz8U81cKoDncuZvH7KIAVBmjLno4nGyICn8Jr/EiwICVLMmrb
-mVOJToa3p0jtGjrzh1TG6FmjlUkxOQFUVu6oarryNDDhdYQapk4U4CVYiojcKlge
-IsYAYldt2MMuphkFj7m58+k+OU8KGsxZyraJKVmzrZKGj8C6fX9VJ8bbqrAMRXPM
-GG5NDhZhrdmWttU+KeFZjE7JbHpjC5s3DdYxv4yQM5dg9TskGq3r0Is8DxwKUkuD
-7DWWxrtnO9cZeNxJJciyRPUm5101T2q9AA8=
+MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMCExHzAdBgNVBAMMFkQgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNz9lwA09P8Z+ToSxuyy8g12cpzpkCTtt9
+a15qOqHSf835WL00/q+NigU0omcWrpSIO3c/8qClRi4FLrinL//g3x24HjFvV/mq
+VZyDqgSUzeQPmfR0wTiNTJBnun6SQln/FNZOIjF4BIljfYT6YOfSDWEL2KUgs4rO
+8e+3sLWmgdBHUPtaCTThoONrz+gmOE3LcK5MliyeRhgM4xGfjYplxbEDXGHZNahd
+KQh8RS44E9ywcqbmKQSFam39dK9gbCRR4jpYOMEPsk6sjmOBNgGfAgTeVFNM+l9n
+RNvw7c4/8FvndbNy1eh2nCRzKwzZfN2FqGG5QtFpNQSIA4rCqhDLAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPpFgmPRZ/KT9GprRER0GtKwzRL2
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEArBx83hpKMVR3xZR9
+agudwsnUOy1x5JnfygJcoBwcIn3ypQ6XfJEgEsW39VYVjBtEsjKUi+WxwAv2wLi0
+z7kn2ElS/IGfSCoIuJShP3j+IGb17T9h9vcjXEw2SUgQB95AYus7u2tLjuSns3Uz
+L00RWHYeHNm53Bwz2oIrX/xR8SY1fV7rZ7raLPLXboi2oTTtB9Kl5KzWm3xsbneq
+EU7QYPqGlKB0AGCLHAs+XQXJuYy0b6XngsBq72Bz3h90IKpnx9nCgcdM18lX5H3b
+gL19Tzmkd9MuZXmHrgX3nCjt6E72rDg/jza7rl5CcdWpW6ffQp9r4Ow+O242EZs0
+qGb/1Q==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-chain2.pem b/net/data/ssl/certificates/multi-root-chain2.pem
index 7807e92..e7b91143 100644
--- a/net/data/ssl/certificates/multi-root-chain2.pem
+++ b/net/data/ssl/certificates/multi-root-chain2.pem
@@ -2,300 +2,302 @@
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=B CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=B CA - Multi-root
         Validity
-            Not Before: Feb  8 23:34:58 2016 GMT
-            Not After : Feb  5 23:34:58 2026 GMT
+            Not Before: Mar 11 01:37:16 2016 GMT
+            Not After : Mar  9 01:37:16 2026 GMT
         Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:ca:6c:3d:d6:ef:e6:c8:d4:a3:a8:52:e1:f8:5d:
-                    f7:4e:77:ac:a3:64:6f:8b:d4:3e:cd:18:8c:39:f2:
-                    10:64:f7:f3:61:1a:ce:8f:d8:32:1a:c1:f6:88:51:
-                    0a:12:07:d5:88:5c:f5:45:56:d0:9f:87:17:78:de:
-                    4d:d0:fd:fa:61:81:ef:a0:6b:38:02:3b:3d:8a:4e:
-                    1f:25:74:f0:05:c3:1b:10:f3:a4:52:6d:68:83:af:
-                    83:69:16:54:d4:f9:42:82:98:9e:92:4c:82:33:34:
-                    29:b1:2f:60:d3:f2:00:3a:d6:9b:20:cc:27:57:be:
-                    da:29:b4:74:f7:aa:f6:f0:5a:45:0e:85:da:02:d4:
-                    c1:96:81:26:a0:a4:77:a5:54:b4:24:7a:f5:9f:e6:
-                    08:42:ac:d8:ac:00:f7:fc:8a:43:0d:c9:b6:b7:a3:
-                    4d:e6:50:d9:33:fa:18:28:b2:77:dd:a3:f5:fa:30:
-                    32:f9:bf:25:2c:97:91:1f:69:26:5c:1e:e9:2b:24:
-                    26:5d:90:91:b1:8e:5c:07:2a:bc:39:a4:07:b6:28:
-                    84:dd:75:87:20:50:13:ab:b4:3c:51:23:e5:d7:ea:
-                    89:f2:a9:fd:da:87:b0:d2:9a:14:20:ae:cf:f9:16:
-                    1b:78:b8:a2:94:50:2f:86:4c:20:27:08:d0:44:80:
-                    a3:79
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c8:27:1c:19:81:c0:a7:30:93:03:1c:f8:21:b8:
+                    2f:8a:22:b4:89:0f:da:b1:40:95:df:dc:46:53:fc:
+                    6f:36:26:66:5a:53:6d:45:78:c2:39:16:9a:3f:82:
+                    8b:ba:c5:b0:78:a8:18:bc:d5:a7:92:a5:e6:ac:e2:
+                    0c:81:d0:94:e5:0c:ec:5e:03:0c:17:c5:35:2a:7b:
+                    ab:86:eb:bf:e8:62:0a:8f:b0:25:b2:70:f5:11:8c:
+                    16:4f:c1:76:44:e5:75:e8:93:4f:e9:e7:c4:e4:42:
+                    0a:08:be:73:2c:cb:8f:73:6a:40:77:eb:33:60:ac:
+                    be:c5:27:fd:b1:4f:88:4b:15:af:98:fd:32:53:ae:
+                    b0:2a:0c:b2:f5:05:f3:3a:06:0d:6e:5c:fe:83:fc:
+                    e3:60:ae:99:8e:a1:21:c2:72:02:e6:f4:49:57:e6:
+                    91:31:2e:be:92:a1:ad:f8:71:31:64:74:10:33:d0:
+                    a7:0c:ed:18:c7:b2:50:71:fc:b9:b6:ae:95:a0:8d:
+                    ac:1f:3c:d5:79:a7:a9:88:50:b6:02:cd:68:60:24:
+                    45:9b:b6:e9:82:08:d9:9c:d4:7e:29:7d:2b:d9:ae:
+                    57:7f:62:6a:56:96:8b:4a:33:9e:5f:93:82:b0:d1:
+                    05:03:26:cd:15:f4:87:7f:6a:9a:df:e9:01:b5:d4:
+                    c9:11
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:FALSE
             X509v3 Subject Key Identifier: 
-                78:36:93:58:1F:73:7C:93:CA:AE:BB:9A:4E:A7:37:F1:83:03:4B:CF
+                FB:91:A9:5F:BC:27:81:98:55:30:BF:57:32:4D:B9:DA:56:DD:52:2C
             X509v3 Authority Key Identifier: 
-                keyid:0D:AF:BC:C3:31:09:C6:9D:F8:44:D2:51:E8:13:FF:24:78:9D:83:76
+                keyid:90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
 
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-        5e:87:35:21:15:89:4e:ac:9a:8e:db:d2:dc:83:6e:9e:64:b9:
-        30:f8:91:f7:9f:c4:de:b4:92:bf:05:4a:1b:e3:12:0f:b0:0d:
-        d8:8f:fd:f9:e6:e8:2c:24:e0:88:cc:58:5d:3b:a3:23:95:86:
-        b2:1f:0f:fb:02:95:c4:16:04:24:05:bb:65:e4:48:80:6e:64:
-        33:ed:a0:71:7d:21:f5:6f:70:72:07:54:b2:e7:79:98:8d:b5:
-        2b:0d:68:8e:3a:be:e3:91:f8:6a:60:d1:51:20:08:83:43:18:
-        5a:49:e2:66:21:aa:df:d2:b1:90:96:5a:99:6f:64:a0:96:7f:
-        e5:9b:3f:82:d5:42:8c:7d:fa:9f:b1:62:6c:e6:42:f6:1d:ab:
-        aa:e2:a4:05:33:99:4e:67:18:46:14:16:23:b8:46:db:d1:28:
-        a3:2c:2a:97:32:c3:02:e8:a0:9f:4f:e9:e6:c9:7e:c8:63:0d:
-        ff:de:95:f4:4d:f0:ca:57:49:9a:07:4b:5a:13:96:bc:49:10:
-        5c:3c:92:ce:1e:dd:10:d6:dc:6b:07:f0:ae:3e:0c:d0:05:1f:
-        00:08:79:0c:2a:e5:03:96:7d:1e:cb:3f:b7:f6:30:07:39:66:
-        8b:9a:b4:80:1c:e2:d2:7d:e8:bc:91:26:c5:9a:ec:a1:25:26:
-        56:0a:7b:39
+         b9:31:7a:95:b2:ba:3a:b4:f1:16:76:df:eb:d5:b9:af:67:b1:
+         9d:8a:27:04:9b:61:6f:42:3f:c2:b3:cd:65:c4:86:cb:90:fb:
+         9d:3a:ed:fc:b8:74:da:d7:6a:6c:2f:17:68:d1:73:58:f1:a2:
+         bb:8f:d6:b0:a8:7f:b6:a8:b0:74:d1:ea:c4:62:ed:bc:1e:ef:
+         02:6b:d5:e8:2d:15:78:16:1e:90:fa:f4:29:5a:a8:43:ad:d2:
+         58:40:b4:1c:60:4e:cd:bc:6f:1a:39:e4:46:b2:58:93:96:5a:
+         a8:a4:c4:31:73:ed:89:c4:81:27:e1:4c:66:20:7c:27:c4:f9:
+         61:ff:d1:d5:a5:02:93:4c:06:fa:15:33:7a:1f:5f:eb:29:b2:
+         b5:6a:cd:7e:d6:d7:b7:51:a7:01:2f:22:9f:9e:7e:81:98:c4:
+         72:11:36:2c:e7:c6:d0:f0:7d:98:36:ea:b7:a0:aa:13:8f:6e:
+         ae:41:59:9b:e6:c9:bc:9c:e8:93:f5:0c:4e:ca:b4:dd:e3:01:
+         fe:23:6e:fb:fa:b3:61:66:58:f5:fc:07:16:1d:a9:52:ec:a0:
+         29:61:a4:39:ed:41:50:a3:a2:33:72:0e:3c:03:e1:0a:1a:1a:
+         cf:22:73:09:d7:ea:e8:15:fc:73:3c:d4:4e:34:6c:b4:18:94:
+         c4:d3:6e:12
 -----BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD
-QTAeFw0xNjAyMDgyMzM0NThaFw0yNjAyMDUyMzM0NThaMGAxCzAJBgNVBAYTAlVT
-MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAw
-DgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQDKbD3W7+bI1KOoUuH4XfdOd6yjZG+L1D7NGIw5
-8hBk9/NhGs6P2DIawfaIUQoSB9WIXPVFVtCfhxd43k3Q/fphge+gazgCOz2KTh8l
-dPAFwxsQ86RSbWiDr4NpFlTU+UKCmJ6STIIzNCmxL2DT8gA61psgzCdXvtoptHT3
-qvbwWkUOhdoC1MGWgSagpHelVLQkevWf5ghCrNisAPf8ikMNyba3o03mUNkz+hgo
-snfdo/X6MDL5vyUsl5EfaSZcHukrJCZdkJGxjlwHKrw5pAe2KITddYcgUBOrtDxR
-I+XX6onyqf3ah7DSmhQgrs/5Fht4uKKUUC+GTCAnCNBEgKN5AgMBAAGjbzBtMAwG
-A1UdEwEB/wQCMAAwHQYDVR0OBBYEFHg2k1gfc3yTyq67mk6nN/GDA0vPMB8GA1Ud
-IwQYMBaAFA2vvMMxCcad+ETSUegT/yR4nYN2MB0GA1UdJQQWMBQGCCsGAQUFBwMB
-BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAXoc1IRWJTqyajtvS3INunmS5
-MPiR95/E3rSSvwVKG+MSD7AN2I/9+eboLCTgiMxYXTujI5WGsh8P+wKVxBYEJAW7
-ZeRIgG5kM+2gcX0h9W9wcgdUsud5mI21Kw1ojjq+45H4amDRUSAIg0MYWkniZiGq
-39KxkJZamW9koJZ/5Zs/gtVCjH36n7FibOZC9h2rquKkBTOZTmcYRhQWI7hG29Eo
-oywqlzLDAuign0/p5sl+yGMN/96V9E3wyldJmgdLWhOWvEkQXDySzh7dENbcawfw
-rj4M0AUfAAh5DCrlA5Z9Hss/t/YwBzlmi5q0gBzi0n3ovJEmxZrsoSUmVgp7OQ==
+MIIDZzCCAk+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
+QSAtIE11bHRpLXJvb3QwHhcNMTYwMzExMDEzNzE2WhcNMjYwMzA5MDEzNzE2WjBg
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4x
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCccGYHApzCTAxz4Ibgv
+iiK0iQ/asUCV39xGU/xvNiZmWlNtRXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU
+5QzsXgMMF8U1Knurhuu/6GIKj7AlsnD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuP
+c2pAd+szYKy+xSf9sU+ISxWvmP0yU66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC
+5vRJV+aRMS6+kqGt+HExZHQQM9CnDO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1o
+YCRFm7bpggjZnNR+KX0r2a5Xf2JqVpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJ
+EQIDAQABo28wbTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBT7kalfvCeBmFUwv1cy
+TbnaVt1SLDAfBgNVHSMEGDAWgBSQy1PuNgpasJM4yRG3rP0ncZncgTAdBgNVHSUE
+FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBALkxepWy
+ujq08RZ23+vVua9nsZ2KJwSbYW9CP8KzzWXEhsuQ+5067fy4dNrXamwvF2jRc1jx
+oruP1rCof7aosHTR6sRi7bwe7wJr1egtFXgWHpD69ClaqEOt0lhAtBxgTs28bxo5
+5EayWJOWWqikxDFz7YnEgSfhTGYgfCfE+WH/0dWlApNMBvoVM3ofX+spsrVqzX7W
+17dRpwEvIp+efoGYxHIRNiznxtDwfZg26regqhOPbq5BWZvmybyc6JP1DE7KtN3j
+Af4jbvv6s2FmWPX8BxYdqVLsoClhpDntQVCjojNyDjwD4QoaGs8icwnX6ugV/HM8
+1E40bLQYlMTTbhI=
 -----END CERTIFICATE-----
 Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=C CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=C CA - Multi-root
         Validity
             Not Before: Jan  4 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=B CA
+        Subject: CN=B CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:a2:a0:93:17:1e:ee:f0:fb:87:1f:71:ca:6b:b9:
-                    bd:2d:67:38:2a:24:c7:c3:c2:88:4d:ca:f2:50:33:
-                    60:1d:6f:61:a5:61:02:a4:a7:76:2b:89:43:78:a7:
-                    0a:27:04:dc:a5:5b:6e:a8:4c:29:f2:25:c6:c0:32:
-                    20:e0:01:8d:a1:16:15:c9:b5:d8:17:7d:e0:e8:90:
-                    89:a3:f5:96:1f:90:c6:e3:10:1a:f9:f5:6a:d5:41:
-                    ce:cd:a8:fc:36:77:2f:a2:d7:8e:39:50:36:65:4d:
-                    a7:83:6c:e1:a4:cc:f6:6b:c0:7b:c8:98:f4:01:3f:
-                    94:d3:d6:11:1d:b3:ef:95:c8:ea:07:d9:5e:fd:82:
-                    4f:23:4d:08:89:fb:68:2d:82:12:98:e0:87:f2:7a:
-                    c7:76:98:4c:ca:1d:3e:e8:bc:72:dd:b0:b7:41:84:
-                    6e:39:cd:a9:35:e8:ee:2a:d1:54:cd:21:ed:6f:a4:
-                    ab:e9:d8:c9:d2:e9:11:66:66:78:33:ae:d8:78:75:
-                    ac:1e:ad:0e:23:82:35:13:96:ed:eb:3e:58:eb:27:
-                    fb:1b:fd:27:6e:f0:c3:ff:88:cc:cc:63:35:23:3d:
-                    ce:4d:2e:2d:dc:b3:91:8e:d8:d8:5b:6a:92:28:c5:
-                    e9:a4:02:76:34:e0:6d:41:61:43:71:e1:59:b3:c2:
-                    ce:f7
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
+                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
+                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
+                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
+                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
+                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
+                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
+                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
+                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
+                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
+                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
+                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
+                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
+                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
+                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
+                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
+                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
+                    34:69
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                0D:AF:BC:C3:31:09:C6:9D:F8:44:D2:51:E8:13:FF:24:78:9D:83:76
+                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        28:52:54:55:5c:5b:4f:af:4c:66:cc:c3:71:dd:3e:60:48:76:
-        c3:f0:c0:40:30:f6:44:06:73:2f:c5:b1:1c:6a:e9:6f:fd:92:
-        8d:40:38:eb:46:de:58:cd:68:0f:cd:7f:28:a2:79:29:92:ae:
-        68:f2:ba:0a:f1:e6:17:58:a4:3b:ee:61:6c:d6:5d:2a:07:61:
-        b0:31:c9:9b:dc:08:32:b8:d8:ac:14:9c:1a:ec:21:7d:46:63:
-        75:67:46:36:ec:25:f0:e6:ed:3f:5d:b7:fd:06:67:46:80:a0:
-        b9:a8:25:e7:05:0a:f9:a7:20:48:d4:71:b4:3f:0b:1c:4d:f4:
-        73:8b:cc:9f:67:cf:36:43:e2:82:d5:d5:4e:4c:71:74:5c:db:
-        ba:35:bf:1e:9e:63:46:d0:c7:b9:f4:2a:92:23:c7:59:af:5d:
-        b1:24:7c:ff:1c:08:0d:2a:50:79:57:1c:a2:45:38:a5:3e:d7:
-        c8:5c:91:f2:69:70:d1:47:4a:55:bc:84:dc:9b:9f:ae:f2:94:
-        1c:22:65:11:4c:7c:e1:3c:ae:d4:e6:11:fc:3f:d8:53:6b:65:
-        4a:7c:44:bf:91:bd:b0:3e:df:b5:f5:c5:8e:1f:a5:19:83:2a:
-        8d:4e:13:3d:58:45:8e:11:b6:9e:96:7a:7a:6e:0b:e5:1a:66:
-        7a:00:0e:75
+         97:cd:ae:5a:26:f4:25:f6:c0:8b:08:d8:df:82:35:d8:76:f3:
+         5d:cc:99:bd:ac:70:c9:41:e0:24:c8:fd:e6:4e:41:2c:d4:69:
+         8d:08:25:fd:f3:32:3a:58:0b:d3:58:9c:81:51:bf:97:a4:bc:
+         00:18:1c:4f:1c:54:04:63:e3:72:87:f4:dc:9e:7b:dc:da:5d:
+         e1:ef:59:6b:f0:1f:3d:0c:11:55:1e:9a:1a:d8:8d:bc:7b:18:
+         b7:4f:92:1c:68:73:82:ec:f3:69:48:0a:86:40:4a:a5:6f:ae:
+         8f:10:2e:12:0b:e8:7e:b9:bc:d7:26:f0:cf:f4:0f:5b:77:f2:
+         ff:77:28:b4:5f:5e:ef:65:08:21:b8:f9:1e:56:b9:69:3b:c4:
+         7f:01:88:c9:7c:ca:d0:e2:df:e5:5e:8d:e9:2e:7d:4a:78:04:
+         8b:c1:dc:d4:58:ac:90:fc:5c:8e:48:2b:60:99:63:37:3f:e5:
+         61:da:8f:58:9f:4d:0a:ee:6c:8d:bc:1f:7e:c4:be:0f:32:4b:
+         11:7a:28:bf:dd:d0:a0:40:42:a8:43:4d:0b:2f:01:0e:73:de:
+         1b:a6:df:49:57:58:89:57:c0:23:76:83:f0:9a:0e:83:d9:9b:
+         cb:eb:ac:3f:89:d1:e8:3c:3e:f1:d5:80:0c:38:18:02:5c:5f:
+         e5:68:5e:cf
 -----BEGIN CERTIFICATE-----
-MIIC3DCCAcSgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQyBD
-QTAeFw0xNjAxMDQwMDAwMDBaFw0yNjAxMDIwMDAwMDBaMA8xDTALBgNVBAMMBEIg
-Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCioJMXHu7w+4cfccpr
-ub0tZzgqJMfDwohNyvJQM2Adb2GlYQKkp3YriUN4pwonBNylW26oTCnyJcbAMiDg
-AY2hFhXJtdgXfeDokImj9ZYfkMbjEBr59WrVQc7NqPw2dy+i1445UDZlTaeDbOGk
-zPZrwHvImPQBP5TT1hEds++VyOoH2V79gk8jTQiJ+2gtghKY4Ifyesd2mEzKHT7o
-vHLdsLdBhG45zak16O4q0VTNIe1vpKvp2MnS6RFmZngzrth4dawerQ4jgjUTlu3r
-PljrJ/sb/Sdu8MP/iMzMYzUjPc5NLi3cs5GO2NhbapIoxemkAnY04G1BYUNx4Vmz
-ws73AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFA2vvMMxCcad
-+ETSUegT/yR4nYN2MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
-KFJUVVxbT69MZszDcd0+YEh2w/DAQDD2RAZzL8WxHGrpb/2SjUA460beWM1oD81/
-KKJ5KZKuaPK6CvHmF1ikO+5hbNZdKgdhsDHJm9wIMrjYrBScGuwhfUZjdWdGNuwl
-8ObtP123/QZnRoCguagl5wUK+acgSNRxtD8LHE30c4vMn2fPNkPigtXVTkxxdFzb
-ujW/Hp5jRtDHufQqkiPHWa9dsSR8/xwIDSpQeVccokU4pT7XyFyR8mlw0UdKVbyE
-3JufrvKUHCJlEUx84Tyu1OYR/D/YU2tlSnxEv5G9sD7ftfXFjh+lGYMqjU4TPVhF
-jhG2npZ6em4L5RpmegAOdQ==
+MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQyBD
+QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA0MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
+MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
+HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
+dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
+jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
+CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
+vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCXza5aJvQl9sCLCNjfgjXYdvNdzJm9
+rHDJQeAkyP3mTkEs1GmNCCX98zI6WAvTWJyBUb+XpLwAGBxPHFQEY+Nyh/Tcnnvc
+2l3h71lr8B89DBFVHpoa2I28exi3T5IcaHOC7PNpSAqGQEqlb66PEC4SC+h+ubzX
+JvDP9A9bd/L/dyi0X17vZQghuPkeVrlpO8R/AYjJfMrQ4t/lXo3pLn1KeASLwdzU
+WKyQ/FyOSCtgmWM3P+Vh2o9Yn00K7myNvB9+xL4PMksReii/3dCgQEKoQ00LLwEO
+c94bpt9JV1iJV8AjdoPwmg6D2ZvL66w/idHoPD7x1YAMOBgCXF/laF7P
 -----END CERTIFICATE-----
 Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 4097 (0x1001)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=E Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=E Root CA - Multi-root
         Validity
             Not Before: Jan  5 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=C CA
+        Subject: CN=C CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:c2:21:aa:d2:67:ec:f5:95:9e:c9:00:f2:ee:83:
-                    26:6c:3c:30:d4:a8:78:dd:0a:a5:d6:81:f0:54:25:
-                    de:8f:9a:0e:8f:5c:06:96:b0:83:b7:13:56:33:9e:
-                    d1:6a:7d:45:40:d8:e5:21:1d:c5:6d:31:34:6f:45:
-                    22:cf:6f:01:b4:f8:6c:ce:70:d0:e9:0e:ed:04:d9:
-                    34:7a:91:db:6f:90:94:66:95:26:0b:29:26:4c:6c:
-                    8b:e3:13:a1:42:29:59:a0:2c:fe:83:a5:3c:3d:e8:
-                    32:ac:37:a7:ae:b2:79:d3:12:98:5f:c7:fd:4c:49:
-                    6b:e4:32:40:76:7b:78:ae:a1:61:b1:0a:d1:5c:f3:
-                    96:13:5f:95:5a:a2:35:c5:63:1b:25:05:8d:3c:08:
-                    d0:b0:28:2a:f3:f6:34:ab:a5:cd:e7:82:2c:35:38:
-                    8b:f5:41:6c:71:32:c4:13:67:ef:9b:8f:32:ab:7c:
-                    da:e1:6a:92:4b:5b:9e:39:7e:6b:00:f8:8d:e2:b3:
-                    3b:ad:2f:11:3f:80:d5:19:0e:cc:d4:c1:21:42:46:
-                    42:2d:d0:5e:ae:63:d1:0a:3e:66:fb:eb:0b:9b:e4:
-                    fe:7a:ca:43:5c:cc:98:6a:e1:fd:32:18:4c:63:4c:
-                    cd:98:9b:be:fa:5b:2d:c4:76:cc:8d:e5:6d:aa:bb:
-                    5a:37
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
+                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
+                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
+                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
+                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
+                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
+                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
+                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
+                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
+                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
+                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
+                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
+                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
+                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
+                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
+                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
+                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
+                    4b:11
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                34:19:53:D9:DA:11:B1:FF:00:35:2B:37:00:91:1F:91:C0:F7:2E:0A
+                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        57:6d:1c:44:40:54:a1:e5:3c:a0:e1:e1:d0:72:41:61:93:91:
-        38:65:8b:cc:35:d9:4c:04:80:12:4a:fd:84:71:9f:06:4f:de:
-        06:1c:0d:93:51:b2:2d:d7:c8:f5:0d:4f:fd:14:58:9e:d2:c2:
-        ac:5d:bf:f7:67:5f:68:2d:a2:cf:12:86:79:26:70:11:2d:3f:
-        0c:5f:65:fc:44:fd:6e:87:5e:56:3a:dc:be:da:95:e2:45:aa:
-        07:28:ff:46:1e:4b:bf:03:92:84:53:9b:c9:7a:dd:e7:5e:e9:
-        57:ba:18:c2:23:12:26:27:74:b6:93:44:4c:1e:6a:e2:20:62:
-        e5:33:db:86:14:41:7e:7c:76:5a:e5:d1:7f:fc:f4:f9:a3:23:
-        c9:06:ec:cb:b5:62:1e:bc:7b:1c:70:57:a5:d3:1d:d6:0f:79:
-        6a:f2:05:58:63:11:91:fb:b4:44:6a:b2:97:18:cf:ee:de:5d:
-        ac:d4:d8:63:e2:4f:42:25:fa:44:a4:47:b1:e4:f7:7f:55:a0:
-        e0:f7:09:f8:43:5c:54:1f:6a:e4:87:96:91:a0:8b:72:57:53:
-        52:22:31:d1:26:d4:5f:38:43:17:2a:48:91:37:b6:d8:d2:b3:
-        54:fc:f7:61:4e:c6:bc:39:89:e2:d8:3c:c0:d4:50:33:0b:de:
-        3d:02:70:5d
+         43:35:08:cc:aa:f8:10:9f:9e:fa:ab:24:dc:c6:e6:9a:23:52:
+         c9:4c:81:33:ba:64:b2:86:a8:29:f4:1f:5a:fa:5a:c4:91:56:
+         16:d1:f9:84:96:89:8c:ac:1f:b6:ea:2f:cb:12:f4:92:ed:3b:
+         85:09:eb:f3:7a:2e:09:39:ec:ee:09:4b:fa:86:3e:62:40:0e:
+         57:72:07:de:fa:53:45:ac:40:1c:0d:0b:4a:67:9a:f7:39:ce:
+         33:5e:d0:17:0b:8a:83:ae:33:6f:96:c0:f0:7a:ac:07:36:c5:
+         86:a9:db:93:aa:2e:fa:71:d1:1a:dd:82:2a:f8:1c:30:2a:b9:
+         7d:29:fa:75:62:76:7c:15:15:75:af:78:6c:7c:53:ae:2e:80:
+         14:0d:0b:eb:0f:b1:6d:fa:df:72:0b:6f:f0:90:96:18:71:df:
+         76:1d:8c:f1:d5:c0:4f:ab:38:1a:eb:e6:a1:dd:1d:dc:60:d4:
+         da:7f:40:db:17:fc:4a:56:65:3a:86:60:83:87:b3:f6:3b:a8:
+         85:ac:2b:14:c2:26:77:8f:ee:a4:6f:11:f2:27:08:3f:bf:86:
+         4a:e3:bd:ef:6b:51:ec:72:a7:51:08:47:16:f8:d3:d7:b1:8d:
+         a1:b1:ca:d3:cd:fd:56:0a:2c:2f:62:27:8c:e1:ff:88:83:ff:
+         83:ab:87:70
 -----BEGIN CERTIFICATE-----
-MIIC4TCCAcmgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRSBS
-b290IENBMB4XDTE2MDEwNTAwMDAwMFoXDTI2MDEwMjAwMDAwMFowDzENMAsGA1UE
-AwwEQyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIhqtJn7PWV
-nskA8u6DJmw8MNSoeN0KpdaB8FQl3o+aDo9cBpawg7cTVjOe0Wp9RUDY5SEdxW0x
-NG9FIs9vAbT4bM5w0OkO7QTZNHqR22+QlGaVJgspJkxsi+MToUIpWaAs/oOlPD3o
-Mqw3p66yedMSmF/H/UxJa+QyQHZ7eK6hYbEK0VzzlhNflVqiNcVjGyUFjTwI0LAo
-KvP2NKulzeeCLDU4i/VBbHEyxBNn75uPMqt82uFqkktbnjl+awD4jeKzO60vET+A
-1RkOzNTBIUJGQi3QXq5j0Qo+ZvvrC5vk/nrKQ1zMmGrh/TIYTGNMzZibvvpbLcR2
-zI3lbaq7WjcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUNBlT
-2doRsf8ANSs3AJEfkcD3LgowDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUA
-A4IBAQBXbRxEQFSh5Tyg4eHQckFhk5E4ZYvMNdlMBIASSv2EcZ8GT94GHA2TUbIt
-18j1DU/9FFie0sKsXb/3Z19oLaLPEoZ5JnARLT8MX2X8RP1uh15WOty+2pXiRaoH
-KP9GHku/A5KEU5vJet3nXulXuhjCIxImJ3S2k0RMHmriIGLlM9uGFEF+fHZa5dF/
-/PT5oyPJBuzLtWIevHsccFel0x3WD3lq8gVYYxGR+7REarKXGM/u3l2s1Nhj4k9C
-JfpEpEex5Pd/VaDg9wn4Q1xUH2rkh5aRoItyV1NSIjHRJtRfOEMXKkiRN7bY0rNU
-/PdhTsa8OYni2DzA1FAzC949AnBd
+MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDUwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
+FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
+O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
+l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
+wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
+BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAEM1CMyq+BCfnvqrJNzG5poj
+UslMgTO6ZLKGqCn0H1r6WsSRVhbR+YSWiYysH7bqL8sS9JLtO4UJ6/N6Lgk57O4J
+S/qGPmJADldyB976U0WsQBwNC0pnmvc5zjNe0BcLioOuM2+WwPB6rAc2xYap25Oq
+Lvpx0Rrdgir4HDAquX0p+nVidnwVFXWveGx8U64ugBQNC+sPsW3633ILb/CQlhhx
+33YdjPHVwE+rOBrr5qHdHdxg1Np/QNsX/EpWZTqGYIOHs/Y7qIWsKxTCJneP7qRv
+EfInCD+/hkrjve9rUexyp1EIRxb409exjaGxytPN/VYKLC9iJ4zh/4iD/4Orh3A=
 -----END CERTIFICATE-----
 Certificate:
     Data:
         Version: 3 (0x2)
         Serial Number: 4096 (0x1000)
-        Signature Algorithm: sha256WithRSAEncryption
-        Issuer: CN=E Root CA
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=E Root CA - Multi-root
         Validity
             Not Before: Jan  2 00:00:00 2016 GMT
             Not After : Jan  2 00:00:00 2026 GMT
-        Subject: CN=E Root CA
+        Subject: CN=E Root CA - Multi-root
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (2048 bit)
-                Modulus (2048 bit):
-                    00:a4:35:79:08:1a:d9:5a:a6:12:69:98:d6:3f:c7:
-                    fb:31:f6:f1:d6:a4:1b:f3:6a:fb:36:51:04:f1:9d:
-                    3b:94:81:77:35:7d:62:75:b4:b4:04:69:df:44:49:
-                    fc:43:d5:a4:14:af:67:d0:fb:51:21:2b:8b:dc:8c:
-                    89:d1:0b:08:26:17:3d:75:10:08:6f:ba:a4:24:8b:
-                    7e:c3:fa:3d:ab:fb:f6:f5:14:80:f7:9a:45:00:b2:
-                    84:12:e2:7d:c0:b7:40:ca:6f:06:1e:d2:3c:10:6f:
-                    11:f0:52:a2:16:ef:52:91:09:6f:89:28:cf:70:fc:
-                    e7:9e:1c:4b:5d:88:08:2f:2c:9e:75:c6:b9:6b:25:
-                    68:05:01:98:f2:28:53:7d:be:a1:5f:3a:62:0b:4a:
-                    c4:95:17:97:d0:4a:5d:8a:5f:52:07:7a:6a:8b:81:
-                    41:a2:60:08:92:e8:d0:c2:c8:9c:19:b2:3c:c3:c6:
-                    33:7d:5d:90:a6:0b:d3:ca:7b:8b:6f:70:aa:bb:d1:
-                    90:81:6c:db:b8:48:f8:52:d1:47:32:ed:66:9e:67:
-                    dd:e6:bc:9e:5d:60:33:9f:07:d8:b6:3e:d2:48:f5:
-                    a8:4c:12:6f:19:32:32:a7:66:0c:66:00:79:9f:dc:
-                    91:e4:54:bb:ff:b5:22:ad:0c:5f:f7:5d:d6:1a:f0:
-                    82:59
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b5:60:cb:b4:84:ab:6c:ba:59:52:a9:4c:6a:85:
+                    41:f2:41:17:49:40:3f:3e:e8:70:5c:05:df:dd:64:
+                    9e:fc:be:fb:38:ef:5d:67:ab:0e:de:9c:ea:ad:91:
+                    e1:f4:db:8b:f4:c0:e6:d0:ad:e2:83:15:01:aa:49:
+                    42:97:ae:72:7b:78:e3:20:4e:7e:29:ee:b5:35:6b:
+                    c4:af:d4:54:b0:86:2f:a9:09:a7:3b:8c:05:9e:fd:
+                    b4:b8:1f:3a:aa:d5:b5:d2:91:0f:50:e9:d2:1e:62:
+                    1c:c1:30:07:41:aa:bd:c2:11:3f:cc:c8:0f:a9:7e:
+                    81:69:52:96:86:2a:07:63:7b:f0:23:9e:db:27:88:
+                    8c:dc:aa:8c:66:dd:35:3a:08:60:37:36:41:34:f5:
+                    48:69:23:1a:5b:18:a7:ec:df:68:0a:3c:19:fb:92:
+                    b7:fa:53:9b:f3:70:b6:0d:4c:cb:2f:b7:0e:7e:5f:
+                    94:8c:a3:71:66:09:be:0d:af:db:52:f6:82:3f:88:
+                    64:72:cc:19:79:f4:7b:4d:6e:50:dc:93:88:d5:29:
+                    8a:e1:c8:1f:32:71:9f:d9:0e:14:31:f8:94:11:23:
+                    b1:bf:64:eb:27:3a:64:fb:77:ee:40:8c:a7:03:ed:
+                    1d:ec:8f:ee:25:58:f0:26:91:3c:f8:28:a1:7a:45:
+                    9f:13
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                B7:51:AA:C9:B7:3E:03:E5:11:94:49:A2:26:0F:70:81:7B:4E:7A:A7
+                51:68:BC:D9:1B:1D:7F:8E:0D:4A:33:39:2D:A4:1F:14:29:92:70:8E
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-        6b:32:6f:7f:a4:6c:9c:21:a9:95:ab:b6:2a:50:59:72:36:1a:
-        ad:86:c4:4e:2f:a2:0a:81:47:b1:37:ed:94:5a:e3:c3:ec:43:
-        46:2b:39:6c:66:ba:61:74:44:a4:e6:f6:63:6c:98:4b:d1:01:
-        74:93:77:81:fe:92:5c:4a:bf:a4:d2:0b:aa:c8:00:7b:df:74:
-        75:6e:d7:1a:7d:3b:f4:07:99:bb:04:63:93:97:9f:1d:b0:f0:
-        81:23:94:70:8b:c6:c1:24:c1:05:01:80:c6:4e:cc:ec:7f:05:
-        c8:93:c4:9b:57:bb:ac:8e:b6:7f:ed:41:e6:49:2d:1b:bb:ec:
-        74:47:ce:63:57:a2:e9:42:b5:f6:73:8d:f5:64:a5:53:f0:86:
-        4b:34:29:80:0b:63:16:c6:98:af:d6:cb:17:52:8e:75:fc:95:
-        03:ca:03:1d:a8:d3:83:f4:32:94:b1:6d:2e:f0:1c:87:81:b5:
-        6a:f0:19:20:76:62:e1:da:39:9c:f7:ee:d3:f7:d3:14:39:89:
-        a2:a9:eb:2f:8e:e6:0f:70:e5:63:d1:43:ff:d8:f0:68:13:55:
-        c5:02:ab:f9:a5:d8:ae:7f:4c:c5:e4:1b:c2:ba:4a:e9:d7:d3:
-        6e:69:80:39:d0:ad:0c:9d:2a:e6:6c:e6:e9:f7:49:eb:4b:4d:
-        73:0d:d5:51
+         2d:d4:56:d9:90:bb:62:64:66:78:6d:cd:73:26:cc:42:ce:37:
+         f4:bf:e8:8f:e7:1e:00:cb:c2:bd:54:33:0b:a8:e2:04:e1:5f:
+         59:2a:1a:41:70:0f:d6:32:5f:d0:14:86:fa:e2:a7:19:29:49:
+         77:56:b9:d7:e6:eb:39:61:e4:25:67:22:eb:f8:46:86:b7:6b:
+         7d:44:01:0b:18:cb:ba:e5:af:76:ab:c6:fe:43:6c:d8:f6:33:
+         f7:86:0b:22:da:27:78:91:07:55:3f:b2:c5:1e:10:88:09:b3:
+         cf:22:c6:7e:8f:c6:d0:c5:ec:67:90:72:8b:2b:c4:46:81:2c:
+         82:d1:5c:57:4e:d5:af:c4:d2:d8:b2:a7:91:1a:42:b3:57:bc:
+         4e:81:5e:cf:91:af:da:f1:53:29:de:31:6b:d3:69:a4:4d:a9:
+         14:15:96:51:7d:0d:bd:28:11:03:71:d2:85:11:92:1d:96:1a:
+         12:33:0c:4b:cf:c4:40:19:fb:eb:6a:fe:9b:e7:2d:cd:f7:75:
+         a3:66:4e:a6:7d:8e:8c:2e:5d:b8:2c:a8:5e:d7:42:1b:97:00:
+         ba:12:41:8c:9b:f1:ed:91:49:63:5a:11:0d:e4:7d:f0:dc:36:
+         23:0b:1b:e8:5f:be:1f:6d:a7:aa:bb:30:76:e2:36:b2:5a:68:
+         80:f5:75:7e
 -----BEGIN CERTIFICATE-----
-MIIC5jCCAc6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJRSBS
-b290IENBMB4XDTE2MDEwMjAwMDAwMFoXDTI2MDEwMjAwMDAwMFowFDESMBAGA1UE
-AwwJRSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApDV5
-CBrZWqYSaZjWP8f7Mfbx1qQb82r7NlEE8Z07lIF3NX1idbS0BGnfREn8Q9WkFK9n
-0PtRISuL3IyJ0QsIJhc9dRAIb7qkJIt+w/o9q/v29RSA95pFALKEEuJ9wLdAym8G
-HtI8EG8R8FKiFu9SkQlviSjPcPznnhxLXYgILyyedca5ayVoBQGY8ihTfb6hXzpi
-C0rElReX0Epdil9SB3pqi4FBomAIkujQwsicGbI8w8YzfV2QpgvTynuLb3Cqu9GQ
-gWzbuEj4UtFHMu1mnmfd5ryeXWAznwfYtj7SSPWoTBJvGTIyp2YMZgB5n9yR5FS7
-/7UirQxf913WGvCCWQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBS3UarJtz4D5RGUSaImD3CBe056pzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcN
-AQELBQADggEBAGsyb3+kbJwhqZWrtipQWXI2Gq2GxE4vogqBR7E37ZRa48PsQ0Yr
-OWxmumF0RKTm9mNsmEvRAXSTd4H+klxKv6TSC6rIAHvfdHVu1xp9O/QHmbsEY5OX
-nx2w8IEjlHCLxsEkwQUBgMZOzOx/BciTxJtXu6yOtn/tQeZJLRu77HRHzmNXoulC
-tfZzjfVkpVPwhks0KYALYxbGmK/WyxdSjnX8lQPKAx2o04P0MpSxbS7wHIeBtWrw
-GSB2YuHaOZz37tP30xQ5iaKp6y+O5g9w5WPRQ//Y8GgTVcUCq/ml2K5/TMXkG8K6
-SunX025pgDnQrQydKuZs5un3SetLTXMN1VE=
+MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
+b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
+MDBaMCExHzAdBgNVBAMMFkUgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1YMu0hKtsullSqUxqhUHyQRdJQD8+6HBc
+Bd/dZJ78vvs4711nqw7enOqtkeH024v0wObQreKDFQGqSUKXrnJ7eOMgTn4p7rU1
+a8Sv1FSwhi+pCac7jAWe/bS4Hzqq1bXSkQ9Q6dIeYhzBMAdBqr3CET/MyA+pfoFp
+UpaGKgdje/AjntsniIzcqoxm3TU6CGA3NkE09UhpIxpbGKfs32gKPBn7krf6U5vz
+cLYNTMsvtw5+X5SMo3FmCb4Nr9tS9oI/iGRyzBl59HtNblDck4jVKYrhyB8ycZ/Z
+DhQx+JQRI7G/ZOsnOmT7d+5AjKcD7R3sj+4lWPAmkTz4KKF6RZ8TAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFFovNkbHX+ODUozOS2kHxQpknCO
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEALdRW2ZC7YmRmeG3N
+cybMQs439L/oj+ceAMvCvVQzC6jiBOFfWSoaQXAP1jJf0BSG+uKnGSlJd1a51+br
+OWHkJWci6/hGhrdrfUQBCxjLuuWvdqvG/kNs2PYz94YLItoneJEHVT+yxR4QiAmz
+zyLGfo/G0MXsZ5ByiyvERoEsgtFcV07Vr8TS2LKnkRpCs1e8ToFez5Gv2vFTKd4x
+a9NppE2pFBWWUX0NvSgRA3HShRGSHZYaEjMMS8/EQBn762r+m+ctzfd1o2ZOpn2O
+jC5duCyoXtdCG5cAuhJBjJvx7ZFJY1oRDeR98Nw2Iwsb6F++H22nqrswduI2slpo
+gPV1fg==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-crlset-C-by-E.raw b/net/data/ssl/certificates/multi-root-crlset-C-by-E.raw
deleted file mode 100644
index b13bdd87..0000000
--- a/net/data/ssl/certificates/multi-root-crlset-C-by-E.raw
+++ /dev/null
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-C.raw b/net/data/ssl/certificates/multi-root-crlset-C.raw
new file mode 100644
index 0000000..5beec4c
--- /dev/null
+++ b/net/data/ssl/certificates/multi-root-crlset-C.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-CD-and-FE.raw b/net/data/ssl/certificates/multi-root-crlset-CD-and-FE.raw
new file mode 100644
index 0000000..178cf4dd
--- /dev/null
+++ b/net/data/ssl/certificates/multi-root-crlset-CD-and-FE.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-D-and-E.raw b/net/data/ssl/certificates/multi-root-crlset-D-and-E.raw
new file mode 100644
index 0000000..89e7e20f
--- /dev/null
+++ b/net/data/ssl/certificates/multi-root-crlset-D-and-E.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-E.raw b/net/data/ssl/certificates/multi-root-crlset-E.raw
new file mode 100644
index 0000000..46e4c36
--- /dev/null
+++ b/net/data/ssl/certificates/multi-root-crlset-E.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-F.raw b/net/data/ssl/certificates/multi-root-crlset-F.raw
deleted file mode 100644
index bad62ec..0000000
--- a/net/data/ssl/certificates/multi-root-crlset-F.raw
+++ /dev/null
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-unrelated.raw b/net/data/ssl/certificates/multi-root-crlset-unrelated.raw
new file mode 100644
index 0000000..98680b6
--- /dev/null
+++ b/net/data/ssl/certificates/multi-root-crlset-unrelated.raw
Binary files differ
diff --git a/net/data/ssl/scripts/generate-multi-root-test-chains.sh b/net/data/ssl/scripts/generate-multi-root-test-chains.sh
index 5de08df..c4d1792e 100755
--- a/net/data/ssl/scripts/generate-multi-root-test-chains.sh
+++ b/net/data/ssl/scripts/generate-multi-root-test-chains.sh
@@ -66,7 +66,7 @@
 for i in D E
 do
   echo "Generating CSR ${i}"
-  CA_COMMON_NAME="${i} Root CA" \
+  CA_COMMON_NAME="${i} Root CA - Multi-root" \
   CERTIFICATE="${i}" \
   openssl req \
     -config redundant-ca.cnf \
@@ -75,7 +75,7 @@
     -out "out/${i}.csr"
 
   echo "Generating self-signed ${i}"
-  CA_COMMON_NAME="${i} Root CA" \
+  CA_COMMON_NAME="${i} Root CA - Multi-root" \
   CERTIFICATE="${i}" \
   openssl ca \
     -config redundant-ca.cnf \
@@ -93,7 +93,7 @@
 for i in B C F
 do
   echo "Generating CSR ${i}"
-  CA_COMMON_NAME="${i} CA" \
+  CA_COMMON_NAME="${i} CA - Multi-root" \
   CERTIFICATE="${i}" \
   openssl req \
     -config redundant-ca.cnf \
@@ -103,7 +103,7 @@
 done
 
 echo D signs C
-CA_COMMON_NAME="D CA" \
+CA_COMMON_NAME="D CA - Multi-root" \
 CERTIFICATE=D \
 openssl ca \
   -config redundant-ca.cnf \
@@ -116,7 +116,7 @@
   -out out/C.pem
 
 echo C signs B
-CA_COMMON_NAME="C CA" \
+CA_COMMON_NAME="C CA - Multi-root" \
 CERTIFICATE=C \
 openssl ca \
   -config redundant-ca.cnf \
@@ -129,7 +129,7 @@
   -out out/B.pem
 
 echo E signs C2
-CA_COMMON_NAME="E CA" \
+CA_COMMON_NAME="E CA - Multi-root" \
 CERTIFICATE=E \
 openssl ca \
   -config redundant-ca.cnf \
@@ -142,7 +142,7 @@
   -out out/C2.pem
 
 echo E signs F
-CA_COMMON_NAME="E CA" \
+CA_COMMON_NAME="E CA - Multi-root" \
 CERTIFICATE=E \
 openssl ca \
   -config redundant-ca.cnf \
@@ -158,7 +158,7 @@
 # B-by-F more preferable, the startdate is chosen to be GREATER (later) than
 # B-by-C.
 echo F signs B2
-CA_COMMON_NAME="F CA" \
+CA_COMMON_NAME="F CA - Multi-root" \
 CERTIFICATE=F \
 openssl ca \
   -config redundant-ca.cnf \
@@ -182,7 +182,7 @@
 done
 
 echo "Signing leaves"
-CA_COMMON_NAME="B CA" \
+CA_COMMON_NAME="B CA - Multi-root" \
 CERTIFICATE=B \
 openssl ca \
   -config redundant-ca.cnf \
@@ -208,20 +208,53 @@
 cp out/E.pem ../certificates/multi-root-E-by-E.pem
 
 echo "Generating CRLSets"
-# Block C-by-E (serial number 0x1001) by way of serial number.
-python crlsetutil.py -o ../certificates/multi-root-crlset-C-by-E.raw \
-<<CRLSETBYSERIAL
+# Block D and E by SPKI; invalidates all paths.
+python crlsetutil.py -o ../certificates/multi-root-crlset-D-and-E.raw \
+<<CRLSETDOCBLOCK
+{
+  "BlockedBySPKI": [
+    "out/D.pem",
+    "out/E.pem"
+  ]
+}
+CRLSETDOCBLOCK
+
+# Block E by SPKI.
+python crlsetutil.py -o ../certificates/multi-root-crlset-E.raw \
+<<CRLSETDOCBLOCK
+{
+  "BlockedBySPKI": [
+    "out/E.pem"
+  ]
+}
+CRLSETDOCBLOCK
+
+# Block C-by-D (serial number 0x1001) and F-by-E (serial number 0x1002) by
+# way of serial number.
+python crlsetutil.py -o ../certificates/multi-root-crlset-CD-and-FE.raw \
+<<CRLSETDOCBLOCK
 {
   "BlockedByHash": {
-    "out/E.pem": [4097]
+    "out/D.pem": [4097],
+    "out/E.pem": [4098]
   }
 }
-CRLSETBYSERIAL
+CRLSETDOCBLOCK
 
-# Block F (all versions) by way of SPKI
-python crlsetutil.py -o ../certificates/multi-root-crlset-F.raw \
-<<CRLSETBYSPKI
+# Block C (all versions) by way of SPKI
+python crlsetutil.py -o ../certificates/multi-root-crlset-C.raw \
+<<CRLSETDOCBLOCK
 {
-  "BlockedBySPKI": [ "out/F.pem" ]
+  "BlockedBySPKI": [ "out/C.pem" ]
 }
-CRLSETBYSPKI
\ No newline at end of file
+CRLSETDOCBLOCK
+
+# Block an unrelated/unissued serial (0x0FFF) to enable all paths.
+python crlsetutil.py -o ../certificates/multi-root-crlset-unrelated.raw \
+<<CRLSETDOCBLOCK
+{
+  "BlockedByHash": {
+    "out/E.pem": [4095]
+  }
+}
+CRLSETDOCBLOCK
diff --git a/net/dns/dns_response.cc b/net/dns/dns_response.cc
index c11b8a9c..9896789 100644
--- a/net/dns/dns_response.cc
+++ b/net/dns/dns_response.cc
@@ -11,6 +11,7 @@
 #include "base/sys_byteorder.h"
 #include "net/base/address_list.h"
 #include "net/base/io_buffer.h"
+#include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
 #include "net/dns/dns_protocol.h"
 #include "net/dns/dns_query.h"
@@ -290,7 +291,8 @@
          expected_type == dns_protocol::kTypeAAAA);
 
   size_t expected_size = (expected_type == dns_protocol::kTypeAAAA)
-      ? kIPv6AddressSize : kIPv4AddressSize;
+                             ? IPAddress::kIPv6AddressSize
+                             : IPAddress::kIPv4AddressSize;
 
   uint32_t ttl_sec = std::numeric_limits<uint32_t>::max();
   IPAddressList ip_addresses;
@@ -322,8 +324,9 @@
         return DNS_NAME_MISMATCH;
 
       ttl_sec = std::min(ttl_sec, record.ttl);
-      ip_addresses.push_back(IPAddressNumber(record.rdata.begin(),
-                                             record.rdata.end()));
+      ip_addresses.push_back(
+          IPAddress(reinterpret_cast<const uint8_t*>(record.rdata.data()),
+                    record.rdata.length()));
     }
   }
 
diff --git a/net/docs/bug-triage.md b/net/docs/bug-triage.md
index ac32403..0eb41fe 100644
--- a/net/docs/bug-triage.md
+++ b/net/docs/bug-triage.md
@@ -61,8 +61,7 @@
       fact an alert was responded to as an inidicator of which of them need
       to be followed up on.
 
-* Investigate [Uncomfirmed / Untriaged Internals>Network issues that don't
-  belong to a more specific network component](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified),
+* Investigate [Uncomfirmed / Untriaged Internals>Network issues that don't belong to a more specific network component](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3DInternals%3ENetwork+status%3AUnconfirmed,Untriaged+-label:Needs-Feedback&sort=-modified),
   prioritizing the most recent issues, ones with the most responsive reporters,
   and major crashers.  This will generally take up the majority of your time as
   triager. Continue digging until you can do one of the following:
@@ -90,8 +89,7 @@
       its status should be set to Available.  Future triagers should ignore bugs
       with this status, unless investigating stale bugs.
 
-* Follow up on [Needs-Feedback issues for all components owned by the network
-  stack team](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3AInternals%3ENetwork%2CUI>Browser>Downloads+-component%3AInternals%3ENetwork%3EDataProxy+-component%3AInternals%3ENetwork%3EDataUse+-component%3AInternals%3ENetwork%3EVPN+Needs%3DFeedback).
+* Follow up on [Needs-Feedback issues for all components owned by the network stack team](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=component%3AInternals%3ENetwork%2CUI>Browser>Downloads+-component%3AInternals%3ENetwork%3EDataProxy+-component%3AInternals%3ENetwork%3EDataUse+-component%3AInternals%3ENetwork%3EVPN+Needs%3DFeedback&sort=-modified).
 
     * Remove label once feedback is provided.  Continue to investigate, if
       the previous section applies.
@@ -116,6 +114,8 @@
   crashes that are both in the top 100 for each release and occurred for more
   than two users.
 
+    * Make sure to check for new crashes on all platforms, not just Windows.
+
 ### Best Effort (As you have time):
 
 * Investigate old bugs, and bugs associated with Internals>Network
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index 735629d..179fd96 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -1726,6 +1726,8 @@
     return;
   }
 
+  session_->quic_stream_factory()->OnTcpJobCompleted(job_status_ ==
+                                                     STATUS_SUCCEEDED);
   if (job_status_ == STATUS_SUCCEEDED && other_job_status_ == STATUS_BROKEN) {
     HistogramBrokenAlternateProtocolLocation(
         BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_IMPL_JOB_MAIN);
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index 002e3609..87b9d6f 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -768,6 +768,8 @@
 
   session->quic_stream_factory()->number_of_lossy_connections_[99] =
       params.quic_max_number_of_lossy_connections;
+  session->quic_stream_factory()->MaybeDisableQuic(99);
+  ASSERT_TRUE(session->quic_stream_factory()->IsQuicDisabled(99));
 
   StaticSocketDataProvider socket_data2;
   socket_data2.set_connect_data(MockConnect(ASYNC, OK));
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index fe529d8..6b82396 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -22,6 +22,7 @@
 #include "net/quic/crypto/crypto_handshake_message.h"
 #include "net/quic/crypto/crypto_protocol.h"
 #include "net/quic/quic_address_mismatch.h"
+#include "net/quic/quic_protocol.h"
 #include "net/quic/quic_socket_address_coder.h"
 #include "net/quic/quic_time.h"
 
@@ -613,6 +614,9 @@
 }
 
 void QuicConnectionLogger::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
+  UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.GoAwayReceivedForConnectionMigration",
+                        frame.error_code == QUIC_ERROR_MIGRATING_PORT);
+
   net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_GOAWAY_FRAME_RECEIVED,
                     base::Bind(&NetLogQuicGoAwayFrameCallback, &frame));
 }
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index add54d7..eba15ea5 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -647,6 +647,7 @@
       check_persisted_supports_quic_(true),
       has_initialized_data_(false),
       num_push_streams_created_(0),
+      status_(OPEN),
       task_runner_(nullptr),
       weak_factory_(this) {
   if (disable_quic_on_timeout_with_open_streams)
@@ -999,9 +1000,8 @@
   }
 }
 
-bool QuicStreamFactory::IsQuicDisabled(uint16_t port) {
-  return QuicDisabledReason(port) !=
-         QuicChromiumClientSession::QUIC_DISABLED_NOT;
+bool QuicStreamFactory::IsQuicDisabled(uint16_t port) const {
+  return status_ != OPEN;
 }
 
 bool QuicStreamFactory::OnHandshakeConfirmed(QuicChromiumClientSession* session,
@@ -1030,6 +1030,8 @@
                  max_number_of_lossy_connections_));
   }
 
+  MaybeDisableQuic(port);
+
   bool is_quic_disabled = IsQuicDisabled(port);
   if (is_quic_disabled) {
     // Close QUIC connection if Quic is disabled for this port.
@@ -1043,6 +1045,22 @@
   return is_quic_disabled;
 }
 
+void QuicStreamFactory::OnTcpJobCompleted(bool succeeded) {
+  if (status_ != CLOSED)
+    return;
+
+  // If QUIC connections are failing while TCP connections are working,
+  // then stop using QUIC. On the other hand if both QUIC and TCP are
+  // failing, then attempt to use QUIC again.
+  if (succeeded) {
+    status_ = DISABLED;
+    return;
+  }
+
+  status_ = OPEN;
+  num_timeouts_with_open_streams_ = 0;
+}
+
 void QuicStreamFactory::OnIdleSession(QuicChromiumClientSession* session) {}
 
 void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) {
@@ -1113,6 +1131,7 @@
         num_public_resets_post_handshake_, 0, 20, 10);
   }
 
+  MaybeDisableQuic(port);
   if (IsQuicDisabled(port)) {
     if (disabled_reason ==
         QuicChromiumClientSession::QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE) {
@@ -1129,6 +1148,35 @@
   }
 }
 
+void QuicStreamFactory::MaybeDisableQuic(uint16_t port) {
+  if (status_ == DISABLED)
+    return;
+
+  QuicChromiumClientSession::QuicDisabledReason disabled_reason =
+      QuicDisabledReason(port);
+  if (disabled_reason == QuicChromiumClientSession::QUIC_DISABLED_NOT) {
+    DCHECK_EQ(OPEN, status_);
+    return;
+  }
+
+  if (disabled_reason ==
+      QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS) {
+    // When QUIC there are too many timeouts with open stream, the factory
+    // should be closed. When TCP jobs complete, they will move the factory
+    // to either fully disabled or back to open.
+    status_ = CLOSED;
+    DCHECK(IsQuicDisabled(port));
+    DCHECK_NE(QuicChromiumClientSession::QuicDisabledReason(port),
+              QuicChromiumClientSession::QUIC_DISABLED_NOT);
+    return;
+  }
+
+  status_ = DISABLED;
+  DCHECK(IsQuicDisabled(port));
+  DCHECK_NE(QuicChromiumClientSession::QuicDisabledReason(port),
+            QuicChromiumClientSession::QUIC_DISABLED_NOT);
+}
+
 void QuicStreamFactory::OnSessionClosed(QuicChromiumClientSession* session) {
   DCHECK_EQ(0u, session->GetNumActiveStreams());
   MaybeDisableQuic(session);
@@ -1215,12 +1263,14 @@
 
 void QuicStreamFactory::OnIPAddressChanged() {
   num_timeouts_with_open_streams_ = 0;
+  status_ = OPEN;
   CloseAllSessions(ERR_NETWORK_CHANGED, QUIC_IP_ADDRESS_CHANGED);
   set_require_confirmation(true);
 }
 
 void QuicStreamFactory::OnNetworkConnected(NetworkHandle network) {
   num_timeouts_with_open_streams_ = 0;
+  status_ = OPEN;
 }
 
 void QuicStreamFactory::OnNetworkMadeDefault(NetworkHandle network) {}
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index 919f9ea..1986df85 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -188,8 +188,12 @@
   bool OnHandshakeConfirmed(QuicChromiumClientSession* session,
                             float packet_loss_rate);
 
+  // Called when a TCP job completes for an origin that QUIC potentially
+  // could be used for.
+  void OnTcpJobCompleted(bool succeeded);
+
   // Returns true if QUIC is disabled for this port.
-  bool IsQuicDisabled(uint16_t port);
+  bool IsQuicDisabled(uint16_t port) const;
 
   // Returns reason QUIC is disabled for this port, or QUIC_DISABLED_NOT if not.
   QuicChromiumClientSession::QuicDisabledReason QuicDisabledReason(
@@ -332,6 +336,12 @@
   typedef std::deque<enum QuicChromiumClientSession::QuicDisabledReason>
       DisabledReasonsQueue;
 
+  enum FactoryStatus {
+    OPEN,     // New streams may be created.
+    CLOSED,   // No new streams may be created temporarily.
+    DISABLED  // No more streams may be created until the network changes.
+  };
+
   // Creates a job which doesn't wait for server config to be loaded from the
   // disk cache. This job is started via a PostTask.
   void CreateAuxilaryJob(const QuicServerId server_id,
@@ -391,6 +401,8 @@
   // Collect stats from recent connections, possibly disabling Quic.
   void MaybeDisableQuic(QuicChromiumClientSession* session);
 
+  void MaybeDisableQuic(uint16_t port);
+
   bool require_confirmation_;
   HostResolver* host_resolver_;
   ClientSocketFactory* client_socket_factory_;
@@ -533,6 +545,9 @@
 
   QuicClientPushPromiseIndex push_promise_index_;
 
+  // Current status of the factory's ability to create streams.
+  FactoryStatus status_;
+
   base::TaskRunner* task_runner_;
 
   base::WeakPtrFactory<QuicStreamFactory> weak_factory_;
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index d3ca0673..762a2d7 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -2893,6 +2893,13 @@
   EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
             factory_->QuicDisabledReason(host_port_pair_.port()));
 
+  // Verify that QUIC is un-disabled after a TCP job fails.
+  factory_->OnTcpJobCompleted(/*succeeded=*/false);
+  EXPECT_EQ(
+      0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+  EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+                                                     host_port_pair_.port()));
+
   EXPECT_TRUE(socket_data.AllReadDataConsumed());
   EXPECT_TRUE(socket_data.AllWriteDataConsumed());
   EXPECT_TRUE(socket_data2.AllReadDataConsumed());
@@ -3132,6 +3139,14 @@
 
   scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
   EXPECT_TRUE(stream2.get());
+
+  // Verify that QUIC is un-disabled after a network change.
+  factory_->OnIPAddressChanged();
+  EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+                                                     host_port_pair_.port()));
+  EXPECT_EQ(
+      0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
+
   EXPECT_TRUE(socket_data.AllReadDataConsumed());
   EXPECT_TRUE(socket_data.AllWriteDataConsumed());
   EXPECT_TRUE(socket_data2.AllReadDataConsumed());
@@ -3196,6 +3211,16 @@
   EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
             factory_->QuicDisabledReason(host_port_pair_.port()));
 
+  // Verify that QUIC is fully disabled after a TCP job succeeds.
+  factory_->OnTcpJobCompleted(/*succeeded=*/true);
+  EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+                                                    host_port_pair_.port()));
+
+  // Verify that QUIC stays disabled after a TCP job succeeds.
+  factory_->OnTcpJobCompleted(/*succeeded=*/false);
+  EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
+                                                    host_port_pair_.port()));
+
   EXPECT_TRUE(socket_data.AllReadDataConsumed());
   EXPECT_TRUE(socket_data.AllWriteDataConsumed());
 }
@@ -3484,6 +3509,7 @@
   EXPECT_TRUE(stream2.get());
   scoped_ptr<QuicHttpStream> stream3 = request3.ReleaseStream();
   EXPECT_TRUE(stream3.get());
+
   EXPECT_TRUE(socket_data.AllReadDataConsumed());
   EXPECT_TRUE(socket_data.AllWriteDataConsumed());
   EXPECT_TRUE(socket_data2.AllReadDataConsumed());
diff --git a/net/quic/spdy_utils.cc b/net/quic/spdy_utils.cc
index b5aeb1a0..623637d 100644
--- a/net/quic/spdy_utils.cc
+++ b/net/quic/spdy_utils.cc
@@ -26,7 +26,8 @@
 
   size_t length = SpdyFramer::GetSerializedLength(spdy_version, &headers);
   SpdyFrameBuilder builder(length, spdy_version);
-  SpdyFramer::WriteHeaderBlock(&builder, spdy_version, &headers);
+  SpdyFramer framer(spdy_version);
+  framer.SerializeHeaderBlockWithoutCompression(&builder, headers);
   scoped_ptr<SpdyFrame> block(builder.take());
   return string(block->data(), length);
 }
diff --git a/net/socket/ssl_server_socket_unittest.cc b/net/socket/ssl_server_socket_unittest.cc
index 52ae7d8..466f8a4 100644
--- a/net/socket/ssl_server_socket_unittest.cc
+++ b/net/socket/ssl_server_socket_unittest.cc
@@ -335,13 +335,19 @@
       : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
         cert_verifier_(new MockCertVerifier()),
         client_cert_verifier_(new MockClientCertVerifier()),
-        transport_security_state_(new TransportSecurityState) {
+        transport_security_state_(new TransportSecurityState) {}
+
+  void SetUp() override {
+    PlatformTest::SetUp();
+
     cert_verifier_->set_default_result(ERR_CERT_AUTHORITY_INVALID);
     client_cert_verifier_->set_default_result(ERR_CERT_AUTHORITY_INVALID);
 
     server_cert_ =
         ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der");
+    ASSERT_TRUE(server_cert_);
     server_private_key_ = ReadTestKey("unittest.key.bin");
+    ASSERT_TRUE(server_private_key_);
 
     client_ssl_config_.false_start_enabled = false;
     client_ssl_config_.channel_id_enabled = false;
@@ -350,8 +356,8 @@
     SSLConfig::CertAndStatus cert_and_status;
     cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID;
     std::string server_cert_der;
-    CHECK(X509Certificate::GetDEREncoded(server_cert_->os_cert_handle(),
-                                         &server_cert_der));
+    ASSERT_TRUE(X509Certificate::GetDEREncoded(server_cert_->os_cert_handle(),
+                                               &server_cert_der));
     cert_and_status.der_cert = server_cert_der;
     client_ssl_config_.allowed_bad_certs.push_back(cert_and_status);
   }
@@ -382,12 +388,15 @@
     SSLClientSocketContext context;
     context.cert_verifier = cert_verifier_.get();
     context.transport_security_state = transport_security_state_.get();
+
     client_socket_ = socket_factory_->CreateSSLClientSocket(
         std::move(client_connection), host_and_pair, client_ssl_config_,
         context);
+    ASSERT_TRUE(client_socket_);
 
     server_socket_ =
         server_context_->CreateSSLServerSocket(std::move(server_socket));
+    ASSERT_TRUE(server_socket_);
   }
 
 #if defined(USE_OPENSSL)
@@ -397,8 +406,10 @@
     client_ssl_config_.client_cert =
         ImportCertFromFile(GetTestCertsDirectory(), cert_file_name);
     ASSERT_TRUE(client_ssl_config_.client_cert);
+
     scoped_ptr<crypto::RSAPrivateKey> key = ReadTestKey(private_key_file_name);
     ASSERT_TRUE(key);
+
     client_ssl_config_.client_private_key = WrapOpenSSLPrivateKey(
         crypto::ScopedEVP_PKEY(EVP_PKEY_up_ref(key->key())));
   }
@@ -413,9 +424,12 @@
                                     .MaybeAsASCII()
                                     .c_str()));
     ASSERT_TRUE(cert_names);
+
     for (size_t i = 0; i < sk_X509_NAME_num(cert_names.get()); ++i) {
       uint8_t* str = nullptr;
       int length = i2d_X509_NAME(sk_X509_NAME_value(cert_names.get(), i), &str);
+      ASSERT_LT(0, length);
+
       server_ssl_config_.cert_authorities_.push_back(std::string(
           reinterpret_cast<const char*>(str), static_cast<size_t>(length)));
       OPENSSL_free(str);
@@ -423,6 +437,8 @@
 
     scoped_refptr<X509Certificate> expected_client_cert(
         ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName));
+    ASSERT_TRUE(expected_client_cert);
+
     client_cert_verifier_->AddResultForCert(expected_client_cert.get(), OK);
 
     server_ssl_config_.client_cert_verifier = client_cert_verifier_.get();
@@ -463,16 +479,16 @@
 // test that creation of sockets doesn't crash and have minimal code to run
 // under valgrind in order to help debugging memory problems.
 TEST_F(SSLServerSocketTest, Initialize) {
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 }
 
 // This test executes Connect() on SSLClientSocket and Handshake() on
 // SSLServerSocket to make sure handshaking between the two sockets is
 // completed successfully.
 TEST_F(SSLServerSocketTest, Handshake) {
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback;
   int server_ret = server_socket_->Handshake(handshake_callback.callback());
@@ -509,8 +525,8 @@
 
 // This test makes sure the session cache is working.
 TEST_F(SSLServerSocketTest, HandshakeCached) {
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback;
   int server_ret = server_socket_->Handshake(handshake_callback.callback());
@@ -533,7 +549,7 @@
   EXPECT_EQ(ssl_server_info.handshake_type, SSLInfo::HANDSHAKE_FULL);
 
   // Make sure the second connection is cached.
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
   TestCompletionCallback handshake_callback2;
   int server_ret2 = server_socket_->Handshake(handshake_callback2.callback());
 
@@ -557,8 +573,8 @@
 
 // This test makes sure the session cache separates out by server context.
 TEST_F(SSLServerSocketTest, HandshakeCachedContextSwitch) {
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback;
   int server_ret = server_socket_->Handshake(handshake_callback.callback());
@@ -581,8 +597,8 @@
   EXPECT_EQ(ssl_server_info.handshake_type, SSLInfo::HANDSHAKE_FULL);
 
   // Make sure the second connection is NOT cached when using a new context.
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback2;
   int server_ret2 = server_socket_->Handshake(handshake_callback2.callback());
@@ -611,10 +627,11 @@
 TEST_F(SSLServerSocketTest, HandshakeWithClientCert) {
   scoped_refptr<X509Certificate> client_cert =
       ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
-  ConfigureClientCertsForClient(kClientCertFileName, kClientPrivateKeyFileName);
-  ConfigureClientCertsForServer();
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForClient(
+      kClientCertFileName, kClientPrivateKeyFileName));
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForServer());
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback;
   int server_ret = server_socket_->Handshake(handshake_callback.callback());
@@ -633,7 +650,7 @@
   client_socket_->GetSSLInfo(&ssl_info);
   EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
   server_socket_->GetSSLInfo(&ssl_info);
-  EXPECT_TRUE(ssl_info.cert.get());
+  ASSERT_TRUE(ssl_info.cert.get());
   EXPECT_TRUE(client_cert->Equals(ssl_info.cert.get()));
 }
 
@@ -644,10 +661,11 @@
 TEST_F(SSLServerSocketTest, HandshakeWithClientCertCached) {
   scoped_refptr<X509Certificate> client_cert =
       ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
-  ConfigureClientCertsForClient(kClientCertFileName, kClientPrivateKeyFileName);
-  ConfigureClientCertsForServer();
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForClient(
+      kClientCertFileName, kClientPrivateKeyFileName));
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForServer());
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback;
   int server_ret = server_socket_->Handshake(handshake_callback.callback());
@@ -674,7 +692,7 @@
   client_socket_->Disconnect();
 
   // Create the connection again.
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
   TestCompletionCallback handshake_callback2;
   int server_ret2 = server_socket_->Handshake(handshake_callback2.callback());
 
@@ -699,9 +717,9 @@
 }
 
 TEST_F(SSLServerSocketTest, HandshakeWithClientCertRequiredNotSupplied) {
-  ConfigureClientCertsForServer();
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForServer());
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
   // Use the default setting for the client socket, which is to not send
   // a client certificate. This will cause the client to receive an
   // ERR_SSL_CLIENT_AUTH_CERT_NEEDED error, and allow for inspecting the
@@ -723,6 +741,7 @@
   // handshake message is as expected.
   scoped_refptr<X509Certificate> client_cert =
       ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
+  ASSERT_TRUE(client_cert);
   EXPECT_TRUE(client_cert->IsIssuedByEncoded(request_info->cert_authorities));
 
   client_socket_->Disconnect();
@@ -731,9 +750,9 @@
 }
 
 TEST_F(SSLServerSocketTest, HandshakeWithClientCertRequiredNotSuppliedCached) {
-  ConfigureClientCertsForServer();
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForServer());
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
   // Use the default setting for the client socket, which is to not send
   // a client certificate. This will cause the client to receive an
   // ERR_SSL_CLIENT_AUTH_CERT_NEEDED error, and allow for inspecting the
@@ -755,6 +774,7 @@
   // handshake message is as expected.
   scoped_refptr<X509Certificate> client_cert =
       ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
+  ASSERT_TRUE(client_cert);
   EXPECT_TRUE(client_cert->IsIssuedByEncoded(request_info->cert_authorities));
 
   client_socket_->Disconnect();
@@ -763,7 +783,7 @@
   server_socket_->Disconnect();
 
   // Below, check that the cache didn't store the result of a failed handshake.
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
   TestCompletionCallback handshake_callback2;
   int server_ret2 = server_socket_->Handshake(handshake_callback2.callback());
 
@@ -787,11 +807,13 @@
 TEST_F(SSLServerSocketTest, HandshakeWithWrongClientCertSupplied) {
   scoped_refptr<X509Certificate> client_cert =
       ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
-  ConfigureClientCertsForClient(kWrongClientCertFileName,
-                                kWrongClientPrivateKeyFileName);
-  ConfigureClientCertsForServer();
-  CreateContext();
-  CreateSockets();
+  ASSERT_TRUE(client_cert);
+
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForClient(
+      kWrongClientCertFileName, kWrongClientPrivateKeyFileName));
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForServer());
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback;
   int server_ret = server_socket_->Handshake(handshake_callback.callback());
@@ -808,11 +830,13 @@
 TEST_F(SSLServerSocketTest, HandshakeWithWrongClientCertSuppliedCached) {
   scoped_refptr<X509Certificate> client_cert =
       ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
-  ConfigureClientCertsForClient(kWrongClientCertFileName,
-                                kWrongClientPrivateKeyFileName);
-  ConfigureClientCertsForServer();
-  CreateContext();
-  CreateSockets();
+  ASSERT_TRUE(client_cert);
+
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForClient(
+      kWrongClientCertFileName, kWrongClientPrivateKeyFileName));
+  ASSERT_NO_FATAL_FAILURE(ConfigureClientCertsForServer());
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback handshake_callback;
   int server_ret = server_socket_->Handshake(handshake_callback.callback());
@@ -829,7 +853,7 @@
   server_socket_->Disconnect();
 
   // Below, check that the cache didn't store the result of a failed handshake.
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
   TestCompletionCallback handshake_callback2;
   int server_ret2 = server_socket_->Handshake(handshake_callback2.callback());
 
@@ -844,8 +868,8 @@
 #endif  // defined(USE_OPENSSL)
 
 TEST_F(SSLServerSocketTest, DataTransfer) {
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   // Establish connection.
   TestCompletionCallback connect_callback;
@@ -928,8 +952,8 @@
 // the client's Write() call should not cause an infinite loop.
 // NOTE: this is a test for SSLClientSocket rather than SSLServerSocket.
 TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) {
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   // Establish connection.
   TestCompletionCallback connect_callback;
@@ -979,8 +1003,8 @@
 // after connecting them, and verifies that the results match.
 // This test will fail if False Start is enabled (see crbug.com/90208).
 TEST_F(SSLServerSocketTest, ExportKeyingMaterial) {
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback connect_callback;
   int client_ret = client_socket_->Connect(connect_callback.callback());
@@ -1040,8 +1064,8 @@
   // Require ECDHE on the server.
   server_ssl_config_.require_ecdhe = true;
 
-  CreateContext();
-  CreateSockets();
+  ASSERT_NO_FATAL_FAILURE(CreateContext());
+  ASSERT_NO_FATAL_FAILURE(CreateSockets());
 
   TestCompletionCallback connect_callback;
   int client_ret = client_socket_->Connect(connect_callback.callback());
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index c51ea58..e34345a 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -1174,17 +1174,6 @@
   return total_length;
 }
 
-void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
-                                  const SpdyMajorVersion spdy_version,
-                                  const SpdyHeaderBlock* headers) {
-  frame->WriteUInt32(headers->size());
-  SpdyHeaderBlock::const_iterator it;
-  for (it = headers->begin(); it != headers->end(); ++it) {
-    frame->WriteStringPiece32(it->first);
-    frame->WriteStringPiece32(it->second);
-  }
-}
-
 // TODO(phajdan.jr): Clean up after we no longer need
 // to workaround http://crbug.com/139744.
 #if !defined(USE_SYSTEM_ZLIB)
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 6fce783..30e7899b 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -352,10 +352,9 @@
   // purposes.)
   static const size_t kHeaderDataChunkMaxSize;
 
-  // Serializes a SpdyHeaderBlock.
-  static void WriteHeaderBlock(SpdyFrameBuilder* frame,
-                               const SpdyMajorVersion spdy_version,
-                               const SpdyHeaderBlock* headers);
+  void SerializeHeaderBlockWithoutCompression(
+      SpdyFrameBuilder* builder,
+      const SpdyHeaderBlock& header_block) const;
 
   // Retrieve serialized length of SpdyHeaderBlock.
   // TODO(hkhalil): Remove, or move to quic code.
@@ -691,10 +690,6 @@
   void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
                            z_stream* out) const;
 
-  void SerializeHeaderBlockWithoutCompression(
-      SpdyFrameBuilder* builder,
-      const SpdyHeaderBlock& header_block) const;
-
   // Compresses automatically according to enable_compression_.
   void SerializeHeaderBlock(SpdyFrameBuilder* builder,
                             const SpdyFrameWithHeaderBlockIR& frame);
diff --git a/remoting/host/audio_capturer_win.cc b/remoting/host/audio_capturer_win.cc
index 8c90113..86fd9595 100644
--- a/remoting/host/audio_capturer_win.cc
+++ b/remoting/host/audio_capturer_win.cc
@@ -54,6 +54,7 @@
   DCHECK(!audio_capture_client_.get());
   DCHECK(!audio_client_.get());
   DCHECK(!mm_device_.get());
+  DCHECK(!audio_volume_.get());
   DCHECK(static_cast<PWAVEFORMATEX>(wave_format_ex_) == nullptr);
   DCHECK(thread_checker_.CalledOnValidThread());
 
@@ -193,6 +194,15 @@
     return false;
   }
 
+  // Initialize ISimpleAudioVolume.
+  // TODO(zijiehe): Do we need to control per process volume?
+  hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume),
+                                 audio_volume_.ReceiveVoid());
+  if (FAILED(hr)) {
+    LOG(ERROR) << "Failed to get an ISimpleAudioVolume. Error " << hr;
+    return false;
+  }
+
   silence_detector_.Reset(sampling_rate_, kChannels);
 
   // Start capturing.
@@ -203,6 +213,70 @@
   return true;
 }
 
+float AudioCapturerWin::GetAudioLevel() {
+  BOOL mute;
+  HRESULT hr = audio_volume_->GetMute(&mute);
+  if (FAILED(hr)) {
+    return 1;
+  }
+  if (mute) {
+    return 0;
+  }
+
+  float level;
+  hr = audio_volume_->GetMasterVolume(&level);
+  if (FAILED(hr) || level > 1) {
+    return 1;
+  }
+  if (level < 0) {
+    return 0;
+  }
+  return level;
+}
+
+void AudioCapturerWin::ProcessSamples(uint8_t* data,
+                                      size_t frames,
+                                      int32_t flags) {
+  if (frames == 0) {
+    return;
+  }
+
+  if ((flags & AUDCLNT_BUFFERFLAGS_SILENT) == 0) {
+    return;
+  }
+
+  int16_t* samples = reinterpret_cast<int16_t*>(data);
+  static_assert(sizeof(samples[0]) == kBytesPerSample,
+                "expect 16 bits per sample");
+  size_t sample_count = frames * kChannels;
+  if (silence_detector_.IsSilence(samples, sample_count)) {
+    return;
+  }
+
+  float level = GetAudioLevel();
+  if (level == 0) {
+    return;
+  }
+
+  if (level < 1) {
+    // Windows API does not provide volume adjusted audio sample as Linux does.
+    // So we need to manually append volume signal to the samples.
+    int32_t level_int = static_cast<int32_t>(level * 65536);
+    for (size_t i = 0; i < sample_count; i++) {
+      samples[i] = (static_cast<int32_t>(samples[i]) * level_int) >> 16;
+    }
+  }
+
+  scoped_ptr<AudioPacket> packet(new AudioPacket());
+  packet->add_data(data, frames * wave_format_ex_->nBlockAlign);
+  packet->set_encoding(AudioPacket::ENCODING_RAW);
+  packet->set_sampling_rate(sampling_rate_);
+  packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
+  packet->set_channels(AudioPacket::CHANNELS_STEREO);
+
+  callback_.Run(std::move(packet));
+}
+
 void AudioCapturerWin::DoCapture() {
   DCHECK(AudioCapturer::IsValidSampleRate(sampling_rate_));
   DCHECK(thread_checker_.CalledOnValidThread());
@@ -227,18 +301,7 @@
     if (FAILED(hr))
       break;
 
-    if ((flags & AUDCLNT_BUFFERFLAGS_SILENT) == 0 &&
-        !silence_detector_.IsSilence(reinterpret_cast<const int16_t*>(data),
-                                     frames * kChannels)) {
-      scoped_ptr<AudioPacket> packet(new AudioPacket());
-      packet->add_data(data, frames * wave_format_ex_->nBlockAlign);
-      packet->set_encoding(AudioPacket::ENCODING_RAW);
-      packet->set_sampling_rate(sampling_rate_);
-      packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
-      packet->set_channels(AudioPacket::CHANNELS_STEREO);
-
-      callback_.Run(std::move(packet));
-    }
+    ProcessSamples(data, frames, flags);
 
     hr = audio_capture_client_->ReleaseBuffer(frames);
     if (FAILED(hr))
diff --git a/remoting/host/audio_capturer_win.h b/remoting/host/audio_capturer_win.h
index de3c7953..11070be 100644
--- a/remoting/host/audio_capturer_win.h
+++ b/remoting/host/audio_capturer_win.h
@@ -33,6 +33,16 @@
   // to the network.
   void DoCapture();
 
+  // Returns current volume setting of the host, in range [0.0, 1.0]. If the
+  // audio has been muted, this function returns 0. If Windows API returns error
+  // (such as audio device has been disabled or unpluged), this function ignores
+  // host volume setting, and returns 1.0.
+  float GetAudioLevel();
+
+  // Processes a series of samples, and executes callback if the packet is
+  // qualified to be sent to client.
+  void ProcessSamples(uint8_t* data, size_t frames, int32_t flags);
+
   PacketCapturedCallback callback_;
 
   AudioPacket::SamplingRate sampling_rate_;
@@ -46,6 +56,7 @@
   base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_;
   base::win::ScopedComPtr<IAudioClient> audio_client_;
   base::win::ScopedComPtr<IMMDevice> mm_device_;
+  base::win::ScopedComPtr<ISimpleAudioVolume> audio_volume_;
 
   HRESULT last_capture_error_;
 
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 7ddda70..20637541 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -500,9 +500,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -696,12 +693,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -1206,12 +1197,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -1908,12 +1893,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -2203,9 +2182,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -6451,12 +6427,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -6700,12 +6670,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -6988,9 +6952,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -7228,9 +7189,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index 982f1dc..dac874c 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -74,12 +74,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_runner_host_unittests"
       },
       {
@@ -818,12 +812,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_runner_host_unittests"
       },
       {
@@ -935,6 +923,12 @@
         "swarming": {
           "can_use_on_swarming_builders": true
         },
+        "test": "views_mus_unittests"
+      },
+      {
+        "swarming": {
+          "can_use_on_swarming_builders": true
+        },
         "test": "views_unittests"
       },
       {
@@ -1232,12 +1226,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -1615,12 +1603,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 3cf6772b..9b29c59 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -30,7 +30,6 @@
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_system_unittests",
-      "mojo_public_utility_unittests",
       "mojo_system_unittests",
       "ppapi_unittests",
       "printing_unittests",
@@ -243,12 +242,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -565,12 +558,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -887,12 +874,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -1210,12 +1191,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.memory.fyi.json b/testing/buildbot/chromium.memory.fyi.json
index ab8ad00..74efcba 100644
--- a/testing/buildbot/chromium.memory.fyi.json
+++ b/testing/buildbot/chromium.memory.fyi.json
@@ -277,7 +277,6 @@
       "midi_unittests",
       "mojo_system_unittests",
       "mojo_public_system_unittests",
-      "mojo_public_utility_unittests",
       "mojo_public_bindings_unittests",
       "mojo_common_unittests",
       "net_unittests",
@@ -315,7 +314,6 @@
       "cacheinvalidation_unittests",
       "mojo_system_unittests",
       "mojo_public_system_unittests",
-      "mojo_public_utility_unittests",
       "mojo_public_bindings_unittests",
       "mojo_common_unittests",
       "cast_unittests",
@@ -537,12 +535,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -833,12 +825,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -2104,9 +2090,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -2398,9 +2381,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -2531,9 +2511,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json
index e104989..018301b 100644
--- a/testing/buildbot/chromium.win.json
+++ b/testing/buildbot/chromium.win.json
@@ -253,12 +253,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -659,12 +653,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -1109,12 +1097,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -1487,12 +1469,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "swarming": {
-          "can_use_on_swarming_builders": true
-        },
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_system_unittests"
       },
       {
@@ -1731,9 +1707,6 @@
         "test": "mojo_public_system_unittests"
       },
       {
-        "test": "mojo_public_utility_unittests"
-      },
-      {
         "test": "mojo_runner_host_unittests"
       },
       {
diff --git a/testing/buildbot/chromium_trybot.json b/testing/buildbot/chromium_trybot.json
index 558cec1..4c967b1 100644
--- a/testing/buildbot/chromium_trybot.json
+++ b/testing/buildbot/chromium_trybot.json
@@ -224,7 +224,6 @@
     "mojo_common_unittests",
     "mojo_public_bindings_unittests",
     "mojo_public_system_unittests",
-    "mojo_public_utility_unittests",
     "mojo_system_unittests",
     {
       "platforms": [
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json
index 89757b6..bc7c405 100644
--- a/testing/buildbot/client.v8.fyi.json
+++ b/testing/buildbot/client.v8.fyi.json
@@ -40,7 +40,6 @@
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_system_unittests",
-      "mojo_public_utility_unittests",
       "mojo_system_unittests",
       "nacl_loader_unittests",
       "net_unittests",
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 85bb482..75c8d80 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -356,10 +356,6 @@
     "label": "//mojo/edk/test:mojo_public_system_unittests",
     "type": "console_test_launcher",
   },
-  "mojo_public_utility_unittests": {
-    "label": "//mojo/edk/test:mojo_public_utility_unittests",
-    "type": "console_test_launcher",
-  },
   "mojo_runner_host_unittests": {
     "label": "//mojo/runner/host:unittests",
     "type": "unknown",
diff --git a/testing/buildbot/tryserver.v8.json b/testing/buildbot/tryserver.v8.json
index 7ccbded..2852105c 100644
--- a/testing/buildbot/tryserver.v8.json
+++ b/testing/buildbot/tryserver.v8.json
@@ -40,7 +40,6 @@
       "mojo_common_unittests",
       "mojo_public_bindings_unittests",
       "mojo_public_system_unittests",
-      "mojo_public_utility_unittests",
       "mojo_system_unittests",
       "nacl_loader_unittests",
       "net_unittests",
diff --git a/testing/libfuzzer/BUILD.gn b/testing/libfuzzer/BUILD.gn
index 16ef1e7c..2063f92 100644
--- a/testing/libfuzzer/BUILD.gn
+++ b/testing/libfuzzer/BUILD.gn
@@ -42,3 +42,7 @@
 # building an archive for clusterfuzz.
 config("no_clusterfuzz") {
 }
+
+# noop to tag seed corpus rules.
+source_set("seed_corpus") {
+}
diff --git a/testing/libfuzzer/fuzzer_test.gni b/testing/libfuzzer/fuzzer_test.gni
index 58742329..266016c 100644
--- a/testing/libfuzzer/fuzzer_test.gni
+++ b/testing/libfuzzer/fuzzer_test.gni
@@ -71,6 +71,9 @@
         outputs = [
           out,
         ]
+        deps = [
+          "//testing/libfuzzer:seed_corpus",
+        ]
       }
 
       test_deps += [ ":" + target_name + "_seed_corpus" ]
diff --git a/testing/scripts/common.py b/testing/scripts/common.py
index dabd96e1..3356aa7 100644
--- a/testing/scripts/common.py
+++ b/testing/scripts/common.py
@@ -77,10 +77,10 @@
   else:
     cmd = [
       sys.executable,
-      os.path.join(cmd_args.paths['build'], 'scripts', 'tools', 'runit.py'),
+      cmd_args.paths['runit.py'],
       '--show-path',
       sys.executable,
-      os.path.join(cmd_args.paths['build'], 'scripts', 'slave', 'runtest.py'),
+      cmd_args.paths['runtest.py'],
     ]
   return run_command(cmd + [
       '--target', cmd_args.build_config_fs,
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 62c2cb3..b418031 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -52,7 +52,6 @@
 
 # See also crbug.com/521730 for the these two text/emphasis tests (non-Oilpan) Win10 failures.
 crbug.com/574660 [ Win7 ] fast/text/emphasis-combined-text.html [ Pass Failure ]
-crbug.com/574660 [ Win7 ] fast/text/emphasis-vertical.html [ Pass Failure ]
 
 crbug.com/581974 fast/text/justify-ideograph-vertical.html [ Pass Failure ]
 crbug.com/584211 [ Mac Debug ] svg/transforms/animated-path-inside-transformed-html.xhtml [ Pass Failure ]
@@ -849,6 +848,7 @@
 
 crbug.com/364250 [ Debug ] virtual/threaded/animations/interpolation/transform-interpolation.html [ Pass Crash ]
 crbug.com/364250 [ Debug ] virtual/threaded/animations/interpolation/webkit-transform-interpolation.html [ Pass Crash ]
+crbug.com/522396 web-animations-api/animation-state-changes-negative-playback-rate.html [ Skip ]
 
 crbug.com/467477 fast/multicol/vertical-rl/nested-columns.html [ Failure ]
 
@@ -1103,9 +1103,7 @@
 crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-align-08-b.svg [ NeedsRebaseline ]
 crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-fonts-01-t.svg [ NeedsRebaseline ]
 crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-intro-01-t.svg [ NeedsRebaseline ]
-crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-intro-03-b.svg [ NeedsRebaseline ]
 crbug.com/579842 [ Win ] svg/W3C-SVG-1.1/text-intro-04-t.svg [ NeedsRebaseline ]
-crbug.com/579842 [ Win ] svg/batik/text/verticalText.svg [ NeedsRebaseline ]
 crbug.com/579842 [ Win ] svg/text/text-selection-fonts-01-t.svg [ NeedsRebaseline ]
 
 crbug.com/501659 fast/xsl/xslt-missing-namespace-in-xslt.xml [ Failure ]
@@ -1260,6 +1258,46 @@
 crbug.com/353746 virtual/android/fullscreen/video-specified-size.html [ Failure Pass ]
 
 crbug.com/589525 svg/text/lengthAdjust-text-metrics.html [ NeedsRebaseline ]
+crbug.com/589525 svg/text/ligature-queries.html [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-squeeze-1.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-squeeze-2.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-squeeze-3.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-squeeze-4.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-stretch-1.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-stretch-2.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-stretch-3.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/select-textLength-spacing-stretch-4.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/W3C-SVG-1.1/text-intro-03-b.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/W3C-SVG-1.1/text-path-01-b.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/W3C-SVG-1.1/text-spacing-01-b.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/W3C-SVG-1.1/text-text-07-t.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/longTextOnPath.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/smallFonts.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/textLayout.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/textLayout2.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/textOnPath3.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/textOnPathSpaces.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/verticalText.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/batik/text/verticalTextOnPath.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/custom/glyph-transformation-with-hkern.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/dynamic-updates/SVGTextElement-dom-rotate-attr.html [ NeedsRebaseline ]
+crbug.com/589525 svg/text/bidi-reorder-value-lists.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/bidi-text-query.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/non-bmp-positioning-lists.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/text-selection-path-01-b.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/text-selection-spacing-01-b.svg [ NeedsRebaseline ]
+crbug.com/589525 svg/text/text-selection-text-07-t.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Mac ] svg/W3C-SVG-1.1/text-text-06-t.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Mac ] svg/text/text-selection-text-06-t.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Mac ] svg/W3C-SVG-1.1-SE/text-tspan-02-b.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Win ] svg/W3C-SVG-1.1/struct-frag-02-t.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Win ] svg/custom/stroke-width-large.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Linux ] svg/W3C-SVG-1.1/metadata-example-01-b.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Linux ] svg/W3C-SVG-1.1/text-text-01-b.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Linux ] svg/text/select-x-list-with-tspans-4.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Win Linux ] svg/text/text-rescale.html [ NeedsRebaseline ]
+crbug.com/589525 [ Win Linux ] svg/carto.net/textbox.svg [ NeedsRebaseline ]
+crbug.com/589525 [ Win Linux ] svg/custom/text-match-highlight.html [ NeedsRebaseline ]
 
 crbug.com/527270 accessibility/name-calc-img.html [ Failure Pass Timeout ]
 
@@ -1379,7 +1417,6 @@
 crbug.com/591821 fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure Pass ]
 crbug.com/591821 fast/events/mouse-drag-from-frame-to-other-frame.html [ Failure Pass ]
 crbug.com/591821 fast/events/mouse-drag-from-frame.html [ Failure Pass ]
-crbug.com/591821 fast/events/mouse-event-buttons-attribute.html [ Failure Pass ]
 crbug.com/591821 fast/events/mouse-relative-position.html [ Failure Pass ]
 crbug.com/591821 fast/events/mouse-wheel-main-frame-scroll.html [ Pass Timeout ]
 crbug.com/591821 fast/events/scale-and-scroll-iframe-body.html [ Pass Timeout ]
@@ -1393,7 +1430,6 @@
 crbug.com/591821 virtual/pointerevent/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure Pass ]
 crbug.com/591821 virtual/pointerevent/fast/events/mouse-drag-from-frame-to-other-frame.html [ Failure Pass ]
 crbug.com/591821 virtual/pointerevent/fast/events/mouse-drag-from-frame.html [ Failure Pass ]
-crbug.com/591821 virtual/pointerevent/fast/events/mouse-event-buttons-attribute.html [ Failure Pass ]
 crbug.com/591821 virtual/pointerevent/fast/events/mouse-relative-position.html [ Failure Pass ]
 crbug.com/591821 virtual/pointerevent/fast/events/mouse-wheel-main-frame-scroll.html [ Pass Timeout ]
 crbug.com/591821 virtual/pointerevent/fast/events/scale-and-scroll-iframe-body.html [ Failure Pass ]
@@ -1408,12 +1444,17 @@
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure Pass ]
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/mouse-drag-from-frame-to-other-frame.html [ Failure Pass ]
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/mouse-drag-from-frame.html [ Failure Pass ]
-crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/mouse-event-buttons-attribute.html [ Failure Pass ]
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/mouse-relative-position.html [ Failure Pass ]
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/mouse-wheel-main-frame-scroll.html [ Pass Timeout ]
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/scale-and-scroll-iframe-body.html [ Failure Pass ]
 crbug.com/591821 virtual/trustedeventsdefaultaction/fast/events/updateLayoutForHitTest.html [ Failure Pass ]
 
+crbug.com/593888 [ Linux Debug ] fast/dom/htmlcollection-reachable.html [ Timeout ]
+
+crbug.com/593917 fast/writing-mode/japanese-rl-selection.html [ NeedsRebaseline ]
+crbug.com/593917 fast/text/emphasis-vertical.html [ NeedsRebaseline ]
+crbug.com/593917 fast/writing-mode/japanese-lr-selection.html [ NeedsRebaseline ]
+
 crbug.com/593568 [ Win Debug ] virtual/threaded/fast/scroll-behavior/smooth-scroll/horizontal-smooth-scroll-in-rtl.html [ Failure ] 
 
 crbug.com/591825 [ Mac10.11 Debug ] fast/text/selection-multiple-runs.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/backdrop-filter-interpolation-expected.txt b/third_party/WebKit/LayoutTests/animations/interpolation/backdrop-filter-interpolation-expected.txt
index c9fd2c5..5977c871 100644
--- a/third_party/WebKit/LayoutTests/animations/interpolation/backdrop-filter-interpolation-expected.txt
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/backdrop-filter-interpolation-expected.txt
@@ -251,16 +251,16 @@
 PASS CSS Animations: property <backdrop-filter> from [none] to [sepia(1)] at (0.5) is [sepia(0.5)] 
 PASS CSS Animations: property <backdrop-filter> from [none] to [sepia(1)] at (1) is [sepia(1)] 
 PASS CSS Animations: property <backdrop-filter> from [none] to [sepia(1)] at (1.5) is [sepia(1)] 
-PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (-0.3) is [url('#svgfilter')] 
-PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0) is [url('#svgfilter')] 
-PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.3) is [url('#svgfilter')] 
+PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (-0.3) is [url("#svgfilter")] 
+PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0) is [url("#svgfilter")] 
+PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.3) is [url("#svgfilter")] 
 PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.5) is [none] 
 PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.6) is [none] 
 PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (1) is [none] 
 PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (1.5) is [none] 
-PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (-0.3) is [url('#svgfilter')] 
-PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0) is [url('#svgfilter')] 
-PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.3) is [url('#svgfilter')] 
+PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (-0.3) is [url("#svgfilter")] 
+PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0) is [url("#svgfilter")] 
+PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.3) is [url("#svgfilter")] 
 PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.5) is [blur(5px)] 
 PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.6) is [blur(5px)] 
 PASS CSS Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (1) is [blur(5px)] 
@@ -380,16 +380,16 @@
 PASS Web Animations: property <backdrop-filter> from [none] to [sepia(1)] at (0.5) is [sepia(0.5)] 
 PASS Web Animations: property <backdrop-filter> from [none] to [sepia(1)] at (1) is [sepia(1)] 
 PASS Web Animations: property <backdrop-filter> from [none] to [sepia(1)] at (1.5) is [sepia(1)] 
-PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (-0.3) is [url('#svgfilter')] 
-PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0) is [url('#svgfilter')] 
-PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.3) is [url('#svgfilter')] 
+PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (-0.3) is [url("#svgfilter")] 
+PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0) is [url("#svgfilter")] 
+PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.3) is [url("#svgfilter")] 
 PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.5) is [none] 
 PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (0.6) is [none] 
 PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (1) is [none] 
 PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [none] at (1.5) is [none] 
-PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (-0.3) is [url('#svgfilter')] 
-PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0) is [url('#svgfilter')] 
-PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.3) is [url('#svgfilter')] 
+PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (-0.3) is [url("#svgfilter")] 
+PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0) is [url("#svgfilter")] 
+PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.3) is [url("#svgfilter")] 
 PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.5) is [blur(5px)] 
 PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (0.6) is [blur(5px)] 
 PASS Web Animations: property <backdrop-filter> from [url("#svgfilter")] to [blur(5px)] at (1) is [blur(5px)] 
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/filter-interpolation-expected.txt b/third_party/WebKit/LayoutTests/animations/interpolation/filter-interpolation-expected.txt
index a183ef0..0bbae085 100644
--- a/third_party/WebKit/LayoutTests/animations/interpolation/filter-interpolation-expected.txt
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/filter-interpolation-expected.txt
@@ -251,16 +251,16 @@
 PASS CSS Animations: property <-webkit-filter> from [none] to [sepia(1)] at (0.5) is [sepia(0.5)] 
 PASS CSS Animations: property <-webkit-filter> from [none] to [sepia(1)] at (1) is [sepia(1)] 
 PASS CSS Animations: property <-webkit-filter> from [none] to [sepia(1)] at (1.5) is [sepia(1)] 
-PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (-0.3) is [url('#svgfilter')] 
-PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (0) is [url('#svgfilter')] 
-PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (0.3) is [url('#svgfilter')] 
+PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (-0.3) is [url("#svgfilter")] 
+PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (0) is [url("#svgfilter")] 
+PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (0.3) is [url("#svgfilter")] 
 PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (0.5) is [none] 
 PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (0.6) is [none] 
 PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (1) is [none] 
 PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [none] at (1.5) is [none] 
-PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (-0.3) is [url('#svgfilter')] 
-PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (0) is [url('#svgfilter')] 
-PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (0.3) is [url('#svgfilter')] 
+PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (-0.3) is [url("#svgfilter")] 
+PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (0) is [url("#svgfilter")] 
+PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (0.3) is [url("#svgfilter")] 
 PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (0.5) is [blur(5px)] 
 PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (0.6) is [blur(5px)] 
 PASS CSS Animations: property <-webkit-filter> from [url("#svgfilter")] to [blur(5px)] at (1) is [blur(5px)] 
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/resources/interpolation-test.js b/third_party/WebKit/LayoutTests/animations/interpolation/resources/interpolation-test.js
index 14a138d..c1d4a1e 100644
--- a/third_party/WebKit/LayoutTests/animations/interpolation/resources/interpolation-test.js
+++ b/third_party/WebKit/LayoutTests/animations/interpolation/resources/interpolation-test.js
@@ -213,10 +213,10 @@
 
   var anchor = document.createElement('a');
   function sanitizeUrls(value) {
-    var matches = value.match(/url\("([^\)]*)"\)/g);
+    var matches = value.match(/url\("([^#][^\)]*)"\)/g);
     if (matches !== null) {
       for (var i = 0; i < matches.length; ++i) {
-        var url = /url\("([^\)]*)"\)/g.exec(matches[i])[1];
+        var url = /url\("([^#][^\)]*)"\)/g.exec(matches[i])[1];
         anchor.href = url;
         anchor.pathname = '...' + anchor.pathname.substring(anchor.pathname.lastIndexOf('/'));
         value = value.replace(matches[i], 'url(' + anchor.href + ')');
diff --git a/third_party/WebKit/LayoutTests/css3/filters/filter-property-computed-style-expected.txt b/third_party/WebKit/LayoutTests/css3/filters/filter-property-computed-style-expected.txt
index b596638..24298f35 100644
--- a/third_party/WebKit/LayoutTests/css3/filters/filter-property-computed-style-expected.txt
+++ b/third_party/WebKit/LayoutTests/css3/filters/filter-property-computed-style-expected.txt
@@ -5,16 +5,16 @@
 
 
 Basic reference : url('#a')
-PASS filterStyle is "url('#a')"
+PASS filterStyle is "url(\"#a\")"
 
 Bare unquoted reference converting to quoted form : url(#a)
-PASS filterStyle is "url('#a')"
+PASS filterStyle is "url(\"#a\")"
 
 Multiple references : url('#a') url('#b')
-PASS filterStyle is "url('#a') url('#b')"
+PASS filterStyle is "url(\"#a\") url(\"#b\")"
 
 Reference as 2nd value : grayscale(1) url('#a')
-PASS filterStyle is "grayscale(1) url('#a')"
+PASS filterStyle is "grayscale(1) url(\"#a\")"
 
 Integer value : grayscale(1)
 PASS filterStyle is "grayscale(1)"
diff --git a/third_party/WebKit/LayoutTests/css3/filters/script-tests/filter-property-computed-style.js b/third_party/WebKit/LayoutTests/css3/filters/script-tests/filter-property-computed-style.js
index 7a73edd..e9b6c5da 100644
--- a/third_party/WebKit/LayoutTests/css3/filters/script-tests/filter-property-computed-style.js
+++ b/third_party/WebKit/LayoutTests/css3/filters/script-tests/filter-property-computed-style.js
@@ -21,10 +21,10 @@
     stylesheet.deleteRule(0);
 }
 
-testComputedFilterRule("Basic reference", "url('#a')");
-testComputedFilterRule("Bare unquoted reference converting to quoted form", "url(#a)", "url('#a')");
-testComputedFilterRule("Multiple references", "url('#a') url('#b')");
-testComputedFilterRule("Reference as 2nd value", "grayscale(1) url('#a')");
+testComputedFilterRule("Basic reference", "url('#a')", 'url("#a")');
+testComputedFilterRule("Bare unquoted reference converting to quoted form", "url(#a)", 'url("#a")');
+testComputedFilterRule("Multiple references", "url('#a') url('#b')", 'url("#a") url("#b")');
+testComputedFilterRule("Reference as 2nd value", "grayscale(1) url('#a')", 'grayscale(1) url("#a")');
 testComputedFilterRule("Integer value", "grayscale(1)");
 testComputedFilterRule("Float value converts to integer", "grayscale(1.0)", "grayscale(1)");
 testComputedFilterRule("Zero value", "grayscale(0)");
diff --git a/third_party/WebKit/LayoutTests/editing/input/paste-linebreak-into-initially-hidden-textarea.html b/third_party/WebKit/LayoutTests/editing/input/paste-linebreak-into-initially-hidden-textarea.html
index c1c337f..10b7d6a 100644
--- a/third_party/WebKit/LayoutTests/editing/input/paste-linebreak-into-initially-hidden-textarea.html
+++ b/third_party/WebKit/LayoutTests/editing/input/paste-linebreak-into-initially-hidden-textarea.html
@@ -18,7 +18,7 @@
 textarea.selectionStart = textarea.selectionEnd = 0;
 document.execCommand('insertHTML', false, 'hello\nworld\n');
 
-var expected = 'hello\nworld\nwebkit';
+var expected = 'hello\nworld\n\nwebkit';
 if (textarea.value == expected)
     document.getElementById('log').innerText = 'PASS';
 else
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt
index 3953b477..4c70c74 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set-expected.txt
@@ -4,30 +4,30 @@
 
 
 Test auto-repeat syntax.
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[foo bar] 10px"
-PASS element.style.gridTemplateColumns is "[foo bar] 10px"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "20px [foo bar]"
-PASS element.style.gridTemplateRows is "2em [foo bar]"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[foo bar] 800px"
-PASS element.style.gridTemplateColumns is "[foo bar] minmax(10px, 1fr)"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "[foo] 20px [bar]"
-PASS element.style.gridTemplateRows is "[foo] minmax(2em, max-content) [bar]"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "100px 20px 20px"
-PASS element.style.gridTemplateColumns is "minmax(10px, 100px) 20px 20px"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "70px 20px [bar foo] 10px [foo] 10px"
-PASS element.style.gridTemplateRows is "70px minmax(2em, max-content) [bar] [foo] 1em [foo] 1em"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[foo bar] 10px"
-PASS element.style.gridTemplateColumns is "[foo bar] 10px"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "20px [foo bar]"
-PASS element.style.gridTemplateRows is "2em [foo bar]"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "[foo bar] 800px"
-PASS element.style.gridTemplateColumns is "[foo bar] minmax(10px, 1fr)"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "[foo] 20px [bar]"
-PASS element.style.gridTemplateRows is "[foo] minmax(2em, max-content) [bar]"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "10px 20px 20px"
-PASS element.style.gridTemplateColumns is "minmax(10px, min-content) 20px 20px"
-PASS getComputedStyle(element, '').getPropertyValue('grid-template-rows') is "60px 20px [bar foo] 10px [foo] 10px"
-PASS element.style.gridTemplateRows is "10% minmax(2em, max-content) [bar] [foo] 1em [foo] 1em"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-columns') should be [foo bar] 10px. Was 0px.
+PASS element.style.gridTemplateColumns is "repeat(auto-fill, [foo bar] 10px)"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-rows') should be 20px [foo bar]. Was 0px.
+PASS element.style.gridTemplateRows is "repeat(auto-fill, 2em [foo bar])"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-columns') should be [foo bar] 800px. Was 0px.
+PASS element.style.gridTemplateColumns is "repeat(auto-fill, [foo bar] minmax(10px, 1fr))"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-rows') should be [foo] 20px [bar]. Was 0px.
+PASS element.style.gridTemplateRows is "repeat(auto-fill, [foo] minmax(2em, max-content) [bar])"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-columns') should be 100px 20px 20px. Was 20px 20px.
+PASS element.style.gridTemplateColumns is "repeat(auto-fill, minmax(10px, 100px)) 20px 20px"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-rows') should be 70px 20px [bar foo] 10px [foo] 10px. Was 70px 10px [foo] 10px [foo].
+PASS element.style.gridTemplateRows is "70px repeat(auto-fill, minmax(2em, max-content) [bar]) [foo] 1em [foo] 1em"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-columns') should be [foo bar] 10px. Was 0px.
+PASS element.style.gridTemplateColumns is "repeat(auto-fit, [foo bar] 10px)"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-rows') should be 20px [foo bar]. Was 0px.
+PASS element.style.gridTemplateRows is "repeat(auto-fit, 2em [foo bar])"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-columns') should be [foo bar] 800px. Was 0px.
+PASS element.style.gridTemplateColumns is "repeat(auto-fit, [foo bar] minmax(10px, 1fr))"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-rows') should be [foo] 20px [bar]. Was 0px.
+PASS element.style.gridTemplateRows is "repeat(auto-fit, [foo] minmax(2em, max-content) [bar])"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-columns') should be 10px 20px 20px. Was 20px 20px.
+PASS element.style.gridTemplateColumns is "repeat(auto-fit, minmax(10px, min-content)) 20px 20px"
+FAIL getComputedStyle(element, '').getPropertyValue('grid-template-rows') should be 60px 20px [bar foo] 10px [foo] 10px. Was 60px 10px [foo] 10px [foo].
+PASS element.style.gridTemplateRows is "10% repeat(auto-fit, minmax(2em, max-content) [bar]) [foo] 1em [foo] 1em"
 
 Test invalid repeat syntax.
 PASS window.getComputedStyle(element, '').getPropertyValue('grid-template-columns') is "none"
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html
index 94f18a54..ebfa116 100644
--- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html
+++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-element-auto-repeat-get-set.html
@@ -9,12 +9,12 @@
     description('Test that setting/getting grid-template-{columns|rows} with repeat(auto-fill|auto-fit,) works as expected');
 
     debug("Test auto-repeat syntax.");
-    testGridDefinitionsSetJSValues("repeat(auto-fill, [foo bar] 10px)", "repeat(auto-fill, 2em [foo bar])", "[foo bar] 10px", "20px [foo bar]", "[foo bar] 10px", "2em [foo bar]");
-    testGridDefinitionsSetJSValues("repeat(auto-fill, [foo bar] minmax(10px, 1fr))", "repeat(auto-fill, [foo] minmax(2em, max-content) [bar])", "[foo bar] 800px", "[foo] 20px [bar]", "[foo bar] minmax(10px, 1fr)", "[foo] minmax(2em, max-content) [bar]");
-    testGridDefinitionsSetJSValues("repeat(auto-fill, minmax(10px, 100px)) repeat(2, 20px)", "repeat(1, 70px) repeat(auto-fill, minmax(2em, max-content) [bar]) repeat(2, [foo] 1em)", "100px 20px 20px", "70px 20px [bar foo] 10px [foo] 10px", "minmax(10px, 100px) 20px 20px", "70px minmax(2em, max-content) [bar] [foo] 1em [foo] 1em");
-    testGridDefinitionsSetJSValues("repeat(auto-fit, [foo bar] 10px)", "repeat(auto-fit, 2em [foo bar])", "[foo bar] 10px", "20px [foo bar]", "[foo bar] 10px", "2em [foo bar]");
-    testGridDefinitionsSetJSValues("repeat(auto-fit, [foo bar] minmax(10px, 1fr))", "repeat(auto-fit, [foo] minmax(2em, max-content) [bar])", "[foo bar] 800px", "[foo] 20px [bar]", "[foo bar] minmax(10px, 1fr)", "[foo] minmax(2em, max-content) [bar]");
-    testGridDefinitionsSetJSValues("repeat(auto-fit, minmax(10px, min-content)) repeat(2, 20px)", "repeat(1, 10%) repeat(auto-fit, minmax(2em, max-content) [bar]) repeat(2, [foo] 1em)", "10px 20px 20px", "60px 20px [bar foo] 10px [foo] 10px", "minmax(10px, min-content) 20px 20px", "10% minmax(2em, max-content) [bar] [foo] 1em [foo] 1em");
+    testGridDefinitionsSetJSValues("repeat(auto-fill, [foo bar] 10px)", "repeat(auto-fill, 2em [foo bar])", "[foo bar] 10px", "20px [foo bar]", "repeat(auto-fill, [foo bar] 10px)", "repeat(auto-fill, 2em [foo bar])");
+    testGridDefinitionsSetJSValues("repeat(auto-fill, [foo bar] minmax(10px, 1fr))", "repeat(auto-fill, [foo] minmax(2em, max-content) [bar])", "[foo bar] 800px", "[foo] 20px [bar]", "repeat(auto-fill, [foo bar] minmax(10px, 1fr))", "repeat(auto-fill, [foo] minmax(2em, max-content) [bar])");
+    testGridDefinitionsSetJSValues("repeat(auto-fill, minmax(10px, 100px)) repeat(2, 20px)", "repeat(1, 70px) repeat(auto-fill, minmax(2em, max-content) [bar]) repeat(2, [foo] 1em)", "100px 20px 20px", "70px 20px [bar foo] 10px [foo] 10px", "repeat(auto-fill, minmax(10px, 100px)) 20px 20px", "70px repeat(auto-fill, minmax(2em, max-content) [bar]) [foo] 1em [foo] 1em");
+    testGridDefinitionsSetJSValues("repeat(auto-fit, [foo bar] 10px)", "repeat(auto-fit, 2em [foo bar])", "[foo bar] 10px", "20px [foo bar]", "repeat(auto-fit, [foo bar] 10px)", "repeat(auto-fit, 2em [foo bar])");
+    testGridDefinitionsSetJSValues("repeat(auto-fit, [foo bar] minmax(10px, 1fr))", "repeat(auto-fit, [foo] minmax(2em, max-content) [bar])", "[foo bar] 800px", "[foo] 20px [bar]", "repeat(auto-fit, [foo bar] minmax(10px, 1fr))", "repeat(auto-fit, [foo] minmax(2em, max-content) [bar])");
+    testGridDefinitionsSetJSValues("repeat(auto-fit, minmax(10px, min-content)) repeat(2, 20px)", "repeat(1, 10%) repeat(auto-fit, minmax(2em, max-content) [bar]) repeat(2, [foo] 1em)", "10px 20px 20px", "60px 20px [bar foo] 10px [foo] 10px", "repeat(auto-fit, minmax(10px, min-content)) 20px 20px", "10% repeat(auto-fit, minmax(2em, max-content) [bar]) [foo] 1em [foo] 1em");
 
     debug("");
     debug("Test invalid repeat syntax.");
diff --git a/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute-expected.txt b/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute-expected.txt
index b12b0b4..2d94dff 100644
--- a/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute-expected.txt
@@ -1,3 +1,6 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
 ===== doubleClickAction with initial state=[] =====
 1. targetDiv received mouseover buttons: 0
 2. targetDiv received mouseenter buttons: 0
@@ -206,7 +209,4 @@
 23. targetDiv received mouseout buttons: 6
 24. targetDiv received mouseleave buttons: 6
 
-PASS successfullyParsed is true
-
-TEST COMPLETE
 
diff --git a/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute.html b/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute.html
index cc8ad65..f2416024 100644
--- a/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute.html
+++ b/third_party/WebKit/LayoutTests/fast/events/mouse-event-buttons-attribute.html
@@ -14,9 +14,9 @@
   top: 100px;
 }
 </style>
-
 <div id="target"></div>
 <img id="drag" src="resources/greenbox30.png" draggable>
+
 <script src="../../resources/js-test.js"></script>
 <script>
 
@@ -24,8 +24,6 @@
 const R = 'rightButton';
 const M = 'middleButton';
 
-var targetDiv = document.getElementById('target');
-var dragImg = document.getElementById('drag');
 var seqNo = 0;
 var testSet = [
   { initialButtons: [],        action: doubleClickAction },
@@ -125,6 +123,8 @@
 }
 
 function init() {
+  var targetDiv = document.getElementById('target');
+  var dragImg = document.getElementById('drag');
   var eventList = ['dblclick', 'click', 'mousedown', 'mouseup', 'mousemove', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'mousewheel', 'dragstart', 'dragend', 'dragenter', 'dragleave', 'dragover', 'drag', 'contextmenu'];
   eventList.forEach(function(eventName) {
     targetDiv.addEventListener(eventName, function(event) {
@@ -136,28 +136,29 @@
   });
 }
 
-function runTests() {
-  for (var i = 0; i < testSet.length; i++) {
-    printTestInfo(testSet[i]);
+window.onload=function() {
+  init();
+  if(window.eventSender) {
+    for (var i = 0; i < testSet.length; i++) {
+      printTestInfo(testSet[i]);
 
-    // Reset the state for the new test
-    seqNo = 0;
-    eventSender.setMouseButtonState(-1, testSet[i].initialButtons);
-    internals.settings.setShowContextMenuOnMouseUp(testSet[i].showContextMenuOnMouseUp);
+      // Reset the state for the new test
+      seqNo = 0;
+      eventSender.setMouseButtonState(-1, testSet[i].initialButtons);
+      internals.settings.setShowContextMenuOnMouseUp(testSet[i].showContextMenuOnMouseUp);
 
-    testSet[i].action();
+      testSet[i].action();
 
-    // Reset the mouse position
-    eventSender.mouseMoveTo(-1, -1);
+      // Reset the mouse position
+      eventSender.mouseMoveTo(-1, -1);
 
-    debug('');
+      debug('');
+    }
   }
 }
 
-init();
-if (window.eventSender)
-  runTests();
-else
+if (!window.eventSender) {
   debug("This test requires eventSender");
+}
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol-expected.txt
deleted file mode 100644
index dd9963d..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL TEXTAREA with white-space:nowrap should not increase the number of EOLs assert_equals: expected "a\n\n   b\n" but got "a b "
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol.html b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol.html
index 0bca8f1..d4224f6 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-nowrap-paste-eol.html
@@ -14,8 +14,6 @@
     });
     document.execCommand('copy');
     document.execCommand('paste');
-    // TODO(tkent): The following assertion fails now. crbug.com/2007 and
-    // crbug.com/528491.
     assert_equals(textarea.value, 'a\n\n   b\n');
 }, 'TEXTAREA with white-space:nowrap should not increase the number of EOLs');
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol-expected.txt
deleted file mode 100644
index 2c3c90c..0000000
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL TEXTAREA with white-space:pre-line should not produce nbsp by Enter key assert_equals: expected "P1\n\nP2\n\n\n\nP3\n" but got "P1\n\nP2\n\n  P3\n"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol.html b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol.html
index 781d49a..b0ddb42e 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-preline-eol.html
@@ -17,7 +17,6 @@
     eventSender.keyDown('\n');
     eventSender.keyDown('upArrow');
     eventSender.keyDown('\n');
-    // TODO(tkent): The following assertion fails now. crbug.com/410417
     assert_equals(textarea.value, 'P1\n\nP2\n\n\n\nP3\n');
 }, 'TEXTAREA with white-space:pre-line should not produce nbsp by Enter key');
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/images/resources/full2loop.gif b/third_party/WebKit/LayoutTests/fast/images/resources/full2loop.gif
new file mode 100644
index 0000000..e003421
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/images/resources/full2loop.gif
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/js/script-tests/string-match.js b/third_party/WebKit/LayoutTests/fast/js/script-tests/string-match.js
deleted file mode 100644
index 92a1f65..0000000
--- a/third_party/WebKit/LayoutTests/fast/js/script-tests/string-match.js
+++ /dev/null
@@ -1,24 +0,0 @@
-description(
-"String.match(&hellip;) test"
-);
-
-// match with a global regexp should set lastIndex to zero; if read-only this should throw.
-// If the regexp is not global, lastIndex is not modified.
-var re;
-function testMatch(_re, readonly)
-{
-    re = _re;
-    re.lastIndex = 3;
-    if (readonly)
-        re = Object.defineProperty(re, 'lastIndex', {writable:false});
-    return '0x1x2'.match(re);
-}
-
-shouldBe("testMatch(/x/g, false)", '["x","x"]');
-shouldThrow("testMatch(/x/g, true)");
-shouldBe("testMatch(/x/, false)", '["x"]');
-shouldBe("testMatch(/x/, true)", '["x"]');
-shouldBe("testMatch(/x/g, false); re.lastIndex", '0');
-shouldThrow("testMatch(/x/g, true); re.lastIndex");
-shouldBe("testMatch(/x/, false); re.lastIndex", '3');
-shouldBe("testMatch(/x/, true); re.lastIndex", '3');
diff --git a/third_party/WebKit/LayoutTests/fast/js/string-match-expected.txt b/third_party/WebKit/LayoutTests/fast/js/string-match-expected.txt
deleted file mode 100644
index 4b28c42..0000000
--- a/third_party/WebKit/LayoutTests/fast/js/string-match-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-String.match(…) test
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS testMatch(/x/g, false) is ["x","x"]
-FAIL testMatch(/x/g, true) should throw an exception. Was x,x.
-PASS testMatch(/x/, false) is ["x"]
-PASS testMatch(/x/, true) is ["x"]
-PASS testMatch(/x/g, false); re.lastIndex is 0
-FAIL testMatch(/x/g, true); re.lastIndex should throw an exception. Was 3.
-PASS testMatch(/x/, false); re.lastIndex is 3
-PASS testMatch(/x/, true); re.lastIndex is 3
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/js/string-match.html b/third_party/WebKit/LayoutTests/fast/js/string-match.html
deleted file mode 100644
index 6128120..0000000
--- a/third_party/WebKit/LayoutTests/fast/js/string-match.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<script src="script-tests/string-match.js"></script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/text/emphasis-vertical.html b/third_party/WebKit/LayoutTests/fast/text/emphasis-vertical.html
index d33a81d..1e57bd93 100644
--- a/third_party/WebKit/LayoutTests/fast/text/emphasis-vertical.html
+++ b/third_party/WebKit/LayoutTests/fast/text/emphasis-vertical.html
@@ -1,10 +1,11 @@
 <!doctype html>
+<html lang="ja">
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 <style>
     body {
         -webkit-writing-mode: vertical-rl;
         font-size: 18px;
-        font-family: "HiraMinPro-W3";
+        font-family: "HiraMinPro-W3", "Yu Gothic", "MS Gothic";
         overflow: hidden;
     }
 
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-lr-selection.html b/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-lr-selection.html
index 08f0e1e..1adffa9 100644
--- a/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-lr-selection.html
+++ b/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-lr-selection.html
@@ -1,10 +1,10 @@
 <!doctype html>
-<html style="border:10px solid maroon; -webkit-writing-mode:vertical-lr">
+<html style="border:10px solid maroon; -webkit-writing-mode:vertical-lr" lang="ja">
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 <style>
 body {
-    font-family: "HiraMinPro-W3", "MS Gothic";
+    font-family: "HiraMinPro-W3", "Yu Gothic", "MS Gothic";
     font-size: 16pt;
 }
 </style>
diff --git a/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-rl-selection.html b/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-rl-selection.html
index 7f7d8a1e..2759ed3 100644
--- a/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-rl-selection.html
+++ b/third_party/WebKit/LayoutTests/fast/writing-mode/japanese-rl-selection.html
@@ -1,10 +1,10 @@
 <!doctype html>
-<html style="border:10px solid maroon; -webkit-writing-mode:vertical-rl">
+<html style="border:10px solid maroon; -webkit-writing-mode:vertical-rl" lang="ja">
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 <style>
 body {
-    font-family: "HiraMinPro-W3", "MS Gothic";
+    font-family: "HiraMinPro-W3", "Yu Gothic", "MS Gothic";
     font-size: 16pt;
 }
 </style>
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt b/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt
index f386fc0..60b89d8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/307-after-303-after-post-expected.txt
@@ -5,10 +5,10 @@
 main frame - didFinishLoadForFrame
 main frame - didStartProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/post-to-303-target.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/post-to-303-target.php, main document URL http://127.0.0.1:8000/loading/resources/post-to-303-target.php, http method POST> redirectResponse (null)
-main frame - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/post-to-303-target.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/303-to-307-target.php, main document URL http://127.0.0.1:8000/loading/resources/303-to-307-target.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/post-to-303-target.php, http status code 303>
 main frame - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/post-to-303-target.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/307-post-output-target.php, main document URL http://127.0.0.1:8000/loading/resources/307-post-output-target.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/303-to-307-target.php, http status code 307>
+main frame - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/post-to-303-target.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/307-post-output-target.php, http status code 200>
 main frame - didCommitLoadForFrame
 http://127.0.0.1:8000/loading/resources/post-to-303-target.php - didFinishLoading
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt b/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt
index f861015..28026fd 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/redirect-methods-expected.txt
@@ -18,8 +18,8 @@
 frame "0" - didFinishLoadForFrame
 frame "0" - didStartProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
-frame "0" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 301>
+frame "0" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
 frame "0" - didCommitLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didFinishLoading
@@ -41,8 +41,8 @@
 frame "1" - didFinishLoadForFrame
 frame "1" - didStartProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
-frame "1" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 302>
+frame "1" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
 frame "1" - didCommitLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didFinishLoading
@@ -64,8 +64,8 @@
 frame "2" - didFinishLoadForFrame
 frame "2" - didStartProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
-frame "2" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 303>
+frame "2" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
 frame "2" - didCommitLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didFinishLoading
@@ -87,8 +87,8 @@
 frame "3" - didFinishLoadForFrame
 frame "3" - didStartProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse (null)
-frame "3" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method POST> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 307>
+frame "3" - didReceiveServerRedirectForProvisionalLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
 frame "3" - didCommitLoadForFrame
 http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didFinishLoading
diff --git a/third_party/WebKit/LayoutTests/http/tests/misc/performance-entry-serializer.html b/third_party/WebKit/LayoutTests/http/tests/misc/performance-entry-serializer.html
new file mode 100644
index 0000000..9ae14b8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/misc/performance-entry-serializer.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<script src="/w3c/resources/testharness.js"></script>
+<script src="/w3c/resources/testharnessreport.js"></script>
+<script>
+
+test(function() {
+    window.performance.mark('mark1');
+    window.performance.mark('mark2');
+    window.performance.measure('measure1', 'mark1', 'mark2');
+
+    var entries = window.performance.getEntries();
+    for (var i = 0; i < entries.length; i++) {
+        var entry = entries[i];
+        var serialized = JSON.parse(JSON.stringify(entry));
+        for (var attr in entry) {
+            if (typeof entry[attr] != 'function') {
+                assert_equals(serialized[attr], entry[attr], entry.constructor.name + '.' + attr);
+            }
+        }
+    }
+}, 'PerformanceEntry subclasses should serialize all attributes');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/multipart/multipart-main-resource-expected.html b/third_party/WebKit/LayoutTests/http/tests/multipart/multipart-main-resource-expected.html
index 1ad5e6b..0958893 100644
--- a/third_party/WebKit/LayoutTests/http/tests/multipart/multipart-main-resource-expected.html
+++ b/third_party/WebKit/LayoutTests/http/tests/multipart/multipart-main-resource-expected.html
@@ -1 +1 @@
-<iframe src="resources/green-100x100.png"></iframe>
+<iframe src="resources/abe.png"></iframe>
diff --git a/third_party/WebKit/LayoutTests/http/tests/preload/download_resources.html b/third_party/WebKit/LayoutTests/http/tests/preload/download_resources.html
index aae995e..c9907b9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/preload/download_resources.html
+++ b/third_party/WebKit/LayoutTests/http/tests/preload/download_resources.html
@@ -9,8 +9,8 @@
 <link rel=preload href="../resources/square.png" as=image>
 <link rel=preload href="../resources/square.png?background" as=image>
 <link rel=preload href="../resources/Ahem.ttf" as=font crossorigin>
-<link rel=preload href="../resources/test.mp4" as=video>
-<link rel=preload href="../resources/test.oga" as=audio>
+<link rel=preload href="../resources/test.mp4" as=media>
+<link rel=preload href="../resources/test.oga" as=media>
 <link rel=preload href="../security/resources/captions.vtt" as=track>
 <link rel=preload href="../resources/dummy.xml" as=foobarxmlthing>
 <link rel=preload href="../resources/dummy.xml">
diff --git a/third_party/WebKit/LayoutTests/http/tests/preload/onload_event.html b/third_party/WebKit/LayoutTests/http/tests/preload/onload_event.html
index f16e90b0..7eba8c4 100644
--- a/third_party/WebKit/LayoutTests/http/tests/preload/onload_event.html
+++ b/third_party/WebKit/LayoutTests/http/tests/preload/onload_event.html
@@ -18,8 +18,8 @@
 <link rel=preload href="../resources/dummy.css" as=style onload="styleLoaded = true;">
 <link rel=preload href="../resources/square.png" as=image onload="imageLoaded = true;">
 <link rel=preload href="../resources/Ahem.ttf" as=font crossorigin onload="fontLoaded = true;">
-<link rel=preload href="../resources/test.mp4" as=video onload="videoLoaded = true;">
-<link rel=preload href="../resources/test.oga" as=audio onload="audioLoaded = true;">
+<link rel=preload href="../resources/test.mp4" as=media onload="videoLoaded = true;">
+<link rel=preload href="../resources/test.oga" as=media onload="audioLoaded = true;">
 <link rel=preload href="../security/resources/captions.vtt" as=track onload="trackLoaded = true;">
 <link rel=preload href="../resources/dummy.xml" as=foobarxmlthing onload="gibberishLoaded = true;" onerror="gibberishErrored = true;">
 <link rel=preload href="../resources/dummy.xml" onload="noTypeLoaded = true;">
diff --git a/third_party/WebKit/LayoutTests/http/tests/preload/single_download_preload.html b/third_party/WebKit/LayoutTests/http/tests/preload/single_download_preload.html
index 9bc093f..2f99a13 100644
--- a/third_party/WebKit/LayoutTests/http/tests/preload/single_download_preload.html
+++ b/third_party/WebKit/LayoutTests/http/tests/preload/single_download_preload.html
@@ -9,8 +9,8 @@
 <link rel=preload href="../resources/square.png" as=image>
 <link rel=preload href="../resources/square.png?background" as=image>
 <link rel=preload href="../resources/Ahem.ttf" as=font crossorigin>
-<link rel=preload href="../resources/test.mp4" as=video>
-<link rel=preload href="../resources/test.oga" as=audio>
+<link rel=preload href="../resources/test.mp4" as=media>
+<link rel=preload href="../resources/test.oga" as=media>
 <link rel=preload href="../security/resources/captions.vtt" as=track>
 <link rel=preload href="../resources/dummy.xml" as=foobarxmlthing>
 <link rel=preload href="../resources/dummy.xml">
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/extendable-message-event.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/extendable-message-event.html
new file mode 100644
index 0000000..16a60fb2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/extendable-message-event.html
@@ -0,0 +1,230 @@
+<!DOCTYPE html>
+<title>ServiceWorkerGlobalScope: ExtendableMessageEvent</title>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src='../resources/test-helpers.js'></script>
+<script>
+
+promise_test(function(t) {
+    var script = 'resources/extendable-message-event-worker.js';
+    var scope = 'resources/scope/extendable-message-event-from-toplevel';
+    var registration;
+
+    return service_worker_unregister_and_register(t, script, scope)
+      .then(function(r) {
+          registration = r;
+          add_completion_callback(function() { registration.unregister(); });
+          return wait_for_state(t, registration.installing, 'activated');
+        })
+      .then(function() {
+          var saw_message = new Promise(function(resolve) {
+              navigator.serviceWorker.onmessage =
+                  function(event) { resolve(event.data); }
+            });
+          registration.active.postMessage('start');
+          return saw_message;
+        })
+      .then(function(results) {
+          var expected_results = [
+              'Client message: [object ExtendableMessageEvent]',
+              '  event.origin: ' + location.origin,
+              '  event.lastEventId: ',
+              '  event.source: [object WindowClient]',
+              '  event.source.url: ' + location.href,
+              '  event.source.frameType: top-level',
+              '  event.source.visibilityState: visible',
+              '  event.source.focused: true',
+              '  event.ports: null',
+          ];
+          assert_array_equals(results, expected_results);
+        });
+  }, 'Post an extendable message from a top-level client');
+
+promise_test(function(t) {
+    var script = 'resources/extendable-message-event-worker.js';
+    var scope = 'resources/scope/extendable-message-event-from-nested';
+    var frame;
+
+    return service_worker_unregister_and_register(t, script, scope)
+      .then(function(registration) {
+          add_completion_callback(function() { registration.unregister(); });
+          return wait_for_state(t, registration.installing, 'activated');
+        })
+      .then(function() { return with_iframe(scope); })
+      .then(function(f) {
+          frame = f;
+          add_completion_callback(function() { frame.remove(); });
+          var saw_message = new Promise(function(resolve) {
+              frame.contentWindow.navigator.serviceWorker.onmessage =
+                  function(event) { resolve(event.data); }
+            });
+          f.contentWindow.navigator.serviceWorker.controller.postMessage('');
+          return saw_message;
+        })
+      .then(function(results) {
+          var expected_results = [
+              'Client message: [object ExtendableMessageEvent]',
+              '  event.origin: ' + frame.contentWindow.location.origin,
+              '  event.lastEventId: ',
+              '  event.source: [object WindowClient]',
+              '  event.source.url: ' + frame.contentWindow.location.href,
+              '  event.source.frameType: nested',
+              '  event.source.visibilityState: visible',
+              '  event.source.focused: false',
+              '  event.ports: null',
+          ];
+          assert_array_equals(results, expected_results);
+        });
+  }, 'Post an extendable message from a nested client');
+
+promise_test(function(t) {
+    var script = 'resources/extendable-message-event-worker.js';
+    var scope = 'resources/extendable-message-event-sandboxed-iframe.html';
+
+    return service_worker_unregister_and_register(t, script, scope)
+      .then(function(registration) {
+          add_completion_callback(function() { registration.unregister(); });
+          return wait_for_state(t, registration.installing, 'activated');
+        })
+      .then(function() { return with_iframe(scope); })
+      .then(function(frame) {
+          add_completion_callback(function() { frame.remove(); });
+          var saw_message = new Promise(function(resolve) {
+              onmessage = function(event) {
+                resolve(event.data);
+              }
+            });
+          frame.contentWindow.postMessage('', '*');
+          return saw_message;
+        })
+      .then(function(results) {
+          // 'origin' and 'url' should be hided.
+          var expected_results = [
+              'Client message: [object ExtendableMessageEvent]',
+              '  event.origin: ',
+              '  event.lastEventId: ',
+              '  event.source: [object WindowClient]',
+              '  event.source.url: ',
+              '  event.source.frameType: nested',
+              '  event.source.visibilityState: visible',
+              '  event.source.focused: false',
+              '  event.ports: null',
+          ];
+          assert_array_equals(results, expected_results);
+        });
+  }, 'Post an extendable message from a sandboxed client');
+
+// TODO(nhiroki): Add tests to post an extendable message from a client whose
+// execution context is already stopped (http://crbug.com/543198).
+
+promise_test(function(t) {
+    var script = 'resources/extendable-message-event-loopback-worker.js';
+    var scope = 'resources/scope/extendable-message-event-loopback';
+    var registration;
+
+    return service_worker_unregister_and_register(t, script, scope)
+      .then(function(r) {
+          registration = r;
+          add_completion_callback(function() { registration.unregister(); });
+          return wait_for_state(t, registration.installing, 'activated');
+        })
+      .then(function() {
+          var results = [];
+          var saw_message = new Promise(function(resolve) {
+              navigator.serviceWorker.onmessage = function(event) {
+                switch (event.data.type) {
+                  case 'record':
+                    Array.prototype.push.apply(results, event.data.results);
+                    break;
+                  case 'finish':
+                    resolve(results);
+                    break;
+                }
+              };
+            });
+          registration.active.postMessage({type: 'start'});
+          return saw_message;
+        })
+      .then(function(results) {
+          var expected_results = [
+              '1st loopback: [object ExtendableMessageEvent]',
+              '  event.origin: ' + location.origin,
+              '  event.lastEventId: ',
+              '  event.source: [object ServiceWorker]',
+              '  event.source.scriptURL: ' + normalizeURL(script),
+              '  event.source.state: activated',
+              '  event.ports: null',
+              '2nd loopback: [object ExtendableMessageEvent]',
+              '  event.origin: ' + location.origin,
+              '  event.lastEventId: ',
+              '  event.source: [object ServiceWorker]',
+              '  event.source.scriptURL: ' + normalizeURL(script),
+              '  event.source.state: activated',
+              '  event.ports: null',
+          ];
+          assert_array_equals(results, expected_results);
+        });
+  }, 'Post loopback extendable messages');
+
+promise_test(function(t) {
+    var script1 = 'resources/extendable-message-event-ping-worker.js';
+    var script2 = 'resources/extendable-message-event-pong-worker.js';
+    var scope = 'resources/scope/extendable-message-event-pingpong';
+    var registration;
+
+    return service_worker_unregister_and_register(t, script1, scope)
+      .then(function(r) {
+          registration = r;
+          add_completion_callback(function() { registration.unregister(); });
+          return wait_for_state(t, registration.installing, 'activated');
+        })
+      .then(function() {
+          // A controlled frame is necessary for keeping a waiting worker.
+          return with_iframe(scope);
+        })
+      .then(function(frame) {
+          add_completion_callback(function() { frame.remove(); });
+          return navigator.serviceWorker.register(script2, {scope: scope});
+        })
+      .then(function(r) {
+          return wait_for_state(t, r.installing, 'installed');
+        })
+      .then(function() {
+          var results = [];
+          var saw_message = new Promise(function(resolve) {
+              navigator.serviceWorker.onmessage = function(event) {
+                switch (event.data.type) {
+                  case 'record':
+                    Array.prototype.push.apply(results, event.data.results);
+                    break;
+                  case 'finish':
+                    resolve(results);
+                    break;
+                }
+              };
+            });
+          registration.active.postMessage({type: 'start'});
+          return saw_message;
+        })
+      .then(function(results) {
+          var expected_results = [
+              'Ping message: [object ExtendableMessageEvent]',
+              '  event.origin: ' + location.origin,
+              '  event.lastEventId: ',
+              '  event.source: [object ServiceWorker]',
+              '  event.source.scriptURL: ' + normalizeURL(script1),
+              '  event.source.state: activated',
+              '  event.ports: null',
+              'Pong message: [object ExtendableMessageEvent]',
+              '  event.origin: ' + location.origin,
+              '  event.lastEventId: ',
+              '  event.source: [object ServiceWorker]',
+              '  event.source.scriptURL: ' + normalizeURL(script2),
+              '  event.source.state: installed',
+              '  event.ports: null',
+          ];
+          assert_array_equals(results, expected_results);
+        });
+  }, 'Post extendable messages among service workers');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js
new file mode 100644
index 0000000..a888516
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-loopback-worker.js
@@ -0,0 +1,44 @@
+self.addEventListener('message', function(event) {
+    switch (event.data.type) {
+      case 'start':
+        self.registration.active.postMessage(
+            {type: '1st', client_id: event.source.id});
+        break;
+      case '1st':
+        // 1st loopback message via ServiceWorkerRegistration.active.
+        var results = [
+            '1st loopback: ' + event,
+            '  event.origin: ' + event.origin,
+            '  event.lastEventId: ' + event.lastEventId,
+            '  event.source: ' + event.source,
+            '  event.source.scriptURL: ' + event.source.scriptURL,
+            '  event.source.state: ' + event.source.state,
+            '  event.ports: ' + event.ports,
+        ];
+        var client_id = event.data.client_id;
+        event.source.postMessage({type: '2nd', client_id: client_id});
+        event.waitUntil(clients.get(client_id)
+            .then(function(client) {
+                client.postMessage({type: 'record', results: results});
+              }));
+        break;
+      case '2nd':
+        // 2nd loopback message via ExtendableMessageEvent.source.
+        var results = [
+            '2nd loopback: ' + event,
+            '  event.origin: ' + event.origin,
+            '  event.lastEventId: ' + event.lastEventId,
+            '  event.source: ' + event.source,
+            '  event.source.scriptURL: ' + event.source.scriptURL,
+            '  event.source.state: ' + event.source.state,
+            '  event.ports: ' + event.ports,
+        ];
+        var client_id = event.data.client_id;
+        event.waitUntil(clients.get(client_id)
+            .then(function(client) {
+                client.postMessage({type: 'record', results: results});
+                client.postMessage({type: 'finish'});
+              }));
+        break;
+      }
+  });
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js
new file mode 100644
index 0000000..eb3f064
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-ping-worker.js
@@ -0,0 +1,26 @@
+self.addEventListener('message', function(event) {
+    switch (event.data.type) {
+      case 'start':
+        // Send a ping message to another service worker.
+        self.registration.waiting.postMessage(
+            {type: 'ping', client_id: event.source.id});
+        break;
+      case 'pong':
+        var results = [
+            'Pong message: ' + event,
+            '  event.origin: ' + event.origin,
+            '  event.lastEventId: ' + event.lastEventId,
+            '  event.source: ' + event.source,
+            '  event.source.scriptURL: ' + event.source.scriptURL,
+            '  event.source.state: ' + event.source.state,
+            '  event.ports: ' + event.ports,
+        ];
+        var client_id = event.data.client_id;
+        event.waitUntil(clients.get(client_id)
+            .then(function(client) {
+                client.postMessage({type: 'record', results: results});
+                client.postMessage({type: 'finish'});
+              }));
+        break;
+    }
+  });
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js
new file mode 100644
index 0000000..bc2a00a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-pong-worker.js
@@ -0,0 +1,21 @@
+self.addEventListener('message', function(event) {
+    switch (event.data.type) {
+      case 'ping':
+        var results = [
+            'Ping message: ' + event,
+            '  event.origin: ' + event.origin,
+            '  event.lastEventId: ' + event.lastEventId,
+            '  event.source: ' + event.source,
+            '  event.source.scriptURL: ' + event.source.scriptURL,
+            '  event.source.state: ' + event.source.state,
+            '  event.ports: ' + event.ports,
+        ];
+        var client_id = event.data.client_id;
+        event.waitUntil(clients.get(client_id)
+            .then(function(client) {
+                client.postMessage({type: 'record', results: results});
+                event.source.postMessage({type: 'pong', client_id: client_id});
+              }));
+        break;
+    }
+  });
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-sandboxed-iframe.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-sandboxed-iframe.html
new file mode 100644
index 0000000..5eae7f4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-sandboxed-iframe.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script>
+onmessage = function(event) {
+  navigator.serviceWorker.onmessage = function(e) {
+      event.source.postMessage(e.data, '*');
+    };
+  var worker = navigator.serviceWorker.controller;
+
+  // Remove 'allow-same-origin' permission.
+  var meta = document.createElement('meta');
+  meta.setAttribute('http-equiv', 'Content-Security-Policy');
+  meta.setAttribute('content', 'sandbox allow-scripts');
+  document.head.appendChild(meta);
+
+  worker.postMessage('');
+}
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js
new file mode 100644
index 0000000..e7491b1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/ServiceWorkerGlobalScope/resources/extendable-message-event-worker.js
@@ -0,0 +1,14 @@
+self.addEventListener('message', function(event) {
+    var results = [
+        'Client message: ' + event,
+        '  event.origin: ' + event.origin,
+        '  event.lastEventId: ' + event.lastEventId,
+        '  event.source: ' + event.source,
+        '  event.source.url: ' + event.source.url,
+        '  event.source.frameType: ' + event.source.frameType,
+        '  event.source.visibilityState: ' + event.source.visibilityState,
+        '  event.source.focused: ' + event.source.focused,
+        '  event.ports: ' + event.ports,
+    ];
+    event.source.postMessage(results);
+  });
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-async-respond-with.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-async-respond-with.html
index c27fbd5..f911041 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-async-respond-with.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-async-respond-with.html
@@ -16,13 +16,13 @@
           return with_iframe(scope);
         })
       .then(function(frame) {
+          add_completion_callback(function() { frame.remove(); });
           var channel = new MessageChannel();
           var saw_message = new Promise(function(resolve) {
               channel.port1.onmessage = function(e) { resolve(e.data); }
             });
           var worker = frame.contentWindow.navigator.serviceWorker.controller;
 
-          frame.remove();
           worker.postMessage({port: channel.port2}, [channel.port2]);
           return saw_message;
         })
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-respond-with-stops-propagation.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-respond-with-stops-propagation.html
index 20629ef..d49ceed9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-respond-with-stops-propagation.html
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-event-respond-with-stops-propagation.html
@@ -17,13 +17,13 @@
           return with_iframe(scope);
         })
       .then(function(frame) {
+          add_completion_callback(function() { frame.remove(); });
           var channel = new MessageChannel();
           var saw_message = new Promise(function(resolve) {
               channel.port1.onmessage = function(e) { resolve(e.data); }
             });
           var worker = frame.contentWindow.navigator.serviceWorker.controller;
 
-          frame.remove();
           worker.postMessage({port: channel.port2}, [channel.port2]);
           return saw_message;
         })
diff --git a/third_party/WebKit/LayoutTests/svg/text/lengthAdjust-text-metrics-expected.txt b/third_party/WebKit/LayoutTests/svg/text/lengthAdjust-text-metrics-expected.txt
index 917f661..08c5223f 100644
--- a/third_party/WebKit/LayoutTests/svg/text/lengthAdjust-text-metrics-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/text/lengthAdjust-text-metrics-expected.txt
@@ -14,7 +14,7 @@
 PASS lengthToString(svgText.getComputedTextLength()) is "200.0"
 
 Test getSubStringLength() API
-FAIL lengthToString(svgText.getSubStringLength(0, 1)) should be 61.5. Was 66.6.
+FAIL lengthToString(svgText.getSubStringLength(0, 1)) should be 61.5. Was 54.5.
 FAIL lengthToString(svgText.getSubStringLength(0, 2)) should be 117.9. Was 115.2.
 FAIL lengthToString(svgText.getSubStringLength(0, 3)) should be 169.2. Was 169.7.
 PASS lengthToString(svgText.getSubStringLength(0, 4)) is "200.0"
@@ -27,19 +27,19 @@
 
 Test getStartPositionOfChar() API
 PASS pointToString(svgText.getStartPositionOfChar(0)) is "(10.0,20.0)"
-FAIL pointToString(svgText.getStartPositionOfChar(1)) should be (71.5,20.0). Was (76.6,20.0).
+FAIL pointToString(svgText.getStartPositionOfChar(1)) should be (71.5,20.0). Was (64.5,20.0).
 FAIL pointToString(svgText.getStartPositionOfChar(2)) should be (127.9,20.0). Was (125.2,20.0).
 FAIL pointToString(svgText.getStartPositionOfChar(3)) should be (179.2,20.0). Was (179.7,20.0).
 
 Test getEndPositionOfChar() API
-FAIL pointToString(svgText.getEndPositionOfChar(0)) should be (71.5,20.0). Was (76.6,20.0).
+FAIL pointToString(svgText.getEndPositionOfChar(0)) should be (71.5,20.0). Was (64.5,20.0).
 FAIL pointToString(svgText.getEndPositionOfChar(1)) should be (127.9,20.0). Was (125.2,20.0).
 FAIL pointToString(svgText.getEndPositionOfChar(2)) should be (179.2,20.0). Was (179.7,20.0).
 PASS pointToString(svgText.getEndPositionOfChar(3)) is "(210.0,20.0)"
 
 Test getExtentOfChar() API
-FAIL rectToString(svgText.getExtentOfChar(0)) should be (10.0,1.9)-(61.5x22.3). Was (10.0,2.0)-(66.6x22.0).
-FAIL rectToString(svgText.getExtentOfChar(1)) should be (71.5,1.9)-(56.4x22.3). Was (76.6,2.0)-(48.6x22.0).
+FAIL rectToString(svgText.getExtentOfChar(0)) should be (10.0,1.9)-(61.5x22.3). Was (10.0,2.0)-(54.5x22.0).
+FAIL rectToString(svgText.getExtentOfChar(1)) should be (71.5,1.9)-(56.4x22.3). Was (64.5,2.0)-(60.6x22.0).
 FAIL rectToString(svgText.getExtentOfChar(2)) should be (127.9,1.9)-(51.3x22.3). Was (125.2,2.0)-(54.5x22.0).
 FAIL rectToString(svgText.getExtentOfChar(3)) should be (179.2,1.9)-(30.8x22.3). Was (179.7,2.0)-(30.3x22.0).
 
@@ -57,9 +57,9 @@
 > Testing point=(10.1,10.0)
 PASS svgText.getCharNumAtPosition(point) is 0
 > Testing point=(71.4,10.0)
-PASS svgText.getCharNumAtPosition(point) is 0
+FAIL svgText.getCharNumAtPosition(point) should be 0. Was 1.
 > Testing point=(71.6,10.0)
-FAIL svgText.getCharNumAtPosition(point) should be 1. Was 0.
+PASS svgText.getCharNumAtPosition(point) is 1
 > Testing point=(127.8,10.0)
 FAIL svgText.getCharNumAtPosition(point) should be 1. Was 2.
 > Testing point=(128.0,10.0)
diff --git a/third_party/WebKit/LayoutTests/svg/text/ligature-queries.html b/third_party/WebKit/LayoutTests/svg/text/ligature-queries.html
new file mode 100644
index 0000000..6e8596e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/text/ligature-queries.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<meta charset="utf8">
+<style>
+    .commonLigatures {
+        font-variant-ligatures: common-ligatures;
+    }
+    .noselect {
+        -webkit-user-select: none;
+        user-select: none;
+    }
+</style>
+<svg width="600px" height="500px" xmlns="http://www.w3.org/2000/svg">
+    <defs>
+        <path id="path" d="M 25 400 C 300 400 200 200 500 450" />
+    </defs>
+    <g id="container"/>
+    <g font-family="Arial" font-size="50px">
+        <text x="25" y="50" class="commonLigatures" font-family="cursive">öh &#x443;&#x030c;eah! fi ffi abcffidef</text>
+        <text x="25" y="150" class="commonLigatures" font-family="serif">öh &#x443;&#x030c;eah! fi ffi abcffidef</text>
+        <text x="25" y="250" class="commonLigatures" font-family="sans-serif">öh &#x443;&#x030c;eah! fi ffi abcffidef</text>
+        <use xlink:href="#path" stroke-width="2" stroke="black" fill="transparent"/>
+        <text x="25" y="350" class="commonLigatures" font-family="cursive">
+            <textPath xlink:href="#path">ffiffiffiffiffiffiffiffiffiffiffi</textPath>
+        </text>
+      </text>
+    </g>
+</svg>
+<script>
+    function highlightGlyph(text, index, color) {
+        var extent = text.getExtentOfChar(index);
+
+        // Highlight rect that we've selected using the extent information
+        var rectElement = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+        rectElement.setAttribute("x", extent.x);
+        rectElement.setAttribute("y", extent.y);
+        rectElement.setAttribute("width", extent.width);
+        rectElement.setAttribute("height", extent.height);
+        rectElement.setAttribute("fill-opacity", "0.5");
+        rectElement.setAttribute("fill", color);
+        document.getElementById("container").appendChild(rectElement);
+        // Output the start offset
+        var textElement = document.createElementNS("http://www.w3.org/2000/svg", "text");
+        textElement.setAttribute("x", extent.x + extent.width / 2);
+        textElement.setAttribute("y", extent.y + extent.height + 5);
+        textElement.setAttribute("text-anchor", "middle");
+        textElement.setAttribute("font-size", 10);
+        textElement.setAttribute("class", "noselect");
+        textElement.appendChild(document.createTextNode(index));
+        document.getElementById("container").appendChild(textElement);
+    }
+
+    var colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
+    // Highlight each glyph with a semi-transparent rectangle and
+    // a number corresponding to the queried character index.
+    var textElements = document.querySelectorAll("text");
+    for (var elemNum = 0; elemNum < textElements.length; ++elemNum) {
+        var text = textElements[elemNum];
+        var charCount = text.getNumberOfChars();
+        for (var index = 0; index < charCount; ++index)
+            highlightGlyph(text, index, colors[index % colors.length]);
+    }
+</script>
diff --git a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
index 3a68a79..ba889fe 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
@@ -12,6 +12,7 @@
 #include "bindings/core/v8/V8BindingForTesting.h"
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8IteratorResultValue.h"
+#include "bindings/core/v8/V8RecursionScope.h"
 #include "bindings/core/v8/V8ThrowException.h"
 #include "core/dom/Document.h"
 #include "core/streams/ReadableStreamController.h"
@@ -138,7 +139,7 @@
     ~ReadableStreamOperationsTest() override
     {
         // Execute all pending microtasks
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         EXPECT_FALSE(m_block.HasCaught());
     }
 
@@ -149,6 +150,7 @@
     {
         v8::Local<v8::String> source;
         v8::Local<v8::Script> script;
+        V8RecursionScope::MicrotaskSuppression microtasks(isolate());
         if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) {
             ADD_FAILURE();
             return ScriptValue();
@@ -253,12 +255,12 @@
         Function::createFunction(getScriptState(), it2),
         NotReached::createFunction(getScriptState()));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_FALSE(it1->isSet());
     EXPECT_FALSE(it2->isSet());
 
     ASSERT_FALSE(evalWithPrintingError("controller.enqueue('hello')").isEmpty());
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(it1->isSet());
     EXPECT_TRUE(it1->isValid());
     EXPECT_FALSE(it1->isDone());
@@ -266,7 +268,7 @@
     EXPECT_FALSE(it2->isSet());
 
     ASSERT_FALSE(evalWithPrintingError("controller.close()").isEmpty());
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(it1->isSet());
     EXPECT_TRUE(it1->isValid());
     EXPECT_FALSE(it1->isDone());
@@ -309,7 +311,7 @@
     ReadableStreamOperations::read(getScriptState(), reader).then(Function::createFunction(getScriptState(), it2), NotReached::createFunction(getScriptState()));
     ReadableStreamOperations::read(getScriptState(), reader).then(Function::createFunction(getScriptState(), it3), NotReached::createFunction(getScriptState()));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(10, underlyingSource->desiredSize());
 
@@ -326,7 +328,7 @@
     EXPECT_FALSE(it3->isSet());
 
     underlyingSource->close();
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(it3->isSet());
     EXPECT_TRUE(it3->isValid());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
index 65c9393..52af5edc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromisePropertyTest.cpp
@@ -281,7 +281,7 @@
     getProperty()->resolve(value);
     EXPECT_EQ(Property::Resolved, getProperty()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(1u, nOtherResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
@@ -307,7 +307,7 @@
     getProperty()->resolve(value);
     EXPECT_EQ(Property::Resolved, getProperty()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(0u, nOtherResolveCalls);
 
@@ -316,7 +316,7 @@
         otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState()));
     }
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(1u, nOtherResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
@@ -343,7 +343,7 @@
         getProperty()->promise(otherWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), otherActual, nOtherRejectCalls));
     }
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nRejectCalls);
     EXPECT_EQ(wrap(mainWorld(), reason), actual);
     EXPECT_EQ(1u, nOtherRejectCalls);
@@ -374,7 +374,7 @@
     getProperty()->resolve(new GarbageCollectedScriptWrappable("value"));
     EXPECT_EQ(Property::Pending, getProperty()->getState());
 
-    v8::Isolate::GetCurrent()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(v8::Isolate::GetCurrent());
 }
 
 TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset)
@@ -405,7 +405,7 @@
     EXPECT_EQ(0u, nOldResolveCalls);
     EXPECT_EQ(0u, nNewRejectCalls);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nOldResolveCalls);
     EXPECT_EQ(1u, nNewRejectCalls);
     EXPECT_NE(oldPromise, newPromise);
@@ -445,7 +445,7 @@
     getProperty()->resolve(value.get());
     EXPECT_EQ(Property::Resolved, getProperty()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nResolveCalls);
     EXPECT_EQ(wrap(mainWorld(), value), actual);
 }
@@ -464,7 +464,7 @@
     getProperty()->reject(reason);
     EXPECT_EQ(Property::Rejected, getProperty()->getState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ(1u, nRejectCalls);
     EXPECT_EQ(wrap(mainWorld(), reason), actual);
 }
@@ -514,7 +514,7 @@
             property->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actualValue, nResolveCalls), notReached(currentScriptState()));
         }
         property->resolve(value);
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         {
             ScriptState::Scope scope(mainScriptState());
             actual = toCoreString(actualValue.v8Value()->ToString(mainScriptState()->context()).ToLocalChecked());
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
index ea55caa..23f2b2a 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseResolverTest.cpp
@@ -60,7 +60,7 @@
         createClosure(callback, v8::Undefined(isolate()), isolate());
 
         // Execute all pending microtasks
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
     }
 
     OwnPtr<DummyPageHolder> m_pageHolder;
@@ -96,7 +96,7 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -111,14 +111,14 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
     resolver->resolve("bye");
     resolver->reject("bye");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -144,7 +144,7 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -159,14 +159,14 @@
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("hello", onRejected);
 
     resolver->resolve("bye");
     resolver->reject("bye");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("hello", onRejected);
@@ -196,7 +196,7 @@
     }
 
     resolver->resolve("hello");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -321,7 +321,7 @@
     }
 
     resolver->resolve();
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_EQ(String(), onRejected);
@@ -345,7 +345,7 @@
     }
 
     resolver->reject();
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(String(), onFulfilled);
     EXPECT_EQ("undefined", onRejected);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
index a537ddc..73b38ba 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptPromiseTest.cpp
@@ -83,7 +83,7 @@
         createClosure(callback, v8::Undefined(m_scope.isolate()), m_scope.isolate());
 
         // Execute all pending microtasks
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
     }
 
     String toString(const ScriptValue& value)
@@ -124,13 +124,13 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     resolver.resolve(v8String(isolate(), "hello"));
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", toString(onFulfilled));
     EXPECT_TRUE(onRejected.isEmpty());
@@ -148,7 +148,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", toString(onFulfilled));
     EXPECT_TRUE(onRejected.isEmpty());
@@ -165,13 +165,13 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     resolver.reject(v8String(isolate(), "hello"));
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -189,7 +189,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -226,7 +226,7 @@
     EXPECT_TRUE(onRejected1.isEmpty());
     EXPECT_TRUE(onRejected2.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ("hello", toString(onFulfilled1));
     EXPECT_EQ("hello", toString(onFulfilled2));
@@ -248,7 +248,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("hello", toString(onRejected));
@@ -264,7 +264,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_EQ("SyntaxError: some syntax error", toString(onRejected));
@@ -282,7 +282,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(onFulfilled.isEmpty());
     EXPECT_TRUE(toStringArray(onFulfilled).isEmpty());
@@ -304,7 +304,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(onFulfilled.isEmpty());
     Vector<String> values = toStringArray(onFulfilled);
@@ -329,7 +329,7 @@
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_TRUE(onRejected.isEmpty());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isEmpty());
     EXPECT_FALSE(onRejected.isEmpty());
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
index 696a886..3694ca5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -321,7 +321,7 @@
 
     v8::Debug::SetLiveEditEnabled(isolate, false);
 
-    isolate->SetAutorunMicrotasks(false);
+    isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
 }
 
 namespace {
@@ -351,10 +351,17 @@
 
 } // namespace
 
+static void adjustAmountOfExternalAllocatedMemory(int size)
+{
+    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size);
+}
+
 void V8Initializer::initializeMainThread()
 {
     ASSERT(isMainThread());
 
+    WTF::ArrayBufferContents::initialize(adjustAmountOfExternalAllocatedMemory);
+
     DEFINE_STATIC_LOCAL(ArrayBufferAllocator, arrayBufferAllocator, ());
     auto v8ExtrasMode = RuntimeEnabledFeatures::experimentalV8ExtrasEnabled() ? gin::IsolateHolder::kStableAndExperimentalV8Extras : gin::IsolateHolder::kStableV8Extras;
     gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode, v8ExtrasMode, &arrayBufferAllocator);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
index 0a2cfcb9..65c02bc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.cpp
@@ -30,7 +30,6 @@
 #include "bindings/core/v8/V8Binding.h"
 #include "bindings/core/v8/V8HiddenValue.h"
 #include "bindings/core/v8/V8ObjectConstructor.h"
-#include "bindings/core/v8/V8RecursionScope.h"
 #include "bindings/core/v8/V8ScriptRunner.h"
 #include "core/frame/Deprecation.h"
 #include "core/inspector/MainThreadDebugger.h"
@@ -53,18 +52,6 @@
     V8PerIsolateData::from(isolate)->runEndOfScopeTasks();
 }
 
-#if ENABLE(ASSERT)
-static void assertV8RecursionScope(v8::Isolate* isolate)
-{
-    ASSERT(V8RecursionScope::properlyUsed(isolate));
-}
-
-static bool runningUnitTest()
-{
-    return Platform::current()->unitTestSupport();
-}
-#endif
-
 static void useCounterCallback(v8::Isolate* isolate, v8::Isolate::UseCounterFeature feature)
 {
     UseCounter::Feature blinkFeature;
@@ -143,25 +130,15 @@
 }
 
 V8PerIsolateData::V8PerIsolateData()
-    : m_destructionPending(false)
-    , m_isolateHolder(adoptPtr(new gin::IsolateHolder()))
+    : m_isolateHolder(adoptPtr(new gin::IsolateHolder()))
     , m_stringCache(adoptPtr(new StringCache(isolate())))
     , m_hiddenValue(V8HiddenValue::create())
     , m_constructorMode(ConstructorMode::CreateNewObject)
-    , m_recursionLevel(0)
     , m_isHandlingRecursionLevelError(false)
     , m_isReportingException(false)
-#if ENABLE(ASSERT)
-    , m_internalScriptRecursionLevel(0)
-#endif
-    , m_performingMicrotaskCheckpoint(false)
 {
     // FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone.
     isolate()->Enter();
-#if ENABLE(ASSERT)
-    if (!runningUnitTest())
-        isolate()->AddCallCompletedCallback(&assertV8RecursionScope);
-#endif
     isolate()->AddBeforeCallEnteredCallback(&beforeCallEnteredCallback);
     isolate()->AddMicrotasksCompletedCallback(&microtasksCompletedCallback);
     if (isMainThread())
@@ -206,9 +183,6 @@
 {
     V8PerIsolateData* data = from(isolate);
 
-    ASSERT(!data->m_destructionPending);
-    data->m_destructionPending = true;
-
     data->m_threadDebugger.clear();
     // Clear any data that may have handles into the heap,
     // prior to calling ThreadState::detach().
@@ -219,10 +193,6 @@
 // gets called but before the Isolate exits.
 void V8PerIsolateData::destroy(v8::Isolate* isolate)
 {
-#if ENABLE(ASSERT)
-    if (!runningUnitTest())
-        isolate->RemoveCallCompletedCallback(&assertV8RecursionScope);
-#endif
     isolate->RemoveBeforeCallEnteredCallback(&beforeCallEnteredCallback);
     isolate->RemoveMicrotasksCompletedCallback(&microtasksCompletedCallback);
     V8PerIsolateData* data = from(isolate);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
index 090fc856..2cda3f4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8PerIsolateData.h
@@ -74,31 +74,18 @@
 
     static void enableIdleTasks(v8::Isolate*, PassOwnPtr<gin::V8IdleTaskRunner>);
 
-    bool destructionPending() const { return m_destructionPending; }
     v8::Isolate* isolate() { return m_isolateHolder->isolate(); }
 
     StringCache* getStringCache() { return m_stringCache.get(); }
 
     v8::Persistent<v8::Value>& ensureLiveRoot();
 
-    int recursionLevel() const { return m_recursionLevel; }
-    int incrementRecursionLevel() { return ++m_recursionLevel; }
-    int decrementRecursionLevel() { return --m_recursionLevel; }
     bool isHandlingRecursionLevelError() const { return m_isHandlingRecursionLevelError; }
     void setIsHandlingRecursionLevelError(bool value) { m_isHandlingRecursionLevelError = value; }
 
     bool isReportingException() const { return m_isReportingException; }
     void setReportingException(bool value) { m_isReportingException = value; }
 
-    bool performingMicrotaskCheckpoint() const { return m_performingMicrotaskCheckpoint; }
-    void setPerformingMicrotaskCheckpoint(bool performingMicrotaskCheckpoint) { m_performingMicrotaskCheckpoint = performingMicrotaskCheckpoint; }
-
-#if ENABLE(ASSERT)
-    int internalScriptRecursionLevel() const { return m_internalScriptRecursionLevel; }
-    int incrementInternalScriptRecursionLevel() { return ++m_internalScriptRecursionLevel; }
-    int decrementInternalScriptRecursionLevel() { return --m_internalScriptRecursionLevel; }
-#endif
-
     V8HiddenValue* hiddenValue() { return m_hiddenValue.get(); }
 
     v8::Local<v8::FunctionTemplate> domTemplate(const void* domTemplateKey, v8::FunctionCallback = 0, v8::Local<v8::Value> data = v8::Local<v8::Value>(), v8::Local<v8::Signature> = v8::Local<v8::Signature>(), int length = 0);
@@ -131,7 +118,6 @@
     bool hasInstance(const WrapperTypeInfo* untrusted, v8::Local<v8::Value>, DOMTemplateMap&);
     v8::Local<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Local<v8::Value>, DOMTemplateMap&);
 
-    bool m_destructionPending;
     OwnPtr<gin::IsolateHolder> m_isolateHolder;
     DOMTemplateMap m_domTemplateMapForMainWorld;
     DOMTemplateMap m_domTemplateMapForNonMainWorld;
@@ -143,15 +129,9 @@
     bool m_constructorMode;
     friend class ConstructorMode;
 
-    int m_recursionLevel;
     bool m_isHandlingRecursionLevelError;
     bool m_isReportingException;
 
-#if ENABLE(ASSERT)
-    int m_internalScriptRecursionLevel;
-#endif
-    bool m_performingMicrotaskCheckpoint;
-
     Vector<OwnPtr<EndOfScopeTask>> m_endOfScopeTasks;
     OwnPtr<ThreadDebugger> m_threadDebugger;
 };
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
index ed10e86..b4c3acf7 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.cpp
@@ -30,13 +30,6 @@
 
 #include "bindings/core/v8/V8RecursionScope.h"
 
-#include "core/dom/Microtask.h"
-
 namespace blink {
 
-void V8RecursionScope::didLeaveScriptContext()
-{
-    Microtask::performCheckpoint(m_isolate);
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
index dd9a51f..8bbd26c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8RecursionScope.h
@@ -59,63 +59,39 @@
     STACK_ALLOCATED();
 public:
     explicit V8RecursionScope(v8::Isolate* isolate)
-        : m_isolate(isolate)
+        : m_scope(isolate, v8::MicrotasksScope::kRunMicrotasks)
     {
-        V8PerIsolateData::from(m_isolate)->incrementRecursionLevel();
-        // If you want V8 to autorun microtasks, this class needs to have a
-        // v8::Isolate::SuppressMicrotaskExecutionScope member.
-        ASSERT(!isolate->WillAutorunMicrotasks());
+        ASSERT(isolate->GetMicrotasksPolicy() == v8::MicrotasksPolicy::kScoped);
     }
 
     ~V8RecursionScope()
     {
-        if (!V8PerIsolateData::from(m_isolate)->decrementRecursionLevel())
-            didLeaveScriptContext();
     }
 
     static int recursionLevel(v8::Isolate* isolate)
     {
-        return V8PerIsolateData::from(isolate)->recursionLevel();
+        return v8::MicrotasksScope::GetCurrentDepth(isolate);
     }
 
-#if ENABLE(ASSERT)
-    static bool properlyUsed(v8::Isolate* isolate)
-    {
-        return recursionLevel(isolate) > 0 || V8PerIsolateData::from(isolate)->internalScriptRecursionLevel() > 0;
-    }
-#endif
-
     class MicrotaskSuppression {
         USING_FAST_MALLOC(MicrotaskSuppression);
         WTF_MAKE_NONCOPYABLE(MicrotaskSuppression);
     public:
-        MicrotaskSuppression(v8::Isolate* isolate)
-#if ENABLE(ASSERT)
-            : m_isolate(isolate)
-#endif
+        explicit MicrotaskSuppression(v8::Isolate* isolate)
+            : m_scope(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks)
         {
-#if ENABLE(ASSERT)
-            V8PerIsolateData::from(m_isolate)->incrementInternalScriptRecursionLevel();
-#endif
         }
 
         ~MicrotaskSuppression()
         {
-#if ENABLE(ASSERT)
-            V8PerIsolateData::from(m_isolate)->decrementInternalScriptRecursionLevel();
-#endif
         }
 
     private:
-#if ENABLE(ASSERT)
-        v8::Isolate* m_isolate;
-#endif
+        v8::MicrotasksScope m_scope;
     };
 
 private:
-    void didLeaveScriptContext();
-
-    v8::Isolate* m_isolate;
+    v8::MicrotasksScope m_scope;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl
index 61d5c25..6097cfc 100644
--- a/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/StyleBuilderFunctions.cpp.tmpl
@@ -461,15 +461,27 @@
 {{declare_value_function(property_id)}}
 {
     Vector<GridTrackSize> trackSizes;
+    Vector<GridTrackSize> autoRepeatTrackSizes;
+    size_t autoRepeatInsertionPoint;
     NamedGridLinesMap namedGridLines;
     OrderedNamedGridLines orderedNamedGridLines;
-    StyleBuilderConverter::convertGridTrackList(*value, trackSizes, namedGridLines, orderedNamedGridLines, state);
+    NamedGridLinesMap autoRepeatNamedGridLines;
+    OrderedNamedGridLines autoRepeatOrderedNamedGridLines;
+    AutoRepeatType autoRepeatType;
+    StyleBuilderConverter::convertGridTrackList(*value, trackSizes, namedGridLines, orderedNamedGridLines, autoRepeatTrackSizes, autoRepeatNamedGridLines, autoRepeatOrderedNamedGridLines, autoRepeatInsertionPoint, autoRepeatType, state);
     const NamedGridAreaMap& namedGridAreas = state.style()->namedGridArea();
     if (!namedGridAreas.isEmpty())
         StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(namedGridAreas, namedGridLines, For{{type}}s);
     state.style()->setGridTemplate{{type}}s(trackSizes);
     state.style()->setNamedGrid{{type}}Lines(namedGridLines);
     state.style()->setOrderedNamedGrid{{type}}Lines(orderedNamedGridLines);
+    if (autoRepeatTrackSizes.size()) {
+        state.style()->setGridAutoRepeat{{type}}s(autoRepeatTrackSizes);
+        state.style()->setGridAutoRepeat{{type}}sInsertionPoint(autoRepeatInsertionPoint);
+        state.style()->setAutoRepeatNamedGrid{{type}}Lines(autoRepeatNamedGridLines);
+        state.style()->setAutoRepeatOrderedNamedGrid{{type}}Lines(autoRepeatOrderedNamedGridLines);
+        state.style()->setGridAutoRepeatType(autoRepeatType);
+    }
 }
 {% endmacro %}
 {{apply_grid_template('CSSPropertyGridTemplateColumns', 'Column')}}
diff --git a/third_party/WebKit/Source/core/Init.cpp b/third_party/WebKit/Source/core/Init.cpp
index ccfa175..4e58196 100644
--- a/third_party/WebKit/Source/core/Init.cpp
+++ b/third_party/WebKit/Source/core/Init.cpp
@@ -49,6 +49,7 @@
 #include "core/dom/StyleChangeReason.h"
 #include "core/events/EventFactory.h"
 #include "core/fetch/FetchInitiatorTypeNames.h"
+#include "core/fetch/WebCacheMemoryDumpProvider.h"
 #include "core/html/canvas/CanvasRenderingContextFactory.h"
 #include "core/html/parser/HTMLParserThread.h"
 #include "core/workers/WorkerThread.h"
@@ -137,6 +138,8 @@
 
     StringImpl::freezeStaticStrings();
 
+    Platform::current()->registerMemoryDumpProvider(WebCacheMemoryDumpProvider::instance(), "MemoryCache");
+
     // Creates HTMLParserThread::shared and ScriptStreamerThread::shared, but
     // does not start the threads.
     HTMLParserThread::init();
@@ -154,6 +157,8 @@
     ASSERT(Platform::current());
     HTMLParserThread::shutdown();
 
+    Platform::current()->unregisterMemoryDumpProvider(WebCacheMemoryDumpProvider::instance());
+
     WorkerThread::terminateAndWaitForAllWorkers();
 }
 
diff --git a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp
index 10588d72..388d58b5 100644
--- a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp
@@ -43,7 +43,7 @@
 {
     if (FontSize::isValidValueID(valueID)) {
         // TODO(alancutter): Be responsive to changes in isMonospace().
-        return convertFontSize(state.fontBuilder().fontSizeForKeyword(FontSize::keywordSize(valueID), state.style()->fontDescription().isMonospace()));
+        return convertFontSize(state.fontBuilder().fontSizeForKeyword(FontSize::keywordSize(valueID), state.style()->getFontDescription().isMonospace()));
     }
 
     if (valueID != CSSValueSmaller && valueID != CSSValueLarger)
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
index 995b892..a8cfc2a 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
@@ -252,7 +252,7 @@
     }
     if (m_dragImage) {
         loc = m_dragLoc;
-        return DragImage::create(m_dragImage->image());
+        return DragImage::create(m_dragImage->getImage());
     }
     return nullptr;
 }
@@ -276,14 +276,14 @@
 {
     // Shove image data into a DataObject for use as a file
     ImageResource* cachedImage = getImageResource(element);
-    if (!cachedImage || !cachedImage->image() || !cachedImage->isLoaded())
+    if (!cachedImage || !cachedImage->getImage() || !cachedImage->isLoaded())
         return;
 
-    SharedBuffer* imageBuffer = cachedImage->image()->data();
+    SharedBuffer* imageBuffer = cachedImage->getImage()->data();
     if (!imageBuffer || !imageBuffer->size())
         return;
 
-    String imageExtension = cachedImage->image()->filenameExtension();
+    String imageExtension = cachedImage->getImage()->filenameExtension();
     ASSERT(!imageExtension.isEmpty());
 
     // Determine the filename for the file contents of the image.
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 3cdb438..87d2d13 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -1135,6 +1135,8 @@
             'css/CSSFunctionValue.h',
             'css/CSSGradientValue.cpp',
             'css/CSSGradientValue.h',
+            'css/CSSGridAutoRepeatValue.h',
+            'css/CSSGridAutoRepeatValue.cpp',
             'css/CSSGridLineNamesValue.cpp',
             'css/CSSGridLineNamesValue.h',
             'css/CSSGridTemplateAreasValue.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
index c129d6b..a525011 100644
--- a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
+++ b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -424,11 +424,11 @@
     if (!style)
         return nullptr;
 
-    if (int keywordSize = style->fontDescription().keywordSize())
+    if (int keywordSize = style->getFontDescription().keywordSize())
         return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
 
 
-    return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), *style);
+    return zoomAdjustedPixelValue(style->getFontDescription().computedPixelSize(), *style);
 }
 
 bool CSSComputedStyleDeclaration::isMonospaceFont() const
@@ -440,7 +440,7 @@
     if (!style)
         return false;
 
-    return style->fontDescription().isMonospace();
+    return style->getFontDescription().isMonospace();
 }
 
 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
@@ -612,8 +612,8 @@
     if (propertyID == CSSPropertyFontSize && propertyValue->isPrimitiveValue() && m_node) {
         m_node->document().updateLayoutIgnorePendingStylesheets();
         const ComputedStyle* style = m_node->ensureComputedStyle(m_pseudoElementSpecifier);
-        if (style && style->fontDescription().keywordSize()) {
-            CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
+        if (style && style->getFontDescription().keywordSize()) {
+            CSSValueID sizeValue = cssIdentifierForFontSizeKeyword(style->getFontDescription().keywordSize());
             const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(propertyValue);
             if (primitiveValue->isValueID() && primitiveValue->getValueID() == sizeValue)
                 return true;
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
index c657f2b..5650a2d 100644
--- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
@@ -88,10 +88,10 @@
 {
     ImageResource* cachedImage = cachedImageForCSSValue(value, &layoutObject->document());
 
-    if (!cachedImage || cachedImage->errorOccurred() || cachedImage->image()->isNull())
+    if (!cachedImage || cachedImage->errorOccurred() || cachedImage->getImage()->isNull())
         return nullptr;
 
-    return cachedImage->image();
+    return cachedImage->getImage();
 }
 
 static KURL urlForCSSValue(const CSSValue* value)
diff --git a/third_party/WebKit/Source/core/css/CSSGridAutoRepeatValue.cpp b/third_party/WebKit/Source/core/css/CSSGridAutoRepeatValue.cpp
new file mode 100644
index 0000000..238c6ed
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/CSSGridAutoRepeatValue.cpp
@@ -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 "core/css/CSSGridAutoRepeatValue.h"
+
+#include "wtf/text/StringBuilder.h"
+
+namespace blink {
+
+String CSSGridAutoRepeatValue::customCSSText() const
+{
+    StringBuilder result;
+    result.append("repeat(");
+    result.append(getValueName(autoRepeatID()));
+    result.append(", ");
+    result.append(CSSValueList::customCSSText());
+    result.append(")");
+    return result.toString();
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/CSSGridAutoRepeatValue.h b/third_party/WebKit/Source/core/css/CSSGridAutoRepeatValue.h
new file mode 100644
index 0000000..1b69f935
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/CSSGridAutoRepeatValue.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 CSSGridAutoRepeatValue_h
+#define CSSGridAutoRepeatValue_h
+
+#include "core/CSSValueKeywords.h"
+#include "core/css/CSSValueList.h"
+
+namespace blink {
+
+// CSSGridAutoRepeatValue stores the track sizes and line numbers when the auto-repeat
+// syntax is used
+//
+// Right now the auto-repeat syntax is as follows:
+// <auto-repeat>  = repeat( [ auto-fill | auto-fit ], <line-names>? <fixed-size> <line-names>? )
+//
+// meaning that only one fixed size track is allowed. It could be argued that a different
+// class storing two CSSGridLineNamesValue and one CSSValue (for the track size) fits
+// better but the CSSWG has left the door open to allow more than one track in the
+// future. That's why we're using a list, it's prepared for future changes and it also
+// allows us to keep the parsing algorithm almost intact.
+class CSSGridAutoRepeatValue : public CSSValueList {
+public:
+    static PassRefPtrWillBeRawPtr<CSSGridAutoRepeatValue> create(CSSValueID id)
+    {
+        return adoptRefWillBeNoop(new CSSGridAutoRepeatValue(id));
+    }
+
+    String customCSSText() const;
+    CSSValueID autoRepeatID() const { return m_autoRepeatID; }
+
+    DEFINE_INLINE_TRACE_AFTER_DISPATCH() { CSSValueList::traceAfterDispatch(visitor); }
+
+private:
+    CSSGridAutoRepeatValue(CSSValueID id)
+        : CSSValueList(GridAutoRepeatClass, SpaceSeparator)
+        , m_autoRepeatID(id)
+    {
+        ASSERT(id == CSSValueAutoFill || id == CSSValueAutoFit);
+    }
+
+    const CSSValueID m_autoRepeatID;
+};
+
+DEFINE_CSS_VALUE_TYPE_CASTS(CSSGridAutoRepeatValue, isGridAutoRepeatValue());
+
+} // namespace blink
+
+#endif // CSSGridAutoRepeatValue_h
diff --git a/third_party/WebKit/Source/core/css/CSSMarkup.cpp b/third_party/WebKit/Source/core/css/CSSMarkup.cpp
index b9c1fec..07be456 100644
--- a/third_party/WebKit/Source/core/css/CSSMarkup.cpp
+++ b/third_party/WebKit/Source/core/css/CSSMarkup.cpp
@@ -69,46 +69,6 @@
 }
 
 template <typename CharacterType>
-static inline bool isCSSTokenizerURL(const CharacterType* characters, unsigned length)
-{
-    const CharacterType* end = characters + length;
-
-    for (; characters != end; ++characters) {
-        CharacterType c = characters[0];
-        switch (c) {
-        case '!':
-        case '#':
-        case '$':
-        case '%':
-        case '&':
-            break;
-        default:
-            if (c < '*')
-                return false;
-            if (c <= '~')
-                break;
-            if (c < 128)
-                return false;
-        }
-    }
-
-    return true;
-}
-
-// "url" from the CSS tokenizer, minus backslash-escape sequences
-static bool isCSSTokenizerURL(const String& string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return true;
-
-    if (string.is8Bit())
-        return isCSSTokenizerURL(string.characters8(), length);
-    return isCSSTokenizerURL(string.characters16(), length);
-}
-
-template <typename CharacterType>
 static inline String quoteCSSStringInternal(const CharacterType* characters, unsigned length)
 {
     // For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
@@ -181,11 +141,6 @@
     return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);
 }
 
-String quoteCSSURLIfNeeded(const String& string)
-{
-    return isCSSTokenizerURL(string) ? string : quoteCSSString(string);
-}
-
 static void serializeCharacter(UChar32 c, StringBuilder& appendTo)
 {
     appendTo.append('\\');
diff --git a/third_party/WebKit/Source/core/css/CSSMarkup.h b/third_party/WebKit/Source/core/css/CSSMarkup.h
index 9371e94..f50e7e8 100644
--- a/third_party/WebKit/Source/core/css/CSSMarkup.h
+++ b/third_party/WebKit/Source/core/css/CSSMarkup.h
@@ -30,7 +30,6 @@
 namespace blink {
 
 String quoteCSSStringIfNeeded(const String&);
-String quoteCSSURLIfNeeded(const String&);
 
 // Common serializing methods. See: http://dev.w3.org/csswg/cssom/#common-serializing-idioms
 void serializeIdentifier(const String& identifier, StringBuilder& appendTo);
diff --git a/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp b/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp
index 5080f8e..c9b3a264 100644
--- a/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp
+++ b/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp
@@ -118,5 +118,37 @@
     memoryCache()->pruneAll();
 }
 
+TEST_F(CSSStyleSheetResourceTest, DuplicateResourceNotCached)
+{
+    const char url[] = "https://localhost/style.css";
+    KURL imageURL(KURL(), url);
+    KURL cssURL(KURL(), url);
+
+    // Emulate using <img> to do async stylesheet preloads.
+
+    RefPtrWillBeRawPtr<Resource> imageResource = ImageResource::create(ResourceRequest(imageURL), nullptr);
+    ASSERT_TRUE(imageResource);
+    memoryCache()->add(imageResource.get());
+    ASSERT_TRUE(memoryCache()->contains(imageResource.get()));
+
+    RefPtrWillBeRawPtr<CSSStyleSheetResource> cssResource = CSSStyleSheetResource::createForTest(ResourceRequest(cssURL), "utf-8");
+    cssResource->responseReceived(ResourceResponse(cssURL, "style/css", 0, nullAtom, String()), nullptr);
+    cssResource->finish();
+
+    RefPtrWillBeRawPtr<StyleSheetContents> contents = StyleSheetContents::create(CSSParserContext(HTMLStandardMode, nullptr));
+    RefPtrWillBeRawPtr<CSSStyleSheet> sheet = CSSStyleSheet::create(contents, document());
+    EXPECT_TRUE(sheet);
+
+    contents->checkLoaded();
+    cssResource->saveParsedStyleSheet(contents);
+
+    // Verify that the cache will have a mapping for |imageResource| at |url|.
+    // The underlying |contents| for the stylesheet resource must have a
+    // matching cache status.
+    ASSERT_TRUE(memoryCache()->contains(imageResource.get()));
+    ASSERT_FALSE(memoryCache()->contains(cssResource.get()));
+    ASSERT_FALSE(contents->isInMemoryCache());
+}
+
 } // namespace
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
index a137fa6c..f34b0ea 100644
--- a/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
+++ b/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
@@ -56,15 +56,15 @@
     // FIXME: We have a bug right now where the zoom will be applied twice to EX units.
     // We really need to compute EX using fontMetrics for the original specifiedSize and not use
     // our actual constructed layoutObject font.
-    if (!m_font->fontMetrics().hasXHeight())
+    if (!m_font->getFontMetrics().hasXHeight())
         return m_em / 2.0f;
-    return m_font->fontMetrics().xHeight();
+    return m_font->getFontMetrics().xHeight();
 }
 
 float CSSToLengthConversionData::FontSizes::ch() const
 {
     ASSERT(m_font);
-    return m_font->fontMetrics().zeroWidth();
+    return m_font->getFontMetrics().zeroWidth();
 }
 
 CSSToLengthConversionData::ViewportSize::ViewportSize(const LayoutView* layoutView)
diff --git a/third_party/WebKit/Source/core/css/CSSValue.cpp b/third_party/WebKit/Source/core/css/CSSValue.cpp
index 4f3dd601..7481533 100644
--- a/third_party/WebKit/Source/core/css/CSSValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSValue.cpp
@@ -39,6 +39,7 @@
 #include "core/css/CSSFontFeatureValue.h"
 #include "core/css/CSSFunctionValue.h"
 #include "core/css/CSSGradientValue.h"
+#include "core/css/CSSGridAutoRepeatValue.h"
 #include "core/css/CSSGridLineNamesValue.h"
 #include "core/css/CSSGridTemplateAreasValue.h"
 #include "core/css/CSSImageSetValue.h"
@@ -137,6 +138,8 @@
             return compareCSSValues<CSSInitialValue>(*this, other);
         case UnsetClass:
             return compareCSSValues<CSSUnsetValue>(*this, other);
+        case GridAutoRepeatClass:
+            return compareCSSValues<CSSGridAutoRepeatValue>(*this, other);
         case GridLineNamesClass:
             return compareCSSValues<CSSGridLineNamesValue>(*this, other);
         case GridTemplateAreasClass:
@@ -223,6 +226,8 @@
         return toCSSUnsetValue(this)->customCSSText();
     case InitialClass:
         return toCSSInitialValue(this)->customCSSText();
+    case GridAutoRepeatClass:
+        return toCSSGridAutoRepeatValue(this)->customCSSText();
     case GridLineNamesClass:
         return toCSSGridLineNamesValue(this)->customCSSText();
     case GridTemplateAreasClass:
@@ -326,6 +331,9 @@
     case UnsetClass:
         delete toCSSUnsetValue(this);
         return;
+    case GridAutoRepeatClass:
+        delete toCSSGridAutoRepeatValue(this);
+        return;
     case GridLineNamesClass:
         delete toCSSGridLineNamesValue(this);
         return;
@@ -447,6 +455,9 @@
     case UnsetClass:
         toCSSUnsetValue(this)->~CSSUnsetValue();
         return;
+    case GridAutoRepeatClass:
+        toCSSGridAutoRepeatValue(this)->~CSSGridAutoRepeatValue();
+        return;
     case GridLineNamesClass:
         toCSSGridLineNamesValue(this)->~CSSGridLineNamesValue();
         return;
@@ -568,6 +579,9 @@
     case UnsetClass:
         toCSSUnsetValue(this)->traceAfterDispatch(visitor);
         return;
+    case GridAutoRepeatClass:
+        toCSSGridAutoRepeatValue(this)->traceAfterDispatch(visitor);
+        return;
     case GridLineNamesClass:
         toCSSGridLineNamesValue(this)->traceAfterDispatch(visitor);
         return;
diff --git a/third_party/WebKit/Source/core/css/CSSValue.h b/third_party/WebKit/Source/core/css/CSSValue.h
index 8b52da1..33eb456f 100644
--- a/third_party/WebKit/Source/core/css/CSSValue.h
+++ b/third_party/WebKit/Source/core/css/CSSValue.h
@@ -108,6 +108,7 @@
     bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; }
     bool isCustomPropertyDeclaration() const { return m_classType == CustomPropertyDeclarationClass; }
     bool isVariableReferenceValue() const { return m_classType == VariableReferenceClass; }
+    bool isGridAutoRepeatValue() const { return m_classType == GridAutoRepeatClass; }
 
     bool hasFailedOrCanceledSubresources() const;
 
@@ -182,6 +183,7 @@
         FunctionClass,
         ImageSetClass,
         GridLineNamesClass,
+        GridAutoRepeatClass,
         // Do not append non-list class types here.
     };
 
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 719b130e..82158100f 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -465,7 +465,7 @@
     if (length.isNegative())
         return cssValuePool().createIdentifierValue(CSSValueNormal);
 
-    return zoomAdjustedPixelValue(floatValueForLength(length, style.fontDescription().computedSize()), style);
+    return zoomAdjustedPixelValue(floatValueForLength(length, style.getFontDescription().computedSize()), style);
 }
 
 static CSSValueID identifierForFamily(const AtomicString& family)
@@ -494,7 +494,7 @@
 
 static PassRefPtrWillBeRawPtr<CSSValueList> valueForFontFamily(const ComputedStyle& style)
 {
-    const FontFamily& firstFamily = style.fontDescription().family();
+    const FontFamily& firstFamily = style.getFontDescription().family();
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     for (const FontFamily* family = &firstFamily; family; family = family->next())
         list->append(valueForFamily(family->family()));
@@ -503,27 +503,27 @@
 
 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontSize(const ComputedStyle& style)
 {
-    return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style);
+    return zoomAdjustedPixelValue(style.getFontDescription().computedSize(), style);
 }
 
 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontStretch(const ComputedStyle& style)
 {
-    return cssValuePool().createValue(style.fontDescription().stretch());
+    return cssValuePool().createValue(style.getFontDescription().stretch());
 }
 
 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontStyle(const ComputedStyle& style)
 {
-    return cssValuePool().createValue(style.fontDescription().style());
+    return cssValuePool().createValue(style.getFontDescription().style());
 }
 
 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontVariant(const ComputedStyle& style)
 {
-    return cssValuePool().createValue(style.fontDescription().variant());
+    return cssValuePool().createValue(style.getFontDescription().variant());
 }
 
 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontWeight(const ComputedStyle& style)
 {
-    return cssValuePool().createValue(style.fontDescription().weight());
+    return cssValuePool().createValue(style.getFontDescription().weight());
 }
 
 static PassRefPtrWillBeRawPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const ComputedStyle& style)
@@ -566,12 +566,15 @@
 
 static PassRefPtrWillBeRawPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, const LayoutObject* layoutObject, const ComputedStyle& style)
 {
-    const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridTemplateColumns() : style.gridTemplateRows();
-    const OrderedNamedGridLines& orderedNamedGridLines = direction == ForColumns ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines();
+    bool isRowAxis = direction == ForColumns;
+    const Vector<GridTrackSize>& trackSizes = isRowAxis ? style.gridTemplateColumns() : style.gridTemplateRows();
+    const Vector<GridTrackSize>& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows();
+    const OrderedNamedGridLines& orderedNamedGridLines = isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines();
+
     bool isLayoutGrid = layoutObject && layoutObject->isLayoutGrid();
 
     // Handle the 'none' case.
-    bool trackListIsEmpty = trackSizes.isEmpty();
+    bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty();
     if (isLayoutGrid && trackListIsEmpty) {
         // For grids we should consider every listed track, whether implicitly or explicitly created. If we don't have
         // any explicit track and there are no children then there are no implicit tracks. We cannot simply check the
@@ -1213,7 +1216,7 @@
         switch (filterOperation->type()) {
         case FilterOperation::REFERENCE:
             filterValue = CSSFunctionValue::create(CSSValueUrl);
-            filterValue->append(CSSCustomIdentValue::create(toReferenceFilterOperation(filterOperation)->url()));
+            filterValue->append(CSSStringValue::create(toReferenceFilterOperation(filterOperation)->url()));
             break;
         case FilterOperation::GRAYSCALE:
             filterValue = CSSFunctionValue::create(CSSValueGrayscale);
@@ -1661,7 +1664,7 @@
     case CSSPropertyFontWeight:
         return valueForFontWeight(style);
     case CSSPropertyFontFeatureSettings: {
-        const FontFeatureSettings* featureSettings = style.fontDescription().featureSettings();
+        const FontFeatureSettings* featureSettings = style.getFontDescription().featureSettings();
         if (!featureSettings || !featureSettings->size())
             return cssValuePool().createIdentifierValue(CSSValueNormal);
         RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
@@ -2015,7 +2018,7 @@
     case CSSPropertyTextShadow:
         return valueForShadowList(style.textShadow(), style, false);
     case CSSPropertyTextRendering:
-        return cssValuePool().createValue(style.fontDescription().textRendering());
+        return cssValuePool().createValue(style.getFontDescription().textRendering());
     case CSSPropertyTextOverflow:
         if (style.getTextOverflow())
             return cssValuePool().createIdentifierValue(CSSValueEllipsis);
@@ -2087,14 +2090,14 @@
     case CSSPropertyResize:
         return cssValuePool().createValue(style.resize());
     case CSSPropertyFontKerning:
-        return cssValuePool().createValue(style.fontDescription().getKerning());
+        return cssValuePool().createValue(style.getFontDescription().getKerning());
     case CSSPropertyWebkitFontSmoothing:
-        return cssValuePool().createValue(style.fontDescription().fontSmoothing());
+        return cssValuePool().createValue(style.getFontDescription().fontSmoothing());
     case CSSPropertyFontVariantLigatures: {
-        FontDescription::LigaturesState commonLigaturesState = style.fontDescription().commonLigaturesState();
-        FontDescription::LigaturesState discretionaryLigaturesState = style.fontDescription().discretionaryLigaturesState();
-        FontDescription::LigaturesState historicalLigaturesState = style.fontDescription().historicalLigaturesState();
-        FontDescription::LigaturesState contextualLigaturesState = style.fontDescription().contextualLigaturesState();
+        FontDescription::LigaturesState commonLigaturesState = style.getFontDescription().commonLigaturesState();
+        FontDescription::LigaturesState discretionaryLigaturesState = style.getFontDescription().discretionaryLigaturesState();
+        FontDescription::LigaturesState historicalLigaturesState = style.getFontDescription().historicalLigaturesState();
+        FontDescription::LigaturesState contextualLigaturesState = style.getFontDescription().contextualLigaturesState();
         if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
             && historicalLigaturesState == FontDescription::NormalLigaturesState && contextualLigaturesState == FontDescription::NormalLigaturesState)
             return cssValuePool().createIdentifierValue(CSSValueNormal);
diff --git a/third_party/WebKit/Source/core/css/FontFaceSet.cpp b/third_party/WebKit/Source/core/css/FontFaceSet.cpp
index 2673d2860..5d69583 100644
--- a/third_party/WebKit/Source/core/css/FontFaceSet.cpp
+++ b/third_party/WebKit/Source/core/css/FontFaceSet.cpp
@@ -385,8 +385,8 @@
 
     FontFaceCache* fontFaceCache = document()->styleEngine().fontSelector()->fontFaceCache();
     FontFaceArray faces;
-    for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
-        CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.fontDescription(), f->family());
+    for (const FontFamily* f = &font.getFontDescription().family(); f; f = f->next()) {
+        CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.getFontDescription(), f->family());
         if (segmentedFontFace)
             segmentedFontFace->match(text, faces);
     }
@@ -412,8 +412,8 @@
     FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
 
     bool hasLoadedFaces = false;
-    for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
-        CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family());
+    for (const FontFamily* f = &font.getFontDescription().family(); f; f = f->next()) {
+        CSSSegmentedFontFace* face = fontFaceCache->get(font.getFontDescription(), f->family());
         if (face) {
             if (!face->checkFont(text))
                 return false;
@@ -422,8 +422,8 @@
     }
     if (hasLoadedFaces)
         return true;
-    for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
-        if (fontSelector->isPlatformFontAvailable(font.fontDescription(), f->family()))
+    for (const FontFamily* f = &font.getFontDescription().family(); f; f = f->next()) {
+        if (fontSelector->isPlatformFontAvailable(font.getFontDescription(), f->family()))
             return true;
     }
     return false;
@@ -456,7 +456,7 @@
 
     style->setFontDescription(defaultFontDescription);
 
-    style->font().update(style->font().fontSelector());
+    style->font().update(style->font().getFontSelector());
 
     document()->ensureStyleResolver().computeFont(style.get(), *parsedStyle);
 
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
index adc1f6bc..6f0ca6a 100644
--- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp
+++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -1136,7 +1136,7 @@
             return false;
         }
     case CSSSelector::PseudoCornerPresent:
-        return m_scrollbar->scrollableArea() && m_scrollbar->scrollableArea()->isScrollCornerVisible();
+        return m_scrollbar->getScrollableArea() && m_scrollbar->getScrollableArea()->isScrollCornerVisible();
     default:
         return false;
     }
diff --git a/third_party/WebKit/Source/core/css/StyleSheetContents.cpp b/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
index e76b0389..0b89df7 100644
--- a/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
+++ b/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
@@ -579,7 +579,6 @@
 
 void StyleSheetContents::removedFromMemoryCache()
 {
-    ASSERT(m_isInMemoryCache);
     ASSERT(isCacheable());
     m_isInMemoryCache = false;
 }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index a85fe10..76d2b2e 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -50,7 +50,6 @@
     , m_parsedProperties(parsedProperties)
     , m_inParseShorthand(0)
     , m_currentShorthand(CSSPropertyInvalid)
-    , m_implicitShorthand(false)
 {
     m_range.consumeWhitespace();
 }
@@ -3553,6 +3552,46 @@
     return result.release();
 }
 
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeSelfPositionKeyword(CSSParserTokenRange& range)
+{
+    CSSValueID id = range.peek().id();
+    if (id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
+        || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart
+        || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight)
+        return consumeIdent(range);
+    return nullptr;
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumeSelfPositionOverflowPosition(CSSParserTokenRange& range)
+{
+    if (identMatches<CSSValueAuto, CSSValueStretch, CSSValueBaseline, CSSValueLastBaseline>(range.peek().id()))
+        return consumeIdent(range);
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> overflowPosition = consumeIdent<CSSValueUnsafe, CSSValueSafe>(range);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> selfPosition = consumeSelfPositionKeyword(range);
+    if (!selfPosition)
+        return nullptr;
+    if (!overflowPosition)
+        overflowPosition = consumeIdent<CSSValueUnsafe, CSSValueSafe>(range);
+    if (overflowPosition)
+        return CSSValuePair::create(selfPosition.release(), overflowPosition, CSSValuePair::DropIdenticalValues);
+    return selfPosition.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumeJustifyItems(CSSParserTokenRange& range)
+{
+    CSSParserTokenRange rangeCopy = range;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> legacy = consumeIdent<CSSValueLegacy>(rangeCopy);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> positionKeyword = consumeIdent<CSSValueCenter, CSSValueLeft, CSSValueRight>(rangeCopy);
+    if (!legacy)
+        legacy = consumeIdent<CSSValueLegacy>(rangeCopy);
+    if (legacy && positionKeyword) {
+        range = rangeCopy;
+        return CSSValuePair::create(legacy.release(), positionKeyword.release(), CSSValuePair::DropIdenticalValues);
+    }
+    return consumeSelfPositionOverflowPosition(range);
+}
+
 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty)
 {
     CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
@@ -3907,6 +3946,14 @@
     case CSSPropertyWebkitMaskRepeatX:
     case CSSPropertyWebkitMaskRepeatY:
         return nullptr;
+    case CSSPropertyJustifySelf:
+    case CSSPropertyAlignSelf:
+    case CSSPropertyAlignItems:
+        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+        return consumeSelfPositionOverflowPosition(m_range);
+    case CSSPropertyJustifyItems:
+        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+        return consumeJustifyItems(m_range);
     default:
         CSSParserValueList valueList(m_range);
         if (valueList.size()) {
@@ -4294,7 +4341,6 @@
             return false;
     } while (!m_range.atEnd());
 
-    ImplicitScope implicitScope(this);
     for (size_t i = 0; i < shorthand.length(); ++i) {
         if (longhands[i])
             addProperty(shorthandProperties[i], longhands[i].release(), important);
@@ -4431,7 +4477,6 @@
     RefPtrWillBeRawPtr<CSSValue> outset = nullptr;
     RefPtrWillBeRawPtr<CSSValue> repeat = nullptr;
     if (consumeBorderImageComponents(property, m_range, m_context, source, slice, width, outset, repeat)) {
-        ImplicitScope implicitScope(this);
         switch (property) {
         case CSSPropertyWebkitMaskBoxImage:
             addProperty(CSSPropertyWebkitMaskBoxImageSource, source ? source : cssValuePool().createImplicitInitialValue(), important);
@@ -4751,7 +4796,6 @@
     case CSSPropertyWebkitTextStroke:
         return consumeShorthandGreedily(webkitTextStrokeShorthand(), important);
     case CSSPropertyMarker: {
-        ImplicitScope implicitScope(this);
         RefPtrWillBeRawPtr<CSSValue> marker = parseSingleValue(CSSPropertyMarkerStart);
         if (!marker || !m_range.atEnd())
             return false;
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
index aa12460..54a3c230 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -137,9 +137,6 @@
     bool parseGridLineNames(CSSParserValueList&, CSSValueList&, CSSGridLineNamesValue* = nullptr);
     PassRefPtrWillBeRawPtr<CSSValue> parseGridAutoFlow(CSSParserValueList&);
 
-    PassRefPtrWillBeRawPtr<CSSValue> parseLegacyPosition();
-    PassRefPtrWillBeRawPtr<CSSValue> parseItemPositionOverflowPosition();
-
     bool consumeFont(bool important);
     bool consumeSystemFont(bool important);
 
@@ -157,25 +154,6 @@
     PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
     PassRefPtrWillBeRawPtr<CSSCustomIdentValue> createPrimitiveCustomIdentValue(CSSParserValue*);
 
-    class ImplicitScope {
-        STACK_ALLOCATED();
-        WTF_MAKE_NONCOPYABLE(ImplicitScope);
-    public:
-        ImplicitScope(CSSPropertyParser* parser)
-            : m_parser(parser)
-        {
-            m_parser->m_implicitShorthand = true;
-        }
-
-        ~ImplicitScope()
-        {
-            m_parser->m_implicitShorthand = false;
-        }
-
-    private:
-        CSSPropertyParser* m_parser;
-    };
-
     class ShorthandScope {
         STACK_ALLOCATED();
     public:
@@ -223,7 +201,6 @@
     // Locals during parsing:
     int m_inParseShorthand;
     CSSPropertyID m_currentShorthand;
-    bool m_implicitShorthand;
     RefPtrWillBeMember<CSSCalcValue> m_parsedCalculation;
 };
 
diff --git a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
index 9c56692..cadf7672 100644
--- a/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp
@@ -29,6 +29,7 @@
 #include "core/StylePropertyShorthand.h"
 #include "core/css/CSSCustomIdentValue.h"
 #include "core/css/CSSFunctionValue.h"
+#include "core/css/CSSGridAutoRepeatValue.h"
 #include "core/css/CSSGridLineNamesValue.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
 #include "core/css/CSSValuePair.h"
@@ -54,7 +55,7 @@
             shorthandIndex = indexOfShorthandForLonghand(m_currentShorthand, shorthands);
     }
 
-    m_parsedProperties->append(CSSProperty(propId, value, important, setFromShorthand, shorthandIndex, m_implicitShorthand || implicit));
+    m_parsedProperties->append(CSSProperty(propId, value, important, setFromShorthand, shorthandIndex, implicit));
 }
 
 bool CSSPropertyParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc)
@@ -259,19 +260,6 @@
     RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr;
 
     switch (propId) {
-    case CSSPropertyJustifySelf:
-        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-        parsedValue = parseItemPositionOverflowPosition();
-        break;
-    case CSSPropertyJustifyItems:
-        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
-        if ((parsedValue = parseLegacyPosition()))
-            break;
-
-        m_valueList->setCurrentIndex(0);
-        parsedValue = parseItemPositionOverflowPosition();
-        break;
     case CSSPropertyGridAutoFlow:
         ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
         parsedValue = parseGridAutoFlow(*m_valueList);
@@ -301,18 +289,6 @@
         parsedValue = parseGridTemplateAreas();
         break;
 
-        break;
-
-    case CSSPropertyAlignSelf:
-        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-        parsedValue = parseItemPositionOverflowPosition();
-        break;
-
-    case CSSPropertyAlignItems:
-        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-        parsedValue = parseItemPositionOverflowPosition();
-        break;
-
     // Everything else is handled in CSSPropertyParser.cpp
     default:
         return nullptr;
@@ -798,6 +774,28 @@
     return true;
 }
 
+static bool allTracksAreFixedSized(CSSValueList& valueList)
+{
+    for (auto value : valueList) {
+        if (value->isGridLineNamesValue())
+            continue;
+        // The auto-repeat value holds a <fixed-size> = <fixed-breadth> | minmax( <fixed-breadth>, <track-breadth> )
+        if (value->isGridAutoRepeatValue()) {
+            if (!allTracksAreFixedSized(toCSSValueList(*value)))
+                return false;
+            continue;
+        }
+        ASSERT(value->isPrimitiveValue() || (value->isFunctionValue() && toCSSFunctionValue(*value).item(0)));
+        const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue()
+            ? toCSSPrimitiveValue(*value)
+            : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0));
+        CSSValueID valueID = primitiveValue.getValueID();
+        if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || valueID == CSSValueAuto || primitiveValue.isFlex())
+            return false;
+    }
+    return true;
+}
+
 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTrackList()
 {
     ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
@@ -844,19 +842,8 @@
 
     // <auto-repeat> requires definite minimum track sizes in order to compute the number of repetitions.
     // The above while loop detects those appearances after the <auto-repeat> but not the ones before.
-    if (seenAutoRepeat) {
-        for (auto value : *values) {
-            if (value->isGridLineNamesValue())
-                continue;
-            ASSERT(value->isPrimitiveValue() || (value->isFunctionValue() && toCSSFunctionValue(*value).item(0)));
-            const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue()
-                ? toCSSPrimitiveValue(*value)
-                : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0));
-            CSSValueID valueID = primitiveValue.getValueID();
-            if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || valueID == CSSValueAuto || primitiveValue.isFlex())
-                return nullptr;
-        }
-    }
+    if (seenAutoRepeat && !allTracksAreFixedSized(*values))
+        return nullptr;
 
     return values;
 }
@@ -876,7 +863,7 @@
     // because it will be computed later, let's set it to 1.
     size_t repetitions = isAutoRepeat ? 1 : clampTo<size_t>(currentValue->fValue, 0, kGridMaxTracks);
 
-    RefPtrWillBeRawPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated();
+    RefPtrWillBeRawPtr<CSSValueList> repeatedValues = isAutoRepeat ? CSSGridAutoRepeatValue::create(currentValue->id) : CSSValueList::createSpaceSeparated();
     arguments->next(); // Skip the repetition count.
     arguments->next(); // Skip the comma.
 
@@ -906,13 +893,17 @@
     if (!numberOfTracks)
         return false;
 
-    // We clamp the number of repetitions to a multiple of the repeat() track list's size, while staying below the max
-    // grid size.
-    repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks);
+    if (isAutoRepeat) {
+        list.append(repeatedValues.release());
+    } else {
+        // We clamp the number of repetitions to a multiple of the repeat() track list's size, while staying below the max
+        // grid size.
+        repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks);
 
-    for (size_t i = 0; i < repetitions; ++i) {
-        for (size_t j = 0; j < repeatedValues->length(); ++j)
-            list.append(repeatedValues->item(j));
+        for (size_t i = 0; i < repetitions; ++i) {
+            for (size_t j = 0; j < repeatedValues->length(); ++j)
+                list.append(repeatedValues->item(j));
+        }
     }
 
     // parseGridTrackSize iterated over the repeat arguments, move to the next value.
@@ -1141,92 +1132,6 @@
     return parsedValues;
 }
 
-static bool isBaselinePositionKeyword(CSSValueID id)
-{
-    return id == CSSValueBaseline || id == CSSValueLastBaseline;
-}
-
-static bool isAlignmentOverflowKeyword(CSSValueID id)
-{
-    return id == CSSValueUnsafe || id == CSSValueSafe;
-}
-
-static bool isItemPositionKeyword(CSSValueID id)
-{
-    return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
-        || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart
-        || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight;
-}
-
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseLegacyPosition()
-{
-    // [ legacy && [ left | right | center ]
-
-    CSSParserValue* value = m_valueList->current();
-    ASSERT(value);
-
-    if (value->id == CSSValueLegacy) {
-        value = m_valueList->next();
-        if (!value)
-            return nullptr;
-        if (value->id != CSSValueCenter && value->id != CSSValueLeft && value->id != CSSValueRight)
-            return nullptr;
-    } else if (value->id == CSSValueCenter || value->id == CSSValueLeft || value->id == CSSValueRight) {
-        if (!m_valueList->next() || m_valueList->current()->id != CSSValueLegacy)
-            return nullptr;
-    } else {
-        return nullptr;
-    }
-
-    m_valueList->next();
-    return CSSValuePair::create(cssValuePool().createIdentifierValue(CSSValueLegacy), cssValuePool().createIdentifierValue(value->id), CSSValuePair::DropIdenticalValues);
-}
-
-PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseItemPositionOverflowPosition()
-{
-    // auto | stretch | <baseline-position> | [<item-position> && <overflow-position>? ]
-    // <baseline-position> = baseline | last-baseline;
-    // <item-position> = center | start | end | self-start | self-end | flex-start | flex-end | left | right;
-    // <overflow-position> = unsafe | safe
-
-    CSSParserValue* value = m_valueList->current();
-    ASSERT(value);
-
-    if (value->id == CSSValueAuto || value->id == CSSValueStretch || isBaselinePositionKeyword(value->id)) {
-        m_valueList->next();
-        return cssValuePool().createIdentifierValue(value->id);
-    }
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> position = nullptr;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> overflowAlignmentKeyword = nullptr;
-    if (isItemPositionKeyword(value->id)) {
-        position = cssValuePool().createIdentifierValue(value->id);
-        value = m_valueList->next();
-        if (value) {
-            if (isAlignmentOverflowKeyword(value->id))
-                overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
-            else
-                return nullptr;
-        }
-    } else if (isAlignmentOverflowKeyword(value->id)) {
-        overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
-        value = m_valueList->next();
-        if (value && isItemPositionKeyword(value->id))
-            position = cssValuePool().createIdentifierValue(value->id);
-        else
-            return nullptr;
-    } else {
-        return nullptr;
-    }
-
-    m_valueList->next();
-
-    ASSERT(position);
-    if (overflowAlignmentKeyword)
-        return CSSValuePair::create(position, overflowAlignmentKeyword, CSSValuePair::DropIdenticalValues);
-    return position.release();
-}
-
 bool CSSPropertyParser::parseCalculation(CSSParserValue* value, ValueRange range)
 {
     ASSERT(isCalculation(value));
diff --git a/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp b/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp
index 6524b2ed..5458537 100644
--- a/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp
@@ -300,7 +300,7 @@
 
     fontDescription.setSpecifiedSize(specifiedSize);
 
-    checkForGenericFamilyChange(style.fontDescription(), fontDescription);
+    checkForGenericFamilyChange(style.getFontDescription(), fontDescription);
 }
 
 void FontBuilder::updateAdjustedSize(FontDescription& fontDescription, const ComputedStyle& style, FontSelector* fontSelector)
@@ -316,11 +316,11 @@
 
     Font font(fontDescription);
     font.update(fontSelector);
-    if (!font.fontMetrics().hasXHeight())
+    if (!font.getFontMetrics().hasXHeight())
         return;
 
     const float sizeAdjust = fontDescription.sizeAdjust();
-    float aspectValue = font.fontMetrics().xHeight() / specifiedSize;
+    float aspectValue = font.getFontMetrics().xHeight() / specifiedSize;
     float adjustedSize = (sizeAdjust / aspectValue) * specifiedSize;
     adjustedSize = getComputedSizeFromSpecifiedSize(fontDescription, style.effectiveZoom(), adjustedSize);
 
@@ -344,7 +344,7 @@
     if (!m_flags)
         return;
 
-    FontDescription description = style.fontDescription();
+    FontDescription description = style.getFontDescription();
 
     if (isSet(PropertySetFlag::Family)) {
         description.setGenericFamily(m_fontDescription.genericFamily());
diff --git a/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp b/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp
index 35d968a3..e4cab366 100644
--- a/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp
@@ -54,7 +54,7 @@
     builder.setInitial(1.0f); // FIXME: Remove unused param.
     builder.createFont(document().styleEngine().fontSelector(), *initial);
 
-    EXPECT_EQ(16.0f, initial->fontDescription().computedSize());
+    EXPECT_EQ(16.0f, initial->getFontDescription().computedSize());
 }
 
 TEST_F(FontBuilderInitTest, NotDirty)
@@ -79,7 +79,7 @@
     funcs.setValue(fontBuilder);
     fontBuilder.createFont(document().styleEngine().fontSelector(), *style);
 
-    FontDescription outputDescription = style->fontDescription();
+    FontDescription outputDescription = style->getFontDescription();
 
     // FontBuilder should have overwritten our base value set in the parent,
     // hence the descriptions should not be equal.
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
index 445fb9a..8ee0430c 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -31,6 +31,7 @@
 #include "core/css/CSSContentDistributionValue.h"
 #include "core/css/CSSFontFeatureValue.h"
 #include "core/css/CSSFunctionValue.h"
+#include "core/css/CSSGridAutoRepeatValue.h"
 #include "core/css/CSSGridLineNamesValue.h"
 #include "core/css/CSSPathValue.h"
 #include "core/css/CSSPrimitiveValueMappings.h"
@@ -254,9 +255,9 @@
     const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value);
     switch (primitiveValue.getValueID()) {
     case CSSValueBolder:
-        return FontDescription::bolderWeight(state.parentStyle()->fontDescription().weight());
+        return FontDescription::bolderWeight(state.parentStyle()->getFontDescription().weight());
     case CSSValueLighter:
-        return FontDescription::lighterWeight(state.parentStyle()->fontDescription().weight());
+        return FontDescription::lighterWeight(state.parentStyle()->getFontDescription().weight());
     default:
         return primitiveValue.convertTo<FontWeight>();
     }
@@ -451,7 +452,20 @@
     return GridTrackSize(minTrackBreadth, maxTrackBreadth);
 }
 
-void StyleBuilderConverter::convertGridTrackList(const CSSValue& value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, StyleResolverState& state)
+static void convertGridLineNamesList(const CSSValue& value, size_t currentNamedGridLine, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines)
+{
+    ASSERT(value.isGridLineNamesValue());
+
+    for (auto& namedGridLineValue : toCSSValueList(value)) {
+        String namedGridLine = toCSSCustomIdentValue(*namedGridLineValue).value();
+        NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>());
+        result.storedValue->value.append(currentNamedGridLine);
+        OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>());
+        orderedInsertionResult.storedValue->value.append(namedGridLine);
+    }
+}
+
+void StyleBuilderConverter::convertGridTrackList(const CSSValue& value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, Vector<GridTrackSize>& autoRepeatTrackSizes, NamedGridLinesMap& autoRepeatNamedGridLines, OrderedNamedGridLines& autoRepeatOrderedNamedGridLines, size_t& autoRepeatInsertionPoint, AutoRepeatType &autoRepeatType, StyleResolverState& state)
 {
     if (value.isPrimitiveValue()) {
         ASSERT(toCSSPrimitiveValue(value).getValueID() == CSSValueNone);
@@ -459,15 +473,27 @@
     }
 
     size_t currentNamedGridLine = 0;
-    for (auto& currValue : toCSSValueList(value)) {
+    for (auto currValue : toCSSValueList(value)) {
         if (currValue->isGridLineNamesValue()) {
-            for (auto& namedGridLineValue : toCSSGridLineNamesValue(*currValue)) {
-                String namedGridLine = toCSSCustomIdentValue(*namedGridLineValue).value();
-                NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>());
-                result.storedValue->value.append(currentNamedGridLine);
-                OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>());
-                orderedInsertionResult.storedValue->value.append(namedGridLine);
+            convertGridLineNamesList(*currValue, currentNamedGridLine, namedGridLines, orderedNamedGridLines);
+            continue;
+        }
+
+        if (currValue->isGridAutoRepeatValue()) {
+            ASSERT(autoRepeatTrackSizes.isEmpty());
+            size_t autoRepeatIndex = 0;
+            CSSValueID autoRepeatID = toCSSGridAutoRepeatValue(currValue)->autoRepeatID();
+            ASSERT(autoRepeatID == CSSValueAutoFill || autoRepeatID == CSSValueAutoFit);
+            autoRepeatType = autoRepeatID == CSSValueAutoFill ? AutoFill : AutoFit;
+            for (auto autoRepeatValue : toCSSValueList(*currValue)) {
+                if (autoRepeatValue->isGridLineNamesValue()) {
+                    convertGridLineNamesList(*autoRepeatValue, autoRepeatIndex, autoRepeatNamedGridLines, autoRepeatOrderedNamedGridLines);
+                    continue;
+                }
+                ++autoRepeatIndex;
+                autoRepeatTrackSizes.append(convertGridTrackSize(state, *autoRepeatValue));
             }
+            autoRepeatInsertionPoint = currentNamedGridLine++;
             continue;
         }
 
@@ -477,7 +503,7 @@
 
     // The parser should have rejected any <track-list> without any <track-size> as
     // this is not conformant to the syntax.
-    ASSERT(!trackSizes.isEmpty());
+    ASSERT(!trackSizes.isEmpty() || !autoRepeatTrackSizes.isEmpty());
 }
 
 void StyleBuilderConverter::convertOrderedNamedGridLinesMapToNamedGridLinesMap(const OrderedNamedGridLines& orderedNamedGridLines, NamedGridLinesMap& namedGridLines)
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
index 22fd808..e328c8e 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
+++ b/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
@@ -96,7 +96,9 @@
     static float convertTextStrokeWidth(StyleResolverState&, const CSSValue&);
     static TransformOrigin convertTransformOrigin(StyleResolverState&, const CSSValue&);
 
-    static void convertGridTrackList(const CSSValue&, Vector<GridTrackSize>&, NamedGridLinesMap&, OrderedNamedGridLines&, StyleResolverState&);
+    static void convertGridTrackList(const CSSValue&, Vector<GridTrackSize>&, NamedGridLinesMap&, OrderedNamedGridLines&,
+        Vector<GridTrackSize>& autoRepeatTrackSizes, NamedGridLinesMap&, OrderedNamedGridLines&,
+        size_t& autoRepeatInsertionPoint, AutoRepeatType&, StyleResolverState&);
     static void createImplicitNamedGridLinesFromGridArea(const NamedGridAreaMap&, NamedGridLinesMap&, GridTrackSizingDirection);
     static void convertOrderedNamedGridLinesMapToNamedGridLinesMap(const OrderedNamedGridLines&, NamedGridLinesMap&);
 
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
index 73a0484..fdfe9b4 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -555,7 +555,7 @@
     RefPtr<ComputedStyle> documentStyle = ComputedStyle::create();
     documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
     documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() : 1);
-    FontDescription documentFontDescription = documentStyle->fontDescription();
+    FontDescription documentFontDescription = documentStyle->getFontDescription();
     documentFontDescription.setLocale(document.contentLanguage());
     documentStyle->setFontDescription(documentFontDescription);
     documentStyle->setZIndex(0);
@@ -1467,7 +1467,7 @@
     updateFont(state);
 
     // Many properties depend on the font. If it changes we just apply all properties.
-    if (cachedMatchedProperties && cachedMatchedProperties->computedStyle->fontDescription() != state.style()->fontDescription())
+    if (cachedMatchedProperties && cachedMatchedProperties->computedStyle->getFontDescription() != state.style()->getFontDescription())
         applyInheritedOnly = false;
 
     // Now do the normal priority UA properties.
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h b/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h
index fd6c844..b3c88dfa 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h
@@ -130,7 +130,7 @@
     // set these directly on the ComputedStyle w/o telling us. Presumably we'll
     // want to design a better wrapper around ComputedStyle for tracking these mutations
     // and separate it from StyleResolverState.
-    const FontDescription& parentFontDescription() const { return m_parentStyle->fontDescription(); }
+    const FontDescription& parentFontDescription() const { return m_parentStyle->getFontDescription(); }
 
     void setZoom(float f)
     {
diff --git a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
index 9688ef2..7712f84 100644
--- a/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
@@ -145,7 +145,7 @@
         return primitiveValue->getFloatValue();
 
     if (primitiveValue->isFontRelativeLength())
-        return primitiveValue->getFloatValue() * m_document->computedStyle()->fontDescription().computedSize();
+        return primitiveValue->getFloatValue() * m_document->computedStyle()->getFontDescription().computedSize();
 
     if (primitiveValue->isPercentage()) {
         float percentValue = primitiveValue->getFloatValue() / 100.0f;
diff --git a/third_party/WebKit/Source/core/dom/DOMImplementation.cpp b/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
index 16ed9f1..e9f7596 100644
--- a/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
+++ b/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
@@ -234,7 +234,8 @@
     // We do not want QuickTime to take over all image types, obviously.
     if ((type == "application/pdf" || type == "text/pdf") && pluginData && pluginData->supportsMimeType(type))
         return PluginDocument::create(init);
-    if (Image::supportsType(type))
+    // multipart/x-mixed-replace is only supported for images.
+    if (Image::supportsType(type) || type == "multipart/x-mixed-replace")
         return ImageDocument::create(init);
 
     // Check to see if the type can be played by our media player, if so create a MediaDocument
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 22a77889..7003675a 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -901,7 +901,7 @@
     LocalFrame* frame = document().frame();
     if (!frame)
         return;
-    ScrollableArea* viewport = frame->view() ? frame->view()->scrollableArea() : 0;
+    ScrollableArea* viewport = frame->view() ? frame->view()->getScrollableArea() : 0;
     if (!viewport)
         return;
 
@@ -917,7 +917,7 @@
     LocalFrame* frame = document().frame();
     if (!frame)
         return;
-    ScrollableArea* viewport = frame->view() ? frame->view()->scrollableArea() : 0;
+    ScrollableArea* viewport = frame->view() ? frame->view()->getScrollableArea() : 0;
     if (!viewport)
         return;
 
diff --git a/third_party/WebKit/Source/core/dom/Microtask.cpp b/third_party/WebKit/Source/core/dom/Microtask.cpp
index 7c3ec6ed..344c9e01 100644
--- a/third_party/WebKit/Source/core/dom/Microtask.cpp
+++ b/third_party/WebKit/Source/core/dom/Microtask.cpp
@@ -40,13 +40,9 @@
 
 void Microtask::performCheckpoint(v8::Isolate* isolate)
 {
-    V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
-    ASSERT(isolateData);
-    if (isolateData->recursionLevel() || isolateData->performingMicrotaskCheckpoint() || isolateData->destructionPending() || ScriptForbiddenScope::isScriptForbidden())
+    if (ScriptForbiddenScope::isScriptForbidden())
         return;
-    isolateData->setPerformingMicrotaskCheckpoint(true);
-    isolate->RunMicrotasks();
-    isolateData->setPerformingMicrotaskCheckpoint(false);
+    v8::MicrotasksScope::PerformCheckpoint(isolate);
 }
 
 static void microtaskFunctionCallback(void* data)
diff --git a/third_party/WebKit/Source/core/dom/StyleChangeReason.h b/third_party/WebKit/Source/core/dom/StyleChangeReason.h
index 62414193..84e8003 100644
--- a/third_party/WebKit/Source/core/dom/StyleChangeReason.h
+++ b/third_party/WebKit/Source/core/dom/StyleChangeReason.h
@@ -88,7 +88,7 @@
     }
 
     String reasonString() const { return String(m_reason); }
-    const AtomicString& extraData() const { return m_extraData; }
+    const AtomicString& getExtraData() const { return m_extraData; }
 
 private:
     StyleChangeReasonForTracing(StyleChangeReasonString reasonString, const AtomicString& extraData)
diff --git a/third_party/WebKit/Source/core/editing/EditingStyle.cpp b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
index fa9326c..35f4e07 100644
--- a/third_party/WebKit/Source/core/editing/EditingStyle.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
@@ -510,7 +510,7 @@
 void EditingStyle::replaceFontSizeByKeywordIfPossible(const ComputedStyle* computedStyle, CSSComputedStyleDeclaration* cssComputedStyle)
 {
     ASSERT(computedStyle);
-    if (computedStyle->fontDescription().keywordSize())
+    if (computedStyle->getFontDescription().keywordSize())
         m_mutableStyle->setProperty(CSSPropertyFontSize, cssComputedStyle->getFontSizeCSSValuePreferringKeyword()->cssText());
 }
 
diff --git a/third_party/WebKit/Source/core/editing/Editor.cpp b/third_party/WebKit/Source/core/editing/Editor.cpp
index 4c303e6..3f295278 100644
--- a/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -442,7 +442,7 @@
         ImageResource* cachedImage = layoutImage->cachedImage();
         if (!cachedImage || cachedImage->errorOccurred())
             return nullptr;
-        return cachedImage->image();
+        return cachedImage->getImage();
     }
 
     return nullptr;
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
index 382f304..aead3781 100644
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -662,7 +662,7 @@
 bool CompositeEditCommand::canRebalance(const Position& position) const
 {
     Node* node = position.computeContainerNode();
-    if (!position.isOffsetInAnchor() || !node || !node->isTextNode())
+    if (!position.isOffsetInAnchor() || !node || !node->isTextNode() || !node->layoutObjectIsRichlyEditable())
         return false;
 
     Text* textNode = toText(node);
@@ -733,6 +733,8 @@
 
 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(Position& position)
 {
+    if (!isRichlyEditablePosition(position))
+        return;
     Node* node = position.anchorNode();
     if (!node || !node->isTextNode())
         return;
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
index d9fce93..23f606a 100644
--- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -176,6 +176,30 @@
         return;
     }
 
+    if (!editableRoot->layoutObjectIsRichlyEditable()) {
+        bool isPlainText = true;
+        for (Node& node : NodeTraversal::childrenOf(*m_fragment)) {
+            if (isInterchangeHTMLBRElement(&node) && &node == m_fragment->lastChild())
+                continue;
+            if (!node.isTextNode()) {
+                isPlainText = false;
+                break;
+            }
+        }
+        // We don't need TestRendering for plain-text editing + plain-text insertion.
+        if (isPlainText) {
+            removeInterchangeNodes(m_fragment.get());
+            String originalText = m_fragment->textContent();
+            RefPtrWillBeRawPtr<BeforeTextInsertedEvent> event = BeforeTextInsertedEvent::create(originalText);
+            editableRoot->dispatchEvent(event);
+            if (originalText != event->text()) {
+                m_fragment = createFragmentFromText(selection.toNormalizedEphemeralRange(), event->text());
+                removeInterchangeNodes(m_fragment.get());
+            }
+            return;
+        }
+    }
+
     RefPtrWillBeRawPtr<HTMLElement> holder = insertFragmentForTestRendering(editableRoot.get());
     if (!holder) {
         removeInterchangeNodes(m_fragment.get());
@@ -1195,7 +1219,8 @@
         node = next;
     }
 
-    removeUnrenderedTextNodesAtEnds(insertedNodes);
+    if (isRichlyEditablePosition(insertionPos))
+        removeUnrenderedTextNodesAtEnds(insertedNodes);
 
     if (!handledStyleSpans) {
         handleStyleSpans(insertedNodes, editingState);
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
index 3fbca07..cd88eb76 100644
--- a/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
+++ b/third_party/WebKit/Source/core/editing/iterators/TextIterator.cpp
@@ -835,7 +835,7 @@
         const ComputedStyle* style = r->style();
         if (style) {
             int bottomMargin = toLayoutBox(r)->collapsedMarginAfter();
-            int fontSize = style->fontDescription().computedPixelSize();
+            int fontSize = style->getFontDescription().computedPixelSize();
             if (bottomMargin * 2 >= fontSize)
                 return true;
         }
diff --git a/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp b/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
index eaef68a..015d0f3 100644
--- a/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
@@ -28,6 +28,7 @@
 
 #include "core/css/StyleSheetContents.h"
 #include "core/fetch/FetchRequest.h"
+#include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceClientWalker.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/StyleSheetResourceClient.h"
@@ -60,8 +61,6 @@
 
 CSSStyleSheetResource::~CSSStyleSheetResource()
 {
-    // Make sure dispose() was cllaed before destruction.
-    ASSERT(!m_parsedStyleSheetCache);
 }
 
 void CSSStyleSheetResource::removedFromMemoryCache()
@@ -180,9 +179,13 @@
     if (m_parsedStyleSheetCache)
         m_parsedStyleSheetCache->removedFromMemoryCache();
     m_parsedStyleSheetCache = sheet;
-    m_parsedStyleSheetCache->addedToMemoryCache();
 
     setDecodedSize(m_parsedStyleSheetCache->estimatedSizeInBytes());
+
+    // Check if this stylesheet resource didn't conflict with
+    // another resource and has indeed been added to the cache.
+    if (memoryCache()->contains(this))
+        m_parsedStyleSheetCache->addedToMemoryCache();
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
index 4235737..caaac704 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
@@ -99,8 +99,10 @@
 
 DEFINE_TRACE(ImageResource)
 {
+    visitor->trace(m_multipartParser);
     Resource::trace(visitor);
     ImageObserver::trace(visitor);
+    MultipartImageResourceParser::Client::trace(visitor);
 }
 
 void ImageResource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& options)
@@ -159,9 +161,21 @@
 {
     if (m_image && !errorOccurred())
         m_image->resetAnimation();
+    if (m_multipartParser)
+        m_multipartParser->cancel();
     Resource::allClientsRemoved();
 }
 
+void ImageResource::appendData(const char* data, size_t length)
+{
+    if (m_multipartParser) {
+        m_multipartParser->appendData(data, length);
+    } else {
+        Resource::appendData(data, length);
+        updateImage(false);
+    }
+}
+
 std::pair<blink::Image*, float> ImageResource::brokenImage(float deviceScaleFactor)
 {
     if (deviceScaleFactor >= 2) {
@@ -178,7 +192,7 @@
     return errorOccurred();
 }
 
-blink::Image* ImageResource::image()
+blink::Image* ImageResource::getImage()
 {
     ASSERT(!isPurgeable());
 
@@ -287,13 +301,6 @@
     m_image.clear();
 }
 
-void ImageResource::appendData(const char* data, size_t length)
-{
-    Resource::appendData(data, length);
-    if (!loadingMultipartContent())
-        updateImage(false);
-}
-
 void ImageResource::updateImage(bool allDataReceived)
 {
     TRACE_EVENT0("blink", "ImageResource::updateImage");
@@ -327,18 +334,25 @@
     }
 }
 
-void ImageResource::finishOnePart()
+void ImageResource::finish()
 {
-    if (loadingMultipartContent())
-        clear();
-    updateImage(true);
-    if (loadingMultipartContent())
-        m_data.clear();
-    Resource::finishOnePart();
+    if (m_multipartParser) {
+        m_multipartParser->finish();
+        if (m_data) {
+            clearImage();
+            updateImage(true);
+            m_data.clear();
+        }
+    } else {
+        updateImage(true);
+    }
+    Resource::finish();
 }
 
 void ImageResource::error(Resource::Status status)
 {
+    if (m_multipartParser)
+        m_multipartParser->cancel();
     clear();
     Resource::error(status);
     notifyObservers();
@@ -346,8 +360,11 @@
 
 void ImageResource::responseReceived(const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle)
 {
-    if (loadingMultipartContent() && m_data)
-        finishOnePart();
+    ASSERT(!handle);
+    ASSERT(!m_multipartParser);
+    // If there's no boundary, just handle the request normally.
+    if (response.isMultipart() && !response.multipartBoundary().isEmpty())
+        m_multipartParser = new MultipartImageResourceParser(response, response.multipartBoundary(), this);
     Resource::responseReceived(response, handle);
     if (RuntimeEnabledFeatures::clientHintsEnabled()) {
         m_devicePixelRatioHeaderValue = m_response.httpHeaderField(HTTPNames::Content_DPR).toFloat(&m_hasDevicePixelRatioHeaderValue);
@@ -448,20 +465,36 @@
     notifyObservers(&rect);
 }
 
+void ImageResource::onePartInMultipartReceived(const ResourceResponse& response, bool isFirstPart)
+{
+    ASSERT(m_multipartParser);
+    m_response = response;
+    if (m_data) {
+        clear();
+        updateImage(true);
+        m_data.clear();
+        setLoading(false);
+        checkNotify();
+    }
+    if (!isFirstPart && m_loader)
+        m_loader->didFinishLoadingOnePart(0, WebURLLoaderClient::kUnknownEncodedDataLength);
+}
+
+void ImageResource::multipartDataReceived(const char* bytes, size_t size)
+{
+    ASSERT(m_multipartParser);
+    Resource::appendData(bytes, size);
+}
+
 bool ImageResource::isAccessAllowed(SecurityOrigin* securityOrigin)
 {
     if (response().wasFetchedViaServiceWorker())
         return response().serviceWorkerResponseType() != WebServiceWorkerResponseTypeOpaque;
-    if (!image()->currentFrameHasSingleSecurityOrigin())
+    if (!getImage()->currentFrameHasSingleSecurityOrigin())
         return false;
     if (passesAccessControlCheck(securityOrigin))
         return true;
     return !securityOrigin->taintsCanvas(response().url());
 }
 
-bool ImageResource::loadingMultipartContent() const
-{
-    return m_loader && m_loader->loadingMultipartContent();
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.h b/third_party/WebKit/Source/core/fetch/ImageResource.h
index d05ec2b..8baf98c 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.h
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.h
@@ -24,6 +24,7 @@
 #define ImageResource_h
 
 #include "core/CoreExport.h"
+#include "core/fetch/MultipartImageResourceParser.h"
 #include "core/fetch/Resource.h"
 #include "platform/geometry/IntRect.h"
 #include "platform/geometry/IntSizeHash.h"
@@ -42,7 +43,7 @@
 class MemoryCache;
 class SecurityOrigin;
 
-class CORE_EXPORT ImageResource final : public Resource, public ImageObserver {
+class CORE_EXPORT ImageResource final : public Resource, public ImageObserver, public MultipartImageResourceParser::Client {
     friend class MemoryCache;
     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ImageResource);
 public:
@@ -65,7 +66,7 @@
 
     void load(ResourceFetcher*, const ResourceLoaderOptions&) override;
 
-    blink::Image* image(); // Returns the nullImage() if the image is not available yet.
+    blink::Image* getImage(); // Returns the nullImage() if the image is not available yet.
     bool hasImage() const { return m_image.get(); }
 
     static std::pair<blink::Image*, float> brokenImage(float deviceScaleFactor); // Returns an image and the image's resolution scale factor.
@@ -100,7 +101,7 @@
     void appendData(const char*, size_t) override;
     void error(Resource::Status) override;
     void responseReceived(const ResourceResponse&, PassOwnPtr<WebDataConsumerHandle>) override;
-    void finishOnePart() override;
+    void finish() override;
 
     // For compatibility, images keep loading even if there are HTTP errors.
     bool shouldIgnoreHTTPStatusCodeErrors() const override { return true; }
@@ -116,6 +117,10 @@
     void animationAdvanced(const blink::Image*) override;
     void changedInRect(const blink::Image*, const IntRect&) override;
 
+    // MultipartImageResourceParser::Client
+    void onePartInMultipartReceived(const ResourceResponse&, bool isFirstPart) final;
+    void multipartDataReceived(const char*, size_t) final;
+
     DECLARE_VIRTUAL_TRACE();
 
 protected:
@@ -147,10 +152,10 @@
     void clearImage();
     // If not null, changeRect is the changed part of the image.
     void notifyObservers(const IntRect* changeRect = nullptr);
-    bool loadingMultipartContent() const;
 
     float m_devicePixelRatioHeaderValue;
 
+    PersistentWillBeMember<MultipartImageResourceParser> m_multipartParser;
     RefPtr<blink::Image> m_image;
     bool m_hasDevicePixelRatioHeaderValue;
 };
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
index 9a07d62..236650a 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
@@ -100,26 +100,30 @@
     // Note that the response must be routed through ResourceLoader to
     // ensure the load is flagged as multipart.
     ResourceResponse multipartResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String());
+    multipartResponse.setMultipartBoundary("boundary", strlen("boundary"));
     cachedImage->loader()->didReceiveResponse(nullptr, WrappedResourceResponse(multipartResponse), nullptr);
     ASSERT_FALSE(cachedImage->resourceBuffer());
     ASSERT_FALSE(cachedImage->hasImage());
     ASSERT_EQ(client.imageChangedCount(), 0);
     ASSERT_FALSE(client.notifyFinishedCalled());
+    EXPECT_EQ("multipart/x-mixed-replace", cachedImage->response().mimeType());
 
+    const char firstPart[] =
+        "--boundary\n"
+        "Content-Type: image/svg+xml\n\n";
+    cachedImage->appendData(firstPart, strlen(firstPart));
     // Send the response for the first real part. No image or data buffer is created.
-    const char* svgData = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect width='1' height='1' fill='green'/></svg>";
-    unsigned svgDataLength = strlen(svgData);
-    ResourceResponse payloadResponse(KURL(), "image/svg+xml", svgDataLength, nullAtom, String());
-    cachedImage->loader()->didReceiveResponse(nullptr, WrappedResourceResponse(payloadResponse), nullptr);
     ASSERT_FALSE(cachedImage->resourceBuffer());
     ASSERT_FALSE(cachedImage->hasImage());
     ASSERT_EQ(client.imageChangedCount(), 0);
     ASSERT_FALSE(client.notifyFinishedCalled());
+    EXPECT_EQ("image/svg+xml", cachedImage->response().mimeType());
 
+    const char secondPart[] = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect width='1' height='1' fill='green'/></svg>\n";
     // The first bytes arrive. The data buffer is created, but no image is created.
-    cachedImage->appendData(svgData, svgDataLength);
+    cachedImage->appendData(secondPart, strlen(secondPart));
     ASSERT_TRUE(cachedImage->resourceBuffer());
-    ASSERT_EQ(cachedImage->resourceBuffer()->size(), svgDataLength);
+    ASSERT_EQ(cachedImage->resourceBuffer()->size(), strlen(secondPart));
     ASSERT_FALSE(cachedImage->hasImage());
     ASSERT_EQ(client.imageChangedCount(), 0);
     ASSERT_FALSE(client.notifyFinishedCalled());
@@ -129,9 +133,9 @@
     ASSERT_FALSE(cachedImage->resourceBuffer());
     ASSERT_FALSE(cachedImage->errorOccurred());
     ASSERT_TRUE(cachedImage->hasImage());
-    ASSERT_FALSE(cachedImage->image()->isNull());
-    ASSERT_EQ(cachedImage->image()->width(), 1);
-    ASSERT_EQ(cachedImage->image()->height(), 1);
+    ASSERT_FALSE(cachedImage->getImage()->isNull());
+    ASSERT_EQ(cachedImage->getImage()->width(), 1);
+    ASSERT_EQ(cachedImage->getImage()->height(), 1);
     ASSERT_EQ(client.imageChangedCount(), 1);
     ASSERT_TRUE(client.notifyFinishedCalled());
 }
@@ -182,21 +186,21 @@
     cachedImage->finish();
     ASSERT_FALSE(cachedImage->errorOccurred());
     ASSERT_TRUE(cachedImage->hasImage());
-    ASSERT_FALSE(cachedImage->image()->isNull());
+    ASSERT_FALSE(cachedImage->getImage()->isNull());
     ASSERT_TRUE(client.notifyFinishedCalled());
 
     // The prune comes when the ImageResource still has clients. The image should not be deleted.
     cachedImage->prune();
     ASSERT_TRUE(cachedImage->hasClients());
     ASSERT_TRUE(cachedImage->hasImage());
-    ASSERT_FALSE(cachedImage->image()->isNull());
+    ASSERT_FALSE(cachedImage->getImage()->isNull());
 
     // The ImageResource no longer has clients. The image should be deleted by prune.
     client.removeAsClient();
     cachedImage->prune();
     ASSERT_FALSE(cachedImage->hasClients());
     ASSERT_FALSE(cachedImage->hasImage());
-    ASSERT_TRUE(cachedImage->image()->isNull());
+    ASSERT_TRUE(cachedImage->getImage()->isNull());
 }
 
 TEST(ImageResourceTest, UpdateBitmapImages)
@@ -213,10 +217,10 @@
     cachedImage->finish();
     ASSERT_FALSE(cachedImage->errorOccurred());
     ASSERT_TRUE(cachedImage->hasImage());
-    ASSERT_FALSE(cachedImage->image()->isNull());
+    ASSERT_FALSE(cachedImage->getImage()->isNull());
     ASSERT_EQ(client.imageChangedCount(), 2);
     ASSERT_TRUE(client.notifyFinishedCalled());
-    ASSERT_TRUE(cachedImage->image()->isBitmapImage());
+    ASSERT_TRUE(cachedImage->getImage()->isBitmapImage());
 }
 
 TEST(ImageResourceTest, ReloadIfLoFi)
@@ -239,10 +243,10 @@
     cachedImage->finish();
     ASSERT_FALSE(cachedImage->errorOccurred());
     ASSERT_TRUE(cachedImage->hasImage());
-    ASSERT_FALSE(cachedImage->image()->isNull());
+    ASSERT_FALSE(cachedImage->getImage()->isNull());
     ASSERT_EQ(client.imageChangedCount(), 2);
     ASSERT_TRUE(client.notifyFinishedCalled());
-    ASSERT_TRUE(cachedImage->image()->isBitmapImage());
+    ASSERT_TRUE(cachedImage->getImage()->isBitmapImage());
 
     cachedImage->reloadIfLoFi(fetcher);
     ASSERT_FALSE(cachedImage->errorOccurred());
@@ -255,9 +259,9 @@
     cachedImage->finish();
     ASSERT_FALSE(cachedImage->errorOccurred());
     ASSERT_TRUE(cachedImage->hasImage());
-    ASSERT_FALSE(cachedImage->image()->isNull());
+    ASSERT_FALSE(cachedImage->getImage()->isNull());
     ASSERT_TRUE(client.notifyFinishedCalled());
-    ASSERT_TRUE(cachedImage->image()->isBitmapImage());
+    ASSERT_TRUE(cachedImage->getImage()->isBitmapImage());
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp
index 266edfd9..4b748fc 100644
--- a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp
+++ b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.cpp
@@ -25,6 +25,7 @@
 
 void MultipartImageResourceParser::appendData(const char* bytes, size_t size)
 {
+    ASSERT(!isCancelled());
     // m_sawLastBoundary means that we've already received the final boundary
     // token. The server should stop sending us data at this point, but if it
     // does, we just throw it away.
@@ -103,6 +104,8 @@
             m_isParsingHeaders = true;
             break;
         }
+        if (isCancelled())
+            return;
     }
 
     // At this point, we should send over any data we have, but keep enough data
@@ -121,9 +124,11 @@
 void MultipartImageResourceParser::finish()
 {
     ASSERT(!isCancelled());
+    if (m_sawLastBoundary)
+        return;
     // If we have any pending data and we're not in a header, go ahead and send
     // it to the client.
-    if (!m_isParsingHeaders && !m_data.isEmpty() && !m_sawLastBoundary)
+    if (!m_isParsingHeaders && !m_data.isEmpty())
         m_client->multipartDataReceived(m_data.data(), m_data.size());
     m_data.clear();
     m_sawLastBoundary = true;
@@ -158,14 +163,10 @@
         return false;
     m_data.remove(0, end);
 
-    // To avoid recording every multipart load as a separate visit in
-    // the history database, we want to keep track of whether the response
-    // is part of a multipart payload.  We do want to record the first visit,
-    // so we only set isMultipartPayload to true after the first visit.
-    response.setIsMultipartPayload(!m_isFirstPart);
+    bool isFirstPart = m_isFirstPart;
     m_isFirstPart = false;
     // Send the response!
-    m_client->onePartInMultipartReceived(response.toResourceResponse());
+    m_client->onePartInMultipartReceived(response.toResourceResponse(), isFirstPart);
 
     return true;
 }
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h
index c812bb9..92db211 100644
--- a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h
+++ b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParser.h
@@ -55,7 +55,7 @@
     class CORE_EXPORT Client : public WillBeGarbageCollectedMixin {
     public:
         virtual ~Client() = default;
-        virtual void onePartInMultipartReceived(const ResourceResponse&) = 0;
+        virtual void onePartInMultipartReceived(const ResourceResponse&, bool isFirstPart) = 0;
         virtual void multipartDataReceived(const char* bytes, size_t) = 0;
         DEFINE_INLINE_VIRTUAL_TRACE() {}
     };
diff --git a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp
index 6fb132f..184e9de4 100644
--- a/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/MultipartImageResourceParserTest.cpp
@@ -29,8 +29,11 @@
     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockClient);
 
 public:
-    void onePartInMultipartReceived(const ResourceResponse& response) override
+    void onePartInMultipartReceived(const ResourceResponse& response, bool isFirstPart) override
     {
+        if (isFirstPart != m_responses.isEmpty())
+            FAIL() << "m_responses.size() = " << m_responses.size() << ", isFirstPart = " << isFirstPart;
+
         m_responses.append(response);
         m_data.append(Vector<char>());
     }
@@ -442,7 +445,7 @@
     EXPECT_EQ("foofoo", toString(client->m_data[1]));
 }
 
-TEST(MultipartResponseTest, MultipartPayloadSet)
+TEST(MultipartResponseTest, IsFirstPartSet)
 {
     ResourceResponse response;
     response.setMimeType("multipart/x-mixed-replace");
@@ -452,6 +455,7 @@
 
     MultipartImageResourceParser* parser = new MultipartImageResourceParser(response, boundary, client);
 
+    // isFirstPart is checked at MockClient::didReceiveResponse.
     const char data[] =
         "--bound\n"
         "Content-type: text/plain\n\n"
@@ -461,7 +465,6 @@
     ASSERT_EQ(1u, client->m_responses.size());
     ASSERT_EQ(1u, client->m_data.size());
     EXPECT_EQ("response data", toString(client->m_data[0]));
-    EXPECT_FALSE(client->m_responses[0].isMultipartPayload());
 
     const char data2[] =
         "Content-type: text/plain\n\n"
@@ -471,7 +474,6 @@
     ASSERT_EQ(2u, client->m_responses.size());
     ASSERT_EQ(2u, client->m_data.size());
     EXPECT_EQ("response data2", toString(client->m_data[1]));
-    EXPECT_TRUE(client->m_responses[1].isMultipartPayload());
 }
 
 } // namespace
diff --git a/third_party/WebKit/Source/core/fetch/RawResource.cpp b/third_party/WebKit/Source/core/fetch/RawResource.cpp
index af353d5..278fda7 100644
--- a/third_party/WebKit/Source/core/fetch/RawResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/RawResource.cpp
@@ -138,14 +138,6 @@
     Resource::willFollowRedirect(newRequest, redirectResponse);
 }
 
-void RawResource::updateRequest(const ResourceRequest& request)
-{
-    RefPtrWillBeRawPtr<RawResource> protect(this);
-    ResourceClientWalker<RawResourceClient> w(m_clients);
-    while (RawResourceClient* c = w.next())
-        c->updateRequest(this, request);
-}
-
 void RawResource::responseReceived(const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle)
 {
     RefPtrWillBeRawPtr<RawResource> protect(this);
diff --git a/third_party/WebKit/Source/core/fetch/RawResource.h b/third_party/WebKit/Source/core/fetch/RawResource.h
index febd218..0054cff 100644
--- a/third_party/WebKit/Source/core/fetch/RawResource.h
+++ b/third_party/WebKit/Source/core/fetch/RawResource.h
@@ -80,7 +80,6 @@
     bool shouldIgnoreHTTPStatusCodeErrors() const override { return !isLinkPreload(); }
 
     void willFollowRedirect(ResourceRequest&, const ResourceResponse&) override;
-    void updateRequest(const ResourceRequest&) override;
     void responseReceived(const ResourceResponse&, PassOwnPtr<WebDataConsumerHandle>) override;
     void setSerializedCachedMetadata(const char*, size_t) override;
     void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
@@ -112,7 +111,6 @@
     virtual void setSerializedCachedMetadata(Resource*, const char*, size_t) { }
     virtual void dataReceived(Resource*, const char* /* data */, size_t /* length */) { }
     virtual void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&) { }
-    virtual void updateRequest(Resource*, const ResourceRequest&) { }
     virtual void dataDownloaded(Resource*, int) { }
     virtual void didReceiveResourceTiming(Resource*, const ResourceTimingInfo&) { }
 };
diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp
index d0a359a..dbb8562f 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.cpp
+++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -201,30 +201,32 @@
 
 void Resource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& options)
 {
+    RELEASE_ASSERT(!m_loader);
     m_options = options;
     m_loading = true;
+    m_status = Pending;
 
-    ResourceRequest request(m_revalidatingRequest.isNull() ? m_resourceRequest : m_revalidatingRequest);
+    ResourceRequest& request(m_revalidatingRequest.isNull() ? m_resourceRequest : m_revalidatingRequest);
     if (!accept().isEmpty())
         request.setHTTPAccept(accept());
+    request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials);
 
     // FIXME: It's unfortunate that the cache layer and below get to know anything about fragment identifiers.
     // We should look into removing the expectation of that knowledge from the platform network stacks.
+    KURL urlWithoutFragment = request.url();
     if (!m_fragmentIdentifierForRequest.isNull()) {
         KURL url = request.url();
         url.setFragmentIdentifier(m_fragmentIdentifierForRequest);
         request.setURL(url);
         m_fragmentIdentifierForRequest = String();
     }
-    m_status = Pending;
-    if (m_loader) {
-        ASSERT(m_revalidatingRequest.isNull());
-        RELEASE_ASSERT(m_options.synchronousPolicy == RequestSynchronously);
-        m_loader->changeToSynchronous();
-        return;
-    }
-    m_loader = ResourceLoader::create(fetcher, this, request, options);
-    m_loader->start();
+
+    m_loader = ResourceLoader::create(fetcher, this);
+    m_loader->start(request);
+    // If the request reference is null (i.e., a synchronous revalidation will
+    // null the request), don't make the request non-null by setting the url.
+    if (!request.isNull())
+        request.setURL(urlWithoutFragment);
 }
 
 void Resource::checkNotify()
@@ -295,17 +297,11 @@
     markClientsFinished();
 }
 
-void Resource::finishOnePart()
-{
-    setLoading(false);
-    checkNotify();
-}
-
 void Resource::finish()
 {
     ASSERT(m_revalidatingRequest.isNull());
-    ASSERT(!errorOccurred());
-    finishOnePart();
+    setLoading(false);
+    checkNotify();
     markClientsFinished();
     if (!errorOccurred())
         m_status = Cached;
@@ -424,6 +420,7 @@
 
 void Resource::willFollowRedirect(ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
 {
+    newRequest.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials);
     m_redirectChain.append(RedirectPair(newRequest, redirectResponse));
     m_requestedFromNetworkingLayer = true;
 }
@@ -454,7 +451,6 @@
         }
         revalidationFailed();
     }
-
     setResponse(response);
     String encoding = response.textEncodingName();
     if (!encoding.isNull())
@@ -835,6 +831,7 @@
 {
     m_resourceRequest = m_revalidatingRequest;
     m_revalidatingRequest = ResourceRequest();
+    m_redirectChain.clear();
     m_data.clear();
     m_cachedMetadata.clear();
     destroyDecodedDataForFailedRevalidation();
diff --git a/third_party/WebKit/Source/core/fetch/Resource.h b/third_party/WebKit/Source/core/fetch/Resource.h
index 9c6734f..de7f4d7 100644
--- a/third_party/WebKit/Source/core/fetch/Resource.h
+++ b/third_party/WebKit/Source/core/fetch/Resource.h
@@ -123,6 +123,7 @@
     const KURL& url() const { return m_resourceRequest.url();}
     Type getType() const { return static_cast<Type>(m_type); }
     const ResourceLoaderOptions& options() const { return m_options; }
+    ResourceLoaderOptions& mutableOptions() { return m_options; }
     void setOptions(const ResourceLoaderOptions& options) { m_options = options; }
 
     void didChangePriority(ResourceLoadPriority, int intraPriorityValue);
@@ -169,7 +170,7 @@
     // Computes the status of an object after loading.
     // Updates the expire date on the cache entry file
     void setLoadFinishTime(double finishTime) { m_loadFinishTime = finishTime; }
-    void finish();
+    virtual void finish();
 
     // FIXME: Remove the stringless variant once all the callsites' error messages are updated.
     bool passesAccessControlCheck(SecurityOrigin*) const;
@@ -184,7 +185,6 @@
 
     virtual void willFollowRedirect(ResourceRequest&, const ResourceResponse&);
 
-    virtual void updateRequest(const ResourceRequest&) { }
     virtual void responseReceived(const ResourceResponse&, PassOwnPtr<WebDataConsumerHandle>);
     void setResponse(const ResourceResponse& response) { m_response = response; }
     const ResourceResponse& response() const { return m_response; }
@@ -258,7 +258,6 @@
     Resource(const ResourceRequest&, Type);
 
     virtual void checkNotify();
-    virtual void finishOnePart();
 
     virtual void destroyDecodedDataForFailedRevalidation() { }
 
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
index c0864494..f7cd97d 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -262,11 +262,7 @@
 {
     if (FetchRequest::DeferredByClient == request.defer())
         return false;
-    if (policy != Use)
-        return true;
-    if (resource->stillNeedsLoad())
-        return true;
-    return request.options().synchronousPolicy == RequestSynchronously && resource->isLoading();
+    return policy != Use || resource->stillNeedsLoad();
 }
 
 // Limit the number of URLs in m_validatedURLs to avoid memory bloat.
@@ -689,6 +685,10 @@
     if (request.isConditional())
         return Reload;
 
+    // Don't try to reuse an in-progress async request for a new sync request.
+    if (fetchRequest.options().synchronousPolicy == RequestSynchronously && existingResource->isLoading())
+        return Reload;
+
     // Don't reload resources while pasting.
     if (m_allowStaleResources)
         return Use;
@@ -838,13 +838,6 @@
     }
 }
 
-void ResourceFetcher::redirectReceived(Resource* resource, const ResourceResponse& redirectResponse)
-{
-    ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
-    if (it != m_resourceTimingInfoMap.end())
-        it->value->addRedirect(redirectResponse);
-}
-
 void ResourceFetcher::didLoadResource(Resource* resource)
 {
     context().didLoadResource(resource);
@@ -958,11 +951,6 @@
     context().dispatchDidFail(resource->identifier(), error, isInternalRequest);
 }
 
-void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& initiatorInfo)
-{
-    context().dispatchWillSendRequest(identifier, request, redirectResponse, initiatorInfo);
-}
-
 void ResourceFetcher::didReceiveResponse(const Resource* resource, const ResourceResponse& response)
 {
     // If the response is fetched via ServiceWorker, the original URL of the response could be different from the URL of the request.
@@ -1004,7 +992,7 @@
     didLoadResource(loader->cachedResource());
 }
 
-void ResourceFetcher::didInitializeResourceLoader(ResourceLoader* loader)
+void ResourceFetcher::willStartLoadingResource(Resource* resource, ResourceLoader* loader, ResourceRequest& request)
 {
     if (loader->cachedResource()->shouldBlockLoadEvent()) {
         if (!m_loaders)
@@ -1015,6 +1003,12 @@
             m_nonBlockingLoaders = ResourceLoaderSet::create();
         m_nonBlockingLoaders->add(loader);
     }
+
+    context().willStartLoadingResource(request);
+    storeResourceTimingInitiatorInformation(resource);
+    TRACE_EVENT_ASYNC_BEGIN2("blink.net", "Resource", resource, "url", resource->url().getString().ascii(), "priority", resource->resourceRequest().priority());
+
+    context().dispatchWillSendRequest(resource->identifier(), request, ResourceResponse(), resource->options().initiatorInfo);
 }
 
 void ResourceFetcher::willTerminateResourceLoader(ResourceLoader* loader)
@@ -1027,13 +1021,6 @@
         ASSERT_NOT_REACHED();
 }
 
-void ResourceFetcher::willStartLoadingResource(Resource* resource, ResourceRequest& request)
-{
-    context().willStartLoadingResource(request);
-    storeResourceTimingInitiatorInformation(resource);
-    TRACE_EVENT_ASYNC_BEGIN2("blink.net", "Resource", resource, "url", resource->url().getString().ascii(), "priority", resource->resourceRequest().priority());
-}
-
 void ResourceFetcher::stopFetching()
 {
     if (m_nonBlockingLoaders)
@@ -1060,25 +1047,37 @@
     return context().defersLoading();
 }
 
-bool ResourceFetcher::canAccessRedirect(Resource* resource, ResourceRequest& newRequest, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options)
+static bool isManualRedirectFetchRequest(const ResourceRequest& request)
 {
-    if (!context().canRequest(resource->getType(), newRequest, newRequest.url(), options, resource->isUnusedPreload(), FetchRequest::UseDefaultOriginRestrictionForType))
-        return false;
-    if (options.corsEnabled == IsCORSEnabled) {
-        SecurityOrigin* sourceOrigin = options.securityOrigin.get();
-        if (!sourceOrigin)
-            sourceOrigin = context().getSecurityOrigin();
+    return request.fetchRedirectMode() == WebURLRequest::FetchRedirectModeManual && request.requestContext() == WebURLRequest::RequestContextFetch;
+}
 
-        String errorMessage;
-        StoredCredentials withCredentials = resource->lastResourceRequest().allowStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
-        if (!CrossOriginAccessControl::handleRedirect(sourceOrigin, newRequest, redirectResponse, withCredentials, options, errorMessage)) {
-            resource->setCORSFailed();
-            context().addConsoleMessage(errorMessage);
+bool ResourceFetcher::willFollowRedirect(Resource* resource, ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
+{
+    if (!isManualRedirectFetchRequest(resource->resourceRequest())) {
+        if (!context().canRequest(resource->getType(), newRequest, newRequest.url(), resource->options(), resource->isUnusedPreload(), FetchRequest::UseDefaultOriginRestrictionForType))
             return false;
+        if (resource->options().corsEnabled == IsCORSEnabled) {
+            SecurityOrigin* sourceOrigin = resource->options().securityOrigin.get();
+            if (!sourceOrigin)
+                sourceOrigin = context().getSecurityOrigin();
+
+            String errorMessage;
+            StoredCredentials withCredentials = resource->lastResourceRequest().allowStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+            if (!CrossOriginAccessControl::handleRedirect(sourceOrigin, newRequest, redirectResponse, withCredentials, resource->mutableOptions(), errorMessage)) {
+                resource->setCORSFailed();
+                context().addConsoleMessage(errorMessage);
+                return false;
+            }
         }
+        if (resource->getType() == Resource::Image && shouldDeferImageLoad(newRequest.url()))
+            return false;
     }
-    if (resource->getType() == Resource::Image && shouldDeferImageLoad(newRequest.url()))
-        return false;
+
+    ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
+    if (it != m_resourceTimingInfoMap.end())
+        it->value->addRedirect(redirectResponse);
+    context().dispatchWillSendRequest(resource->identifier(), newRequest, redirectResponse, resource->options().initiatorInfo);
     return true;
 }
 
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
index c74f71b..e17afb3 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -107,23 +107,20 @@
     bool isFetching() const;
 
     void didLoadResource(Resource*);
-    void redirectReceived(Resource*, const ResourceResponse&);
+    bool willFollowRedirect(Resource*, ResourceRequest&, const ResourceResponse&);
     void didFinishLoading(Resource*, double finishTime, int64_t encodedDataLength);
     void didFailLoading(const Resource*, const ResourceError&);
-    void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&);
     void didReceiveResponse(const Resource*, const ResourceResponse&);
     void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength);
     void didDownloadData(const Resource*, int dataLength, int encodedDataLength);
     void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*);
-    void didInitializeResourceLoader(ResourceLoader*);
-    void willStartLoadingResource(Resource*, ResourceRequest&);
+    void willStartLoadingResource(Resource*, ResourceLoader*, ResourceRequest&);
     bool defersLoading() const;
 
     enum AccessControlLoggingDecision {
         ShouldLogAccessControlErrors,
         ShouldNotLogAccessControlErrors
     };
-    bool canAccessRedirect(Resource*, ResourceRequest&, const ResourceResponse&, ResourceLoaderOptions&);
     bool canAccessResource(Resource*, SecurityOrigin*, const KURL&, AccessControlLoggingDecision) const;
     bool isControlledByServiceWorker() const;
 
diff --git a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
index b44b22a8..2f81635 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
@@ -47,27 +47,14 @@
 
 namespace blink {
 
-namespace {
-
-bool isManualRedirectFetchRequest(const ResourceRequest& request)
+ResourceLoader* ResourceLoader::create(ResourceFetcher* fetcher, Resource* resource)
 {
-    return request.fetchRedirectMode() == WebURLRequest::FetchRedirectModeManual && request.requestContext() == WebURLRequest::RequestContextFetch;
+    return new ResourceLoader(fetcher, resource);
 }
 
-} // namespace
-
-ResourceLoader* ResourceLoader::create(ResourceFetcher* fetcher, Resource* resource, const ResourceRequest& request, const ResourceLoaderOptions& options)
-{
-    ResourceLoader* loader = new ResourceLoader(fetcher, resource, options);
-    loader->init(request);
-    return loader;
-}
-
-ResourceLoader::ResourceLoader(ResourceFetcher* fetcher, Resource* resource, const ResourceLoaderOptions& options)
+ResourceLoader::ResourceLoader(ResourceFetcher* fetcher, Resource* resource)
     : m_fetcher(fetcher)
     , m_notifiedLoadComplete(false)
-    , m_loadingMultipartContent(false)
-    , m_options(options)
     , m_resource(resource)
     , m_state(ConnectionStateNew)
 {
@@ -105,21 +92,11 @@
     m_fetcher.clear();
 }
 
-void ResourceLoader::init(const ResourceRequest& passedRequest)
-{
-    ResourceRequest request(passedRequest);
-    m_fetcher->willSendRequest(m_resource->identifier(), request, ResourceResponse(), m_options.initiatorInfo);
-    m_originalRequest = m_request = applyOptions(request);
-    m_resource->updateRequest(request);
-    m_fetcher->didInitializeResourceLoader(this);
-}
-
-void ResourceLoader::start()
+void ResourceLoader::start(ResourceRequest& request)
 {
     ASSERT(!m_loader);
-    ASSERT(!m_request.isNull());
 
-    m_fetcher->willStartLoadingResource(m_resource.get(), m_request);
+    m_fetcher->willStartLoadingResource(m_resource.get(), this, request);
     RELEASE_ASSERT(m_state == ConnectionStateNew);
     m_state = ConnectionStateStarted;
 
@@ -128,23 +105,10 @@
     ASSERT(m_loader);
     m_loader->setLoadingTaskRunner(m_fetcher->loadingTaskRunner());
 
-    if (m_options.synchronousPolicy == RequestSynchronously)
-        requestSynchronously();
+    if (m_resource->options().synchronousPolicy == RequestSynchronously)
+        requestSynchronously(request);
     else
-        m_loader->loadAsynchronously(WrappedResourceRequest(m_request), this);
-}
-
-void ResourceLoader::changeToSynchronous()
-{
-    ASSERT(m_options.synchronousPolicy == RequestAsynchronously);
-    ASSERT(m_loader);
-    m_loader->cancel();
-    m_loader.clear();
-    m_loader = adoptPtr(Platform::current()->createURLLoader());
-    ASSERT(m_loader);
-    m_request.setPriority(ResourceLoadPriorityHighest);
-    m_state = ConnectionStateStarted;
-    requestSynchronously();
+        m_loader->loadAsynchronously(WrappedResourceRequest(request), this);
 }
 
 void ResourceLoader::setDefersLoading(bool defers)
@@ -164,8 +128,13 @@
 
 void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64_t encodedDataLength)
 {
-    // If load has been cancelled after finishing (which could happen with a
-    // JavaScript that changes the window location), do nothing.
+    ASSERT(m_state != ConnectionStateReleased);
+    if (!isFinishing()) {
+        // When loading a multipart resource, make the loader non-block when
+        // finishing loading the first part.
+        m_fetcher->subresourceLoaderFinishedLoadingOnePart(this);
+    }
+
     if (m_state == ConnectionStateReleased)
         return;
 
@@ -204,7 +173,7 @@
         return;
     }
 
-    ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError(m_request.url()) : error;
+    ResourceError nonNullError = error.isNull() ? ResourceError::cancelledError(m_resource->lastResourceRequest().url()) : error;
 
     WTF_LOG(ResourceLoading, "Cancelled load of '%s'.\n", m_resource->url().getString().latin1().data());
     m_state = ConnectionStateCanceled;
@@ -224,31 +193,17 @@
 void ResourceLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse)
 {
     ASSERT(m_state != ConnectionStateReleased);
+    ASSERT(!passedNewRequest.isNull());
+    ASSERT(!passedRedirectResponse.isNull());
 
-    ResourceRequest& newRequest(applyOptions(passedNewRequest.toMutableResourceRequest()));
-
-    ASSERT(!newRequest.isNull());
+    ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest());
     const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse());
-    ASSERT(!redirectResponse.isNull());
     newRequest.setFollowedRedirect(true);
-    if (!isManualRedirectFetchRequest(m_resource->resourceRequest()) && !m_fetcher->canAccessRedirect(m_resource.get(), newRequest, redirectResponse, m_options)) {
+
+    if (m_fetcher->willFollowRedirect(m_resource.get(), newRequest, redirectResponse))
+        m_resource->willFollowRedirect(newRequest, redirectResponse);
+    else
         cancel(ResourceError::cancelledDueToAccessCheckError(newRequest.url()));
-        return;
-    }
-    ASSERT(m_state != ConnectionStateReleased);
-
-    applyOptions(newRequest); // canAccessRedirect() can modify m_options so we should re-apply it.
-    m_fetcher->redirectReceived(m_resource.get(), redirectResponse);
-    ASSERT(m_state != ConnectionStateReleased);
-    m_resource->willFollowRedirect(newRequest, redirectResponse);
-    if (newRequest.isNull() || m_state == ConnectionStateReleased)
-        return;
-
-    m_fetcher->willSendRequest(m_resource->identifier(), newRequest, redirectResponse, m_options.initiatorInfo);
-    ASSERT(m_state != ConnectionStateReleased);
-    ASSERT(!newRequest.isNull());
-    m_resource->updateRequest(newRequest);
-    m_request = newRequest;
 }
 
 void ResourceLoader::didReceiveCachedMetadata(WebURLLoader*, const char* data, int length)
@@ -265,7 +220,7 @@
 bool ResourceLoader::responseNeedsAccessControlCheck() const
 {
     // If the fetch was (potentially) CORS enabled, an access control check of the response is required.
-    return m_options.corsEnabled == IsCORSEnabled;
+    return m_resource->options().corsEnabled == IsCORSEnabled;
 }
 
 void ResourceLoader::didReceiveResponse(WebURLLoader*, const WebURLResponse& response, WebDataConsumerHandle* rawHandle)
@@ -274,10 +229,8 @@
     // |rawHandle|'s ownership is transferred to the callee.
     OwnPtr<WebDataConsumerHandle> handle = adoptPtr(rawHandle);
 
-    bool isMultipartPayload = response.isMultipartPayload();
     bool isValidStateTransition = (m_state == ConnectionStateStarted || m_state == ConnectionStateReceivedResponse);
-    // In the case of multipart loads, calls to didReceiveData & didReceiveResponse can be interleaved.
-    RELEASE_ASSERT(isMultipartPayload || isValidStateTransition);
+    RELEASE_ASSERT(isValidStateTransition);
     m_state = ConnectionStateReceivedResponse;
 
     const ResourceResponse& resourceResponse = response.toResourceResponse();
@@ -290,16 +243,16 @@
                 m_state = ConnectionStateStarted;
                 m_loader = adoptPtr(Platform::current()->createURLLoader());
                 ASSERT(m_loader);
-                ASSERT(!m_request.skipServiceWorker());
-                m_request.setSkipServiceWorker(true);
-                WrappedResourceRequest wrappedRequest(m_request);
-                m_loader->loadAsynchronously(wrappedRequest, this);
+                ResourceRequest request = m_resource->lastResourceRequest();
+                ASSERT(!request.skipServiceWorker());
+                request.setSkipServiceWorker(true);
+                m_loader->loadAsynchronously(WrappedResourceRequest(request), this);
                 return;
             }
         } else {
             if (!m_resource->isCacheValidator() || resourceResponse.httpStatusCode() != 304)
                 m_resource->setResponse(resourceResponse);
-            if (!m_fetcher->canAccessResource(m_resource.get(), m_options.securityOrigin.get(), response.url(), ResourceFetcher::ShouldLogAccessControlErrors)) {
+            if (!m_fetcher->canAccessResource(m_resource.get(), m_resource->options().securityOrigin.get(), response.url(), ResourceFetcher::ShouldLogAccessControlErrors)) {
                 m_fetcher->didReceiveResponse(m_resource.get(), resourceResponse);
                 cancel(ResourceError::cancelledDueToAccessCheckError(KURL(response.url())));
                 return;
@@ -315,34 +268,17 @@
     if (m_state == ConnectionStateReleased)
         return;
 
-    if (response.toResourceResponse().isMultipart()) {
-        // We only support multipart for images, though the image may be loaded
-        // as a main resource that we end up displaying through an ImageDocument.
-        if (!m_resource->isImage() && m_resource->getType() != Resource::MainResource) {
-            cancel();
-            return;
-        }
-        m_loadingMultipartContent = true;
-    } else if (isMultipartPayload) {
-        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.
-        // After the first multipart section is complete, signal to delegates that this load is "finished"
-        m_fetcher->subresourceLoaderFinishedLoadingOnePart(this);
-        didFinishLoadingOnePart(0, WebURLLoaderClient::kUnknownEncodedDataLength);
-    }
-    if (m_state == ConnectionStateReleased)
-        return;
-
     if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnoreHTTPStatusCodeErrors())
         return;
 
     if (!m_notifiedLoadComplete) {
         m_notifiedLoadComplete = true;
-        m_fetcher->didFailLoading(m_resource.get(), ResourceError::cancelledError(m_request.url()));
+        m_fetcher->didFailLoading(m_resource.get(), ResourceError::cancelledError(resourceResponse.url()));
     }
 
     ASSERT(m_state != ConnectionStateReleased);
     m_resource->error(Resource::LoadError);
-    cancel();
+    cancel(ResourceError::cancelledError(resourceResponse.url()));
 }
 
 void ResourceLoader::didReceiveResponse(WebURLLoader* loader, const WebURLResponse& response)
@@ -416,19 +352,22 @@
     releaseResources();
 }
 
-void ResourceLoader::requestSynchronously()
+void ResourceLoader::requestSynchronously(ResourceRequest& request)
 {
     // downloadToFile is not supported for synchronous requests.
-    ASSERT(!m_request.downloadToFile());
+    ASSERT(!request.downloadToFile());
     ASSERT(m_loader);
 
+    // Synchronous requests should always be max priority, lest they hang the renderer.
+    request.setPriority(ResourceLoadPriorityHighest);
+
     if (m_fetcher->defersLoading()) {
         cancel();
         return;
     }
 
     RefPtrWillBeRawPtr<Resource> protectResource(m_resource.get());
-    WrappedResourceRequest requestIn(m_request);
+    WrappedResourceRequest requestIn(request);
     WebURLResponse responseOut;
     responseOut.initialize();
     WebURLError errorOut;
@@ -461,10 +400,4 @@
     didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength);
 }
 
-ResourceRequest& ResourceLoader::applyOptions(ResourceRequest& request) const
-{
-    request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials);
-    return request;
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/ResourceLoader.h b/third_party/WebKit/Source/core/fetch/ResourceLoader.h
index d4630f5b..53fb31c 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceLoader.h
+++ b/third_party/WebKit/Source/core/fetch/ResourceLoader.h
@@ -45,22 +45,20 @@
 
 class CORE_EXPORT ResourceLoader final : public GarbageCollectedFinalized<ResourceLoader>, protected WebURLLoaderClient {
 public:
-    static ResourceLoader* create(ResourceFetcher*, Resource*, const ResourceRequest&, const ResourceLoaderOptions&);
+    static ResourceLoader* create(ResourceFetcher*, Resource*);
     ~ResourceLoader() override;
     DECLARE_TRACE();
 
     // Promptly release m_loader.
     EAGERLY_FINALIZE();
 
-    void start();
-    void changeToSynchronous();
+    void start(ResourceRequest&);
 
     void cancel();
     void cancel(const ResourceError&);
     void cancelIfNotFinishing();
 
     Resource* cachedResource() { return m_resource.get(); }
-    const ResourceRequest& originalRequest() const { return m_originalRequest; }
 
     void setDefersLoading(bool);
 
@@ -77,16 +75,13 @@
     void didFail(WebURLLoader*, const WebURLError&) override;
     void didDownloadData(WebURLLoader*, int, int) override;
 
-    bool loadingMultipartContent() const { return m_loadingMultipartContent; }
+    void didFinishLoadingOnePart(double finishTime, int64_t encodedDataLength);
 
 private:
     // Assumes ResourceFetcher and Resource are non-null.
-    ResourceLoader(ResourceFetcher*, Resource*, const ResourceLoaderOptions&);
+    ResourceLoader(ResourceFetcher*, Resource*);
 
-    void init(const ResourceRequest&);
-    void requestSynchronously();
-
-    void didFinishLoadingOnePart(double finishTime, int64_t encodedDataLength);
+    void requestSynchronously(ResourceRequest&);
 
     bool responseNeedsAccessControlCheck() const;
 
@@ -97,14 +92,8 @@
     OwnPtr<WebURLLoader> m_loader;
     Member<ResourceFetcher> m_fetcher;
 
-    ResourceRequest m_request;
-    ResourceRequest m_originalRequest; // Before redirects.
-
     bool m_notifiedLoadComplete;
 
-    bool m_loadingMultipartContent;
-    ResourceLoaderOptions m_options;
-
     enum ConnectionState {
         ConnectionStateNew,
         ConnectionStateStarted,
diff --git a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
index a9ee6ab..cdf2469 100644
--- a/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameSerializer.cpp
@@ -406,7 +406,7 @@
     if (!image || !image->hasImage() || image->errorOccurred() || !shouldAddURL(url))
         return;
 
-    RefPtr<SharedBuffer> data = image->image()->data();
+    RefPtr<SharedBuffer> data = image->getImage()->data();
     addToResources(image, data, url);
 }
 
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 7725566..901d7b8a 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -373,7 +373,7 @@
 void FrameView::invalidateRect(const IntRect& rect)
 {
     if (!parent()) {
-        if (HostWindow* window = hostWindow())
+        if (HostWindow* window = getHostWindow())
             window->invalidateRect(rect);
         return;
     }
@@ -398,7 +398,7 @@
 
     Widget::setFrameRect(newRect);
 
-    updateScrollbars(scrollOffsetDouble());
+    updateScrollbars();
     frameRectsChanged();
 
     updateScrollableAreaSet();
@@ -506,7 +506,7 @@
         return;
 
     m_contentsSize = size;
-    updateScrollbars(scrollOffsetDouble());
+    updateScrollbars();
     ScrollableArea::contentsResized();
 
     Page* page = frame().page();
@@ -537,7 +537,7 @@
         // updating scrollbars twice by skipping the call here when the content
         // size does not change.
         if (!m_frame->document()->printing() && size == contentsSize())
-            updateScrollbars(scrollOffsetDouble());
+            updateScrollbars();
     }
 
     setContentsSize(size);
@@ -1009,7 +1009,7 @@
             }
 
             if (needsScrollbarReconstruction() || scrollOriginChanged())
-                updateScrollbars(scrollOffsetDouble());
+                updateScrollbars();
 
             LayoutSize oldSize = m_size;
 
@@ -1449,7 +1449,7 @@
         }
     }
 
-    hostWindow()->invalidateRect(updateRect);
+    getHostWindow()->invalidateRect(updateRect);
 }
 
 void FrameView::restoreScrollbar()
@@ -1675,7 +1675,7 @@
     page->chromeClient().updateCompositedSelection(selection);
 }
 
-HostWindow* FrameView::hostWindow() const
+HostWindow* FrameView::getHostWindow() const
 {
     Page* page = frame().page();
     if (!page)
@@ -2257,7 +2257,7 @@
         return;
     adjustScrollbarOpacity();
     contentsResized();
-    updateScrollbars(scrollOffsetDouble());
+    updateScrollbars();
     positionScrollbarLayers();
 }
 
@@ -2551,7 +2551,7 @@
     GraphicsLayer* rootGraphicsLayer = layer->compositedLayerMapping()->mainGraphicsLayer();
     if (!rootGraphicsLayer->drawsContent())
         return;
-    const PaintArtifact& paintArtifact = rootGraphicsLayer->paintController().paintArtifact();
+    const PaintArtifact& paintArtifact = rootGraphicsLayer->getPaintController().paintArtifact();
 
     Page* page = frame().page();
     if (!page)
@@ -3160,7 +3160,7 @@
     if (!needsUpdate)
         return;
 
-    updateScrollbars(scrollOffsetDouble());
+    updateScrollbars();
 
     if (!layerForScrolling())
         return;
@@ -3270,7 +3270,7 @@
 
 void FrameView::windowResizerRectChanged()
 {
-    updateScrollbars(scrollOffsetDouble());
+    updateScrollbars();
 }
 
 bool FrameView::hasOverlayScrollbars() const
@@ -3441,7 +3441,7 @@
     return m_frame->settings()->ignoreMainFrameOverflowHiddenQuirk() && m_frame->isMainFrame();
 }
 
-void FrameView::updateScrollbars(const DoubleSize& desiredOffset)
+void FrameView::updateScrollbars()
 {
     if (m_frame->settings() && m_frame->settings()->rootLayerScrolls())
         return;
@@ -3450,7 +3450,7 @@
     if (visualViewportSuppliesScrollbars()) {
         setHasHorizontalScrollbar(false);
         setHasVerticalScrollbar(false);
-        setScrollOffsetFromUpdateScrollbars(desiredOffset);
+        setScrollOffsetFromUpdateScrollbars(scrollOffsetDouble());
         return;
     }
 
@@ -3482,7 +3482,7 @@
         updateScrollCorner();
     }
 
-    setScrollOffsetFromUpdateScrollbars(desiredOffset);
+    setScrollOffsetFromUpdateScrollbars(scrollOffsetDouble());
 }
 
 void FrameView::setScrollOffsetFromUpdateScrollbars(const DoubleSize& offset)
@@ -3520,7 +3520,7 @@
 
 void FrameView::scrollContents(const IntSize& scrollDelta)
 {
-    HostWindow* window = hostWindow();
+    HostWindow* window = getHostWindow();
     if (!window)
         return;
 
@@ -3621,7 +3621,7 @@
 
 IntRect FrameView::contentsToScreen(const IntRect& rect) const
 {
-    HostWindow* window = hostWindow();
+    HostWindow* window = getHostWindow();
     if (!window)
         return IntRect();
     return window->viewportToScreen(contentsToViewport(rect));
@@ -3732,7 +3732,7 @@
     return false;
 }
 
-Widget* FrameView::widget()
+Widget* FrameView::getWidget()
 {
     return this;
 }
@@ -3915,7 +3915,7 @@
     return adjustForAbsoluteZoom(viewportWidth, layoutView());
 }
 
-ScrollableArea* FrameView::scrollableArea()
+ScrollableArea* FrameView::getScrollableArea()
 {
     if (m_viewportScrollableArea)
         return m_viewportScrollableArea.get();
@@ -3930,7 +3930,7 @@
         return this;
 
     LayoutView* layoutView = this->layoutView();
-    return layoutView ? layoutView->scrollableArea() : nullptr;
+    return layoutView ? layoutView->getScrollableArea() : nullptr;
 }
 
 LayoutObject* FrameView::viewportLayoutObject()
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index f17b7c5..d7882674 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -373,7 +373,7 @@
     bool isScrollCornerVisible() const override;
     bool userInputScrollable(ScrollbarOrientation) const override;
     bool shouldPlaceVerticalScrollbarOnLeft() const override;
-    Widget* widget() override;
+    Widget* getWidget() override;
 
     LayoutRect scrollIntoView(
         const LayoutRect& rectInContent,
@@ -383,7 +383,7 @@
 
     // The window that hosts the FrameView. The FrameView will communicate scrolls and repaints to the
     // host window in the window's coordinate space.
-    HostWindow* hostWindow() const;
+    HostWindow* getHostWindow() const;
 
     // Returns a clip rect in host window coordinates. Used to clip the blit on a scroll.
     IntRect windowClipRect(IncludeScrollbarsInRect = ExcludeScrollbars) const;
@@ -548,11 +548,11 @@
     // be the RootFrameViewport, which adds pinch-zoom semantics to scrolling.
     // For non-root frames, this will be the the ScrollableArea used by the
     // FrameView, depending on whether root-layer-scrolls is enabled.
-    ScrollableArea* scrollableArea();
+    ScrollableArea* getScrollableArea();
 
     // Used to get at the underlying layoutViewport in the rare instances where
     // we actually want to scroll *just* the layout viewport (e.g. when sending
-    // deltas from CC). For typical scrolling cases, use scrollableArea().
+    // deltas from CC). For typical scrolling cases, use getScrollableArea().
     ScrollableArea* layoutViewportScrollableArea();
 
     int viewportWidth() const;
@@ -619,7 +619,7 @@
     IntRect adjustScrollbarRectForResizer(const IntRect&, Scrollbar&);
 
     // Called to update the scrollbars to accurately reflect the state of the view.
-    void updateScrollbars(const DoubleSize& desiredOffset);
+    void updateScrollbars();
 
     class InUpdateScrollbarsScope {
         STACK_ALLOCATED();
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index 072f78b..70e44f10 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -165,7 +165,7 @@
     bool flipY;
     parseOptions(options, flipY);
 
-    m_image = cropImage(image->cachedImage()->image(), cropRect, flipY, m_isPremultiplied, PremultiplyAlpha);
+    m_image = cropImage(image->cachedImage()->getImage(), cropRect, flipY, m_isPremultiplied, PremultiplyAlpha);
     if (!m_image)
         return;
     m_image->setOriginClean(!image->wouldTaintOrigin(document->getSecurityOrigin()));
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
index 5fb01b0..03f6bbd 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -98,12 +98,12 @@
         IntRect(-m_image->width(), -m_image->height(), m_image->width(), m_image->height()),
         &(imageElement->document()), defaultOptions);
 
-    ASSERT_EQ(imageBitmapNoCrop->bitmapImage()->imageForCurrentFrame(), imageElement->cachedImage()->image()->imageForCurrentFrame());
-    ASSERT_NE(imageBitmapInteriorCrop->bitmapImage()->imageForCurrentFrame(), imageElement->cachedImage()->image()->imageForCurrentFrame());
-    ASSERT_NE(imageBitmapExteriorCrop->bitmapImage()->imageForCurrentFrame(), imageElement->cachedImage()->image()->imageForCurrentFrame());
+    ASSERT_EQ(imageBitmapNoCrop->bitmapImage()->imageForCurrentFrame(), imageElement->cachedImage()->getImage()->imageForCurrentFrame());
+    ASSERT_NE(imageBitmapInteriorCrop->bitmapImage()->imageForCurrentFrame(), imageElement->cachedImage()->getImage()->imageForCurrentFrame());
+    ASSERT_NE(imageBitmapExteriorCrop->bitmapImage()->imageForCurrentFrame(), imageElement->cachedImage()->getImage()->imageForCurrentFrame());
 
     StaticBitmapImage* emptyImage = imageBitmapOutsideCrop->bitmapImage();
-    ASSERT_NE(emptyImage->imageForCurrentFrame(), imageElement->cachedImage()->image()->imageForCurrentFrame());
+    ASSERT_NE(emptyImage->imageForCurrentFrame(), imageElement->cachedImage()->getImage()->imageForCurrentFrame());
 }
 
 // Verifies that ImageBitmaps constructed from HTMLImageElements hold a reference to the original Image if the HTMLImageElement src is changed.
@@ -118,7 +118,7 @@
     RefPtrWillBeRawPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(),
         IntRect(0, 0, m_image->width(), m_image->height()),
         &(image->document()), defaultOptions);
-    ASSERT_EQ(imageBitmap->bitmapImage()->imageForCurrentFrame(), originalImageResource->image()->imageForCurrentFrame());
+    ASSERT_EQ(imageBitmap->bitmapImage()->imageForCurrentFrame(), originalImageResource->getImage()->imageForCurrentFrame());
 
     RefPtrWillBeRawPtr<ImageResource> newImageResource = ImageResource::create(
         StaticBitmapImage::create(m_image2).get());
@@ -126,19 +126,19 @@
 
     // The ImageBitmap should contain the same data as the original cached image
     {
-        ASSERT_EQ(imageBitmap->bitmapImage()->imageForCurrentFrame(), originalImageResource->image()->imageForCurrentFrame());
+        ASSERT_EQ(imageBitmap->bitmapImage()->imageForCurrentFrame(), originalImageResource->getImage()->imageForCurrentFrame());
         SkImage* image1 = imageBitmap->bitmapImage()->imageForCurrentFrame().get();
         ASSERT_NE(image1, nullptr);
-        SkImage* image2 = originalImageResource->image()->imageForCurrentFrame().get();
+        SkImage* image2 = originalImageResource->getImage()->imageForCurrentFrame().get();
         ASSERT_NE(image2, nullptr);
         ASSERT_EQ(image1, image2);
     }
 
     {
-        ASSERT_NE(imageBitmap->bitmapImage()->imageForCurrentFrame(), newImageResource->image()->imageForCurrentFrame());
+        ASSERT_NE(imageBitmap->bitmapImage()->imageForCurrentFrame(), newImageResource->getImage()->imageForCurrentFrame());
         SkImage* image1 = imageBitmap->bitmapImage()->imageForCurrentFrame().get();
         ASSERT_NE(image1, nullptr);
-        SkImage* image2 = newImageResource->image()->imageForCurrentFrame().get();
+        SkImage* image2 = newImageResource->getImage()->imageForCurrentFrame().get();
         ASSERT_NE(image2, nullptr);
         ASSERT_NE(image1, image2);
     }
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 3b20c40..5ea5d10 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -984,7 +984,7 @@
 
     frame()->document()->updateLayoutIgnorePendingStylesheets();
 
-    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->getScrollableArea();
     double viewportX = viewport->scrollPositionDouble().x();
     return adjustScrollForAbsoluteZoom(viewportX, frame()->pageZoomFactor());
 }
@@ -1004,7 +1004,7 @@
 
     frame()->document()->updateLayoutIgnorePendingStylesheets();
 
-    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->getScrollableArea();
     double viewportY = viewport->scrollPositionDouble().y();
     return adjustScrollForAbsoluteZoom(viewportY, frame()->pageZoomFactor());
 }
@@ -1120,7 +1120,7 @@
     x = ScrollableArea::normalizeNonFiniteScroll(x);
     y = ScrollableArea::normalizeNonFiniteScroll(y);
 
-    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->getScrollableArea();
 
     DoublePoint currentOffset = viewport->scrollPositionDouble();
     DoubleSize scaledDelta(x * frame()->pageZoomFactor(), y * frame()->pageZoomFactor());
@@ -1163,7 +1163,7 @@
         document()->updateLayoutIgnorePendingStylesheets();
 
     DoublePoint layoutPos(x * frame()->pageZoomFactor(), y * frame()->pageZoomFactor());
-    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->getScrollableArea();
     viewport->setScrollPosition(layoutPos, ProgrammaticScroll, ScrollBehaviorAuto);
 }
 
@@ -1192,7 +1192,7 @@
     double scaledX = 0.0;
     double scaledY = 0.0;
 
-    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->scrollableArea();
+    ScrollableArea* viewport = host->settings().inertVisualViewport() ? view->layoutViewportScrollableArea() : view->getScrollableArea();
 
     DoublePoint currentOffset = viewport->scrollPositionDouble();
     scaledX = currentOffset.x();
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index 8028a4f..96a0d16 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -115,7 +115,7 @@
         AffineTransform transform;
         transform.scale(deviceScaleFactor, deviceScaleFactor);
         transform.translate(-m_bounds.x(), -m_bounds.y());
-        context().paintController().createAndAppend<BeginTransformDisplayItem>(*m_localFrame, transform);
+        context().getPaintController().createAndAppend<BeginTransformDisplayItem>(*m_localFrame, transform);
     }
 
     GraphicsContext& context() { return m_pictureBuilder->context(); }
@@ -124,7 +124,7 @@
     {
         if (m_draggedNode && m_draggedNode->layoutObject())
             m_draggedNode->layoutObject()->updateDragState(false);
-        context().paintController().endItem<EndTransformDisplayItem>(*m_localFrame);
+        context().getPaintController().endItem<EndTransformDisplayItem>(*m_localFrame);
         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));
@@ -778,7 +778,7 @@
     if (remainingDelta.isZero())
         return ScrollResult(delta.width(), delta.height(), 0.0f, 0.0f);
 
-    ScrollResult result = view()->scrollableArea()->userScroll(granularity, remainingDelta);
+    ScrollResult result = view()->getScrollableArea()->userScroll(granularity, remainingDelta);
     result.didScrollX = result.didScrollX || (remainingDelta.width() != delta.width());
     result.didScrollY = result.didScrollY || (remainingDelta.height() != delta.height());
 
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
index b718b509..8b2e6c2a 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
@@ -303,9 +303,9 @@
     return layoutViewport().scrollAnimatorEnabled();
 }
 
-HostWindow* RootFrameViewport::hostWindow() const
+HostWindow* RootFrameViewport::getHostWindow() const
 {
-    return layoutViewport().hostWindow();
+    return layoutViewport().getHostWindow();
 }
 
 void RootFrameViewport::serviceScrollAnimations(double monotonicTime)
@@ -329,9 +329,9 @@
     visualViewport().cancelProgrammaticScrollAnimation();
 }
 
-Widget* RootFrameViewport::widget()
+Widget* RootFrameViewport::getWidget()
 {
-    return visualViewport().widget();
+    return visualViewport().getWidget();
 }
 
 void RootFrameViewport::clearScrollAnimators()
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.h b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
index 4640615..44b14408 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.h
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
@@ -64,12 +64,12 @@
     GraphicsLayer* layerForVerticalScrollbar() const override;
     ScrollResult userScroll(ScrollGranularity, const FloatSize&) override;
     bool scrollAnimatorEnabled() const override;
-    HostWindow* hostWindow() const override;
+    HostWindow* getHostWindow() const override;
     void serviceScrollAnimations(double) override;
     void updateCompositorScrollAnimations() override;
     void cancelProgrammaticScrollAnimation() override;
     ScrollBehavior scrollBehaviorStyle() const override;
-    Widget* widget() override;
+    Widget* getWidget() override;
     void clearScrollAnimators() override;
 
 private:
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
index 8b88e82bd..36f9620 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -151,7 +151,7 @@
     if (!mainFrame() || !mainFrame()->view())
         return FloatRect();
 
-    FloatPoint viewLocation = FloatPoint(mainFrame()->view()->scrollableArea()->scrollPositionDouble());
+    FloatPoint viewLocation = FloatPoint(mainFrame()->view()->getScrollableArea()->scrollPositionDouble());
     return FloatRect(viewLocation, visibleSize());
 }
 
@@ -431,7 +431,7 @@
     layerTreeView->clearViewportLayers();
 }
 
-HostWindow* VisualViewport::hostWindow() const
+HostWindow* VisualViewport::getHostWindow() const
 {
     return &frameHost().chromeClient();
 }
@@ -583,7 +583,7 @@
     return frameHost().page().mainFrame() && frameHost().page().mainFrame()->isLocalFrame() ? frameHost().page().deprecatedLocalMainFrame() : 0;
 }
 
-Widget* VisualViewport::widget()
+Widget* VisualViewport::getWidget()
 {
     return mainFrame()->view();
 }
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.h b/third_party/WebKit/Source/core/frame/VisualViewport.h
index ac56048..6d70a24b 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.h
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.h
@@ -166,7 +166,7 @@
     IntPoint rootFrameToViewport(const IntPoint&) const;
 
     // ScrollableArea implementation
-    HostWindow* hostWindow() const override;
+    HostWindow* getHostWindow() const override;
     DoubleRect visibleContentRectDouble(IncludeScrollbarsInRect = ExcludeScrollbars) const override;
     IntRect visibleContentRect(IncludeScrollbarsInRect = ExcludeScrollbars) const override;
     bool shouldUseIntegerScrollOffset() const override;
@@ -193,7 +193,7 @@
     GraphicsLayer* layerForScrolling() const override;
     GraphicsLayer* layerForHorizontalScrollbar() const override;
     GraphicsLayer* layerForVerticalScrollbar() const override;
-    Widget* widget() override;
+    Widget* getWidget() override;
 
     // Used for gathering data on user pinch-zoom statistics.
     void userDidChangeScale();
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index 9206c3f..9594d8f 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -208,15 +208,6 @@
     renderingContextFactories()[type] = renderingContextFactory;
 }
 
-ScriptValue HTMLCanvasElement::getContext(ScriptState* scriptState, const String& type, const CanvasContextCreationAttributes& attributes)
-{
-    CanvasRenderingContext* context = getCanvasRenderingContext(type, attributes);
-    if (!context) {
-        return ScriptValue::createNull(scriptState);
-    }
-    return ScriptValue(scriptState, toV8(context, scriptState->context()->Global(), scriptState->isolate()));
-}
-
 CanvasRenderingContext* HTMLCanvasElement::getCanvasRenderingContext(const String& type, const CanvasContextCreationAttributes& attributes)
 {
     CanvasRenderingContext::ContextType contextType = CanvasRenderingContext::contextTypeFromId(type);
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
index 21f6e93..fe4d8ef 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -63,6 +63,9 @@
 class ImageData;
 class IntSize;
 
+class CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext;
+typedef CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext RenderingContext;
+
 class CORE_EXPORT HTMLCanvasElement final : public HTMLElement, public DocumentVisibilityObserver, public CanvasImageSource, public ImageBufferClient, public ImageBitmapSource {
     DEFINE_WRAPPERTYPEINFO();
     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLCanvasElement);
@@ -90,8 +93,6 @@
         reset();
     }
 
-    // Called by HTMLCanvasElement's V8 bindings.
-    ScriptValue getContext(ScriptState*, const String&, const CanvasContextCreationAttributes&);
     // Called by Document::getCSSCanvasContext as well as above getContext().
     CanvasRenderingContext* getCanvasRenderingContext(const String&, const CanvasContextCreationAttributes&);
 
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl b/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
index 15e7e50..0f07c5a 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
@@ -28,26 +28,13 @@
 
 interface HTMLCanvasElement : HTMLElement
 {
+    // Note: Due to dependecies on modules, getContext is defined in a partial
+    // interface in HTMLCanvasElementModule.idl
+
     // FIXME: width and height should be unsigned long.
     attribute long width;
     attribute long height;
 
-    // Note: this differs deliberately from the specified Web IDL for this function:
-    //     RenderingContext? getContext(DOMString contextId, any... arguments);
-    // in order to eliminate the custom binding. It is functionally equivalent.
-    //
-    // The PermissiveDictionaryConversion extended attribute is needed to allow the
-    // autogenerated code to match the behavior of the custom binding. Web IDL
-    // requires throwing TypeError if the incoming argument is not an object type
-    // (and is not undefined or null). The binding must ignore this.
-    //
-    // Also note: the only reason this must return type "any" is to allow the
-    // InspectorInstrumentation wrappers to be called for canvases. If that could be
-    // handled differently the return type could be changed to "RenderingContext?"
-    // and the [CallWith=ScriptState] extended attribute removed.
-    //
-    [CallWith=ScriptState] any getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributes attributes);
-
     // Note: The arguments argument is variadic in the spec, but not here as
     // only one extra argument is actually used.
     // FIXME: type should not have a default value.
diff --git a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index f39c27b..099cc0c 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -489,7 +489,7 @@
     // The currentSrc IDL attribute must return the img element's current request's current URL.
     // Initially, the pending request turns into current request when it is either available or broken.
     // We use the image's dimensions as a proxy to it being in any of these states.
-    if (!imageLoader().image() || !imageLoader().image()->image() || !imageLoader().image()->image()->width())
+    if (!imageLoader().image() || !imageLoader().image()->getImage() || !imageLoader().image()->getImage()->width())
         return emptyAtom;
 
     return imageLoader().image()->url().getString();
@@ -595,7 +595,7 @@
     if (!imageLoader().imageComplete())
         return nullptr;
 
-    return imageLoader().image()->image();
+    return imageLoader().image()->getImage();
 }
 
 bool HTMLImageElement::isInteractiveContent() const
@@ -616,13 +616,13 @@
     }
 
     RefPtr<Image> sourceImage;
-    if (cachedImage()->image()->isSVGImage()) {
-        SVGImage* svgImage = toSVGImage(cachedImage()->image());
+    if (cachedImage()->getImage()->isSVGImage()) {
+        SVGImage* svgImage = toSVGImage(cachedImage()->getImage());
         IntSize imageSize = roundedIntSize(svgImage->concreteObjectSize(defaultObjectSize));
         sourceImage = SVGImageForContainer::create(svgImage,
             imageSize, 1, document().completeURL(imageSourceURL()));
     } else {
-        sourceImage = cachedImage()->image();
+        sourceImage = cachedImage()->getImage();
     }
 
     *status = NormalSourceImageStatus;
@@ -631,7 +631,7 @@
 
 bool HTMLImageElement::isSVGSource() const
 {
-    return cachedImage() && cachedImage()->image()->isSVGImage();
+    return cachedImage() && cachedImage()->getImage()->isSVGImage();
 }
 
 bool HTMLImageElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
@@ -648,8 +648,8 @@
     if (!image)
         return FloatSize();
 
-    if (image->image() && image->image()->isSVGImage())
-        return toSVGImage(cachedImage()->image())->concreteObjectSize(defaultObjectSize);
+    if (image->getImage() && image->getImage()->isSVGImage())
+        return toSVGImage(cachedImage()->getImage())->concreteObjectSize(defaultObjectSize);
 
     return FloatSize(image->imageSize(LayoutObject::shouldRespectImageOrientation(layoutObject()), 1.0f));
 }
@@ -660,12 +660,12 @@
     if (!image)
         return FloatSize();
 
-    if (image->image() && image->image()->isSVGImage())
-        return toSVGImage(cachedImage()->image())->concreteObjectSize(defaultObjectSize);
+    if (image->getImage() && image->getImage()->isSVGImage())
+        return toSVGImage(cachedImage()->getImage())->concreteObjectSize(defaultObjectSize);
 
     LayoutSize size;
     size = image->imageSize(LayoutObject::shouldRespectImageOrientation(layoutObject()), 1.0f);
-    if (layoutObject() && layoutObject()->isLayoutImage() && image->image() && !image->image()->hasRelativeSize())
+    if (layoutObject() && layoutObject()->isLayoutImage() && image->getImage() && !image->getImage()->hasRelativeSize())
         size.scale(toLayoutImage(layoutObject())->imageDevicePixelRatio());
     return FloatSize(size);
 }
@@ -711,7 +711,7 @@
         exceptionState.throwDOMException(InvalidStateError, "No image can be retrieved from the provided element.");
         return ScriptPromise();
     }
-    if (cachedImage()->image()->isSVGImage()) {
+    if (cachedImage()->getImage()->isSVGImage()) {
         exceptionState.throwDOMException(InvalidStateError, "The image element contains an SVG image, which is unsupported.");
         return ScriptPromise();
     }
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.cpp b/third_party/WebKit/Source/core/html/ImageDocument.cpp
index 640c1de..845152f0 100644
--- a/third_party/WebKit/Source/core/html/ImageDocument.cpp
+++ b/third_party/WebKit/Source/core/html/ImageDocument.cpp
@@ -201,7 +201,7 @@
     return ImageDocumentParser::create(this);
 }
 
-void ImageDocument::createDocumentStructure(bool loadingMultipartContent)
+void ImageDocument::createDocumentStructure()
 {
     RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*this);
     appendChild(rootElement);
@@ -209,13 +209,6 @@
 
     if (frame())
         frame()->loader().dispatchDocumentElementAvailable();
-    // Normally, ImageDocument creates an HTMLImageElement that doesn't actually load
-    // anything, and the ImageDocument routes the main resource data into the HTMLImageElement's
-    // ImageResource. However, the main resource pipeline doesn't know how to handle multipart content.
-    // For multipart content, we instead stop streaming data through the main resource and re-request
-    // the data directly.
-    if (loadingMultipartContent)
-        loader()->stopLoading();
 
     RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
     RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this);
@@ -231,12 +224,11 @@
 
     m_imageElement = HTMLImageElement::create(*this);
     m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none");
-    // If the image is multipart, we neglect to mention to the HTMLImageElement that it's in an
-    // ImageDocument, so that it requests the image normally.
-    if (!loadingMultipartContent)
-        m_imageElement->setLoadingImageDocument();
+    m_imageElement->setLoadingImageDocument();
     m_imageElement->setSrc(url().getString());
     body->appendChild(m_imageElement.get());
+    if (loader())
+        m_imageElement->cachedImage()->responseReceived(loader()->response(), nullptr);
 
     if (shouldShrinkToFit()) {
         // Add event listeners
@@ -249,8 +241,6 @@
 
     rootElement->appendChild(head);
     rootElement->appendChild(body);
-    if (loadingMultipartContent)
-        finishedParsing();
 }
 
 float ImageDocument::scale() const
@@ -415,11 +405,10 @@
 
 ImageResource* ImageDocument::cachedImage()
 {
-    bool loadingMultipartContent = loader() && loader()->loadingMultipartContent();
     if (!m_imageElement)
-        createDocumentStructure(loadingMultipartContent);
+        createDocumentStructure();
 
-    return loadingMultipartContent ? nullptr : m_imageElement->cachedImage();
+    return m_imageElement->cachedImage();
 }
 
 bool ImageDocument::shouldShrinkToFit() const
diff --git a/third_party/WebKit/Source/core/html/ImageDocument.h b/third_party/WebKit/Source/core/html/ImageDocument.h
index 314d9d2..da28cd1c 100644
--- a/third_party/WebKit/Source/core/html/ImageDocument.h
+++ b/third_party/WebKit/Source/core/html/ImageDocument.h
@@ -62,7 +62,7 @@
     void dispose() override;
 #endif
 
-    void createDocumentStructure(bool loadingMultipartContent);
+    void createDocumentStructure();
 
     // These methods are for m_shrinkToFitMode == Desktop.
     void resizeImageToFit(ScaleType);
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp
index d243dbb..e0a3182 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasFontCache.cpp
@@ -35,7 +35,7 @@
     defaultFontDescription.setComputedSize(defaultFontSize);
     m_defaultFontStyle = ComputedStyle::create();
     m_defaultFontStyle->setFontDescription(defaultFontDescription);
-    m_defaultFontStyle->font().update(m_defaultFontStyle->font().fontSelector());
+    m_defaultFontStyle->font().update(m_defaultFontStyle->font().getFontSelector());
 }
 
 CanvasFontCache::~CanvasFontCache()
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
index 3900487..4e2819d 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -77,6 +77,7 @@
     virtual bool hasAlpha() const { return true; }
     virtual void setIsHidden(bool) = 0;
     virtual bool isContextLost() const { return true; }
+    virtual void setCanvasGetContextResult(RenderingContext&) = 0;
 
     // Return true if the content is updated.
     virtual bool paintRenderingResultsToCanvas(SourceDrawingBuffer) { return false; }
diff --git a/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp b/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
index a17897f..4196765 100644
--- a/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
+++ b/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
@@ -231,7 +231,7 @@
             if (LayoutBox* innerEditorLayoutObject = element().innerEditorElement()->layoutBox()) {
                 // FIXME: This class has no need to know about PaintLayer!
                 if (PaintLayer* innerLayer = innerEditorLayoutObject->layer()) {
-                    if (PaintLayerScrollableArea* innerScrollableArea = innerLayer->scrollableArea()) {
+                    if (PaintLayerScrollableArea* innerScrollableArea = innerLayer->getScrollableArea()) {
                         IntSize scrollOffset(!layoutTextControl->style()->isLeftToRightDirection() ? innerScrollableArea->scrollWidth().toInt() : 0, 0);
                         innerScrollableArea->scrollToOffset(scrollOffset, ScrollOffsetClamped);
                     }
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp
index 3009fee9e..8e093f96 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLPreloadScannerTest.cpp
@@ -370,8 +370,7 @@
         {"http://example.test", "<link rel=preload href=bla as=style>", "bla", "http://example.test/", Resource::CSSStyleSheet, 0},
         {"http://example.test", "<link rel=preload href=bla as=image>", "bla", "http://example.test/", Resource::Image, 0},
         {"http://example.test", "<link rel=preload href=bla as=font>", "bla", "http://example.test/", Resource::Font, 0},
-        {"http://example.test", "<link rel=preload href=bla as=audio>", "bla", "http://example.test/", Resource::Media, 0},
-        {"http://example.test", "<link rel=preload href=bla as=video>", "bla", "http://example.test/", Resource::Media, 0},
+        {"http://example.test", "<link rel=preload href=bla as=media>", "bla", "http://example.test/", Resource::Media, 0},
         {"http://example.test", "<link rel=preload href=bla as=track>", "bla", "http://example.test/", Resource::TextTrack, 0},
     };
 
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 570f5228..e433a2d 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -838,7 +838,7 @@
             // Get hotspot and convert from logical pixels to physical pixels.
             IntPoint hotSpot = (*cursors)[i].hotSpot();
             hotSpot.scale(scale, scale);
-            IntSize size = cachedImage->image()->size();
+            IntSize size = cachedImage->getImage()->size();
             if (cachedImage->errorOccurred())
                 continue;
             // Limit the size of cursors (in UI pixels) so that they cannot be
@@ -847,7 +847,7 @@
             if (size.width() > maximumCursorSize || size.height() > maximumCursorSize)
                 continue;
 
-            Image* image = cachedImage->image();
+            Image* image = cachedImage->getImage();
             // Ensure no overflow possible in calculations above.
             if (scale < minimumCursorScale)
                 continue;
@@ -946,7 +946,7 @@
     LayoutObject* layoutObject = node ? node->layoutObject() : nullptr;
     if (layoutObject && m_frame->view()) {
         PaintLayer* layer = layoutObject->enclosingLayer();
-        inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
+        inResizer = layer->getScrollableArea() && layer->getScrollableArea()->isPointInResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
     }
 
     // During selection, use an I-beam no matter what we're over.
@@ -1051,8 +1051,8 @@
         FrameView* view = m_frame->view();
         PaintLayer* layer = mev.innerNode()->layoutObject() ? mev.innerNode()->layoutObject()->enclosingLayer() : nullptr;
         IntPoint p = view->rootFrameToContents(mouseEvent.position());
-        if (layer && layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(p, ResizerForPointer)) {
-            m_resizeScrollableArea = layer->scrollableArea();
+        if (layer && layer->getScrollableArea() && layer->getScrollableArea()->isPointInResizeControl(p, ResizerForPointer)) {
+            m_resizeScrollableArea = layer->getScrollableArea();
             m_resizeScrollableArea->setInResizeMode(true);
             m_offsetFromResizeCorner = LayoutSize(m_resizeScrollableArea->offsetFromResizeCorner(p));
             return WebInputEventResult::HandledSystem;
@@ -1125,7 +1125,7 @@
 
 ScrollableArea* EventHandler::associatedScrollableArea(const PaintLayer* layer) const
 {
-    if (PaintLayerScrollableArea* scrollableArea = layer->scrollableArea()) {
+    if (PaintLayerScrollableArea* scrollableArea = layer->getScrollableArea()) {
         if (scrollableArea->scrollsOverflow())
             return scrollableArea;
     }
@@ -1691,7 +1691,7 @@
 {
     // If clicking on a frame scrollbar, do not mess up with content focus.
     if (targetedEvent.hitTestResult().scrollbar() && m_frame->contentLayoutObject()) {
-        if (targetedEvent.hitTestResult().scrollbar()->scrollableArea() == m_frame->contentLayoutObject()->scrollableArea())
+        if (targetedEvent.hitTestResult().scrollbar()->getScrollableArea() == m_frame->contentLayoutObject()->getScrollableArea())
             return WebInputEventResult::NotHandled;
     }
 
@@ -2225,8 +2225,8 @@
     if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
         PaintLayer* layer = eventTarget->layoutObject() ? eventTarget->layoutObject()->enclosingLayer() : nullptr;
         IntPoint p = m_frame->view()->rootFrameToContents(gestureEvent.position());
-        if (layer && layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(p, ResizerForTouch)) {
-            m_resizeScrollableArea = layer->scrollableArea();
+        if (layer && layer->getScrollableArea() && layer->getScrollableArea()->isPointInResizeControl(p, ResizerForTouch)) {
+            m_resizeScrollableArea = layer->getScrollableArea();
             m_resizeScrollableArea->setInResizeMode(true);
             m_offsetFromResizeCorner = LayoutSize(m_resizeScrollableArea->offsetFromResizeCorner(p));
             return true;
@@ -2846,7 +2846,7 @@
 
     m_frame->view()->setCursor(pointerCursor());
     IntPoint locationInViewport = visualViewport.rootFrameToViewport(locationInRootFrame);
-    IntPoint globalPosition = view->hostWindow()->viewportToScreen(IntRect(locationInViewport, IntSize())).location();
+    IntPoint globalPosition = view->getHostWindow()->viewportToScreen(IntRect(locationInViewport, IntSize())).location();
 
     Node* targetNode = overrideTargetElement ? overrideTargetElement : doc->focusedElement();
     if (!targetNode)
diff --git a/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp b/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp
index 6bf5d94..fc66082 100644
--- a/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp
+++ b/third_party/WebKit/Source/core/inspector/DevToolsHost.cpp
@@ -169,7 +169,7 @@
     float zoomFactor = m_frontendFrame->pageZoomFactor();
     // Cancel the device scale factor applied to the zoom factor in
     // use-zoom-for-dsf mode.
-    const HostWindow* hostWindow = m_frontendFrame->view()->hostWindow();
+    const HostWindow* hostWindow = m_frontendFrame->view()->getHostWindow();
     float windowToViewportRatio = hostWindow->windowToViewportScalar(1.0f);
     return zoomFactor / windowToViewportRatio;
 }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
index 44f1e4b..b5efd8f4 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -332,9 +332,9 @@
     IntRect interestRect(IntPoint(0, 0), size);
     layer->paint(&interestRect);
 
-    GraphicsContext context(layer->paintController());
+    GraphicsContext context(layer->getPaintController());
     context.beginRecording(interestRect);
-    layer->paintController().paintArtifact().replay(context);
+    layer->getPaintController().paintArtifact().replay(context);
     RefPtr<PictureSnapshot> snapshot = adoptRef(new PictureSnapshot(context.endRecording()));
 
     *snapshotId = String::number(++s_lastSnapshotId);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
index e8cfe18..fb7f40bc 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
@@ -389,7 +389,7 @@
     if (response.getSecurityStyle() != ResourceResponse::SecurityStyleUnknown
         && response.getSecurityStyle() != ResourceResponse::SecurityStyleUnauthenticated) {
 
-        const ResourceResponse::SecurityDetails* responseSecurityDetails = response.securityDetails();
+        const ResourceResponse::SecurityDetails* responseSecurityDetails = response.getSecurityDetails();
 
         int numUnknownSCTs = safeCast<int>(responseSecurityDetails->numUnknownSCTs);
         int numInvalidSCTs = safeCast<int>(responseSecurityDetails->numInvalidSCTs);
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
index a27f38b5..4aea374 100644
--- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
+++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -266,7 +266,7 @@
     value->setString("frame", toHexString(node->document().frame()));
     setNodeInfo(value.get(), node, "nodeId", "nodeName");
     value->setString("reason", reason.reasonString());
-    value->setString("extraData", reason.extraData());
+    value->setString("extraData", reason.getExtraData());
     if (RefPtr<ScriptCallStack> stackTrace = ScriptCallStack::capture(1))
         stackTrace->toTracedValue(value.get(), "stackTrace");
     return value.release();
diff --git a/third_party/WebKit/Source/core/layout/HitTestResult.cpp b/third_party/WebKit/Source/core/layout/HitTestResult.cpp
index 9ee7ddf..9ce0a30 100644
--- a/third_party/WebKit/Source/core/layout/HitTestResult.cpp
+++ b/third_party/WebKit/Source/core/layout/HitTestResult.cpp
@@ -318,7 +318,7 @@
     if (layoutObject && layoutObject->isImage()) {
         LayoutImage* image = toLayoutImage(layoutObject);
         if (image->cachedImage() && !image->cachedImage()->errorOccurred())
-            return image->cachedImage()->image();
+            return image->cachedImage()->getImage();
     }
 
     return nullptr;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
index d58373e..33c18f7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -877,7 +877,7 @@
 
         for (auto* block : *infoSet) {
             if (block->hasOverflowClip()) {
-                childrenMarkedForRelayout |= block->layer()->scrollableArea()->updateAfterLayout(layoutScope);
+                childrenMarkedForRelayout |= block->layer()->getScrollableArea()->updateAfterLayout(layoutScope);
             }
         }
     }
@@ -892,14 +892,14 @@
             // Workaround for now. We cannot delay the scroll info for overflow
             // for items with opposite writing directions, as the contents needs
             // to overflow in that direction
-            layer()->scrollableArea()->updateAfterLayout();
+            layer()->getScrollableArea()->updateAfterLayout();
             return;
         }
 
         if (gDelayUpdateScrollInfo)
             gDelayedUpdateScrollInfoSet->add(this);
         else
-            layer()->scrollableArea()->updateAfterLayout();
+            layer()->getScrollableArea()->updateAfterLayout();
     }
 }
 
@@ -909,7 +909,7 @@
 
     bool needsScrollAnchoring = RuntimeEnabledFeatures::scrollAnchoringEnabled() && hasOverflowClip();
     if (needsScrollAnchoring)
-        scrollableArea()->scrollAnchor().save();
+        getScrollableArea()->scrollAnchor().save();
 
     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
     // layoutBlock().
@@ -923,7 +923,7 @@
     invalidateBackgroundObscurationStatus();
 
     if (needsScrollAnchoring)
-        scrollableArea()->scrollAnchor().restore();
+        getScrollableArea()->scrollAnchor().restore();
 
     m_heightAvailableToChildrenChanged = false;
 }
@@ -1603,7 +1603,7 @@
     if (!scrollsOverflow())
         return false;
 
-    return layer()->scrollableArea()->hitTestOverflowControls(result, roundedIntPoint(locationInContainer - toLayoutSize(accumulatedOffset)));
+    return layer()->getScrollableArea()->hitTestOverflowControls(result, roundedIntPoint(locationInContainer - toLayoutSize(accumulatedOffset)));
 }
 
 Node* LayoutBlock::nodeForHitTest() const
@@ -1925,7 +1925,7 @@
 int LayoutBlock::columnGap() const
 {
     if (style()->hasNormalColumnGap())
-        return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
+        return style()->getFontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
     return static_cast<int>(style()->columnGap());
 }
 
@@ -2183,7 +2183,7 @@
     // Note that inline-block counts as replaced here.
     ASSERT(linePositionMode == PositionOfInteriorLineBoxes);
 
-    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
+    const FontMetrics& fontMetrics = style(firstLine)->getFontMetrics();
     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
 }
 
@@ -2202,7 +2202,7 @@
 
     if (childrenInline()) {
         if (firstLineBox())
-            return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
+            return firstLineBox()->logicalTop() + style(true)->getFontMetrics().ascent(firstRootBox()->baselineType());
         return -1;
     }
     for (LayoutBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
@@ -2236,13 +2236,13 @@
 
     if (childrenInline()) {
         if (!firstLineBox() && hasLineIfEmpty()) {
-            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
+            const FontMetrics& fontMetrics = firstLineStyle()->getFontMetrics();
             return fontMetrics.ascent()
                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
         }
         if (lastLineBox())
-            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
+            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->getFontMetrics().ascent(lastRootBox()->baselineType());
         return -1;
     }
 
@@ -2256,7 +2256,7 @@
         }
     }
     if (!haveNormalFlowChild && hasLineIfEmpty()) {
-        const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
+        const FontMetrics& fontMetrics = firstLineStyle()->getFontMetrics();
         return fontMetrics.ascent()
             + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
             + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
@@ -2804,7 +2804,7 @@
     computeOverflow(oldClientAfterEdge, true);
 
     if (hasOverflowClip())
-        layer()->scrollableArea()->updateAfterOverflowRecalc();
+        layer()->getScrollableArea()->updateAfterOverflowRecalc();
 
     return !hasOverflowClip();
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
index db3c4e72..3a9f713 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -440,12 +440,12 @@
     float measuredWidth = 0;
     FloatRect glyphBounds;
 
-    bool kerningIsEnabled = font.fontDescription().getTypesettingFeatures() & Kerning;
+    bool kerningIsEnabled = font.getFontDescription().getTypesettingFeatures() & Kerning;
 
 #if OS(MACOSX)
     // FIXME: Having any font feature settings enabled can lead to selection gaps on
     // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418
-    bool canUseCachedWordMeasurements = font.canShapeWordByWord() && !font.fontDescription().featureSettings();
+    bool canUseCachedWordMeasurements = font.canShapeWordByWord() && !font.getFontDescription().featureSettings();
 #else
     bool canUseCachedWordMeasurements = font.canShapeWordByWord();
 #endif
@@ -498,7 +498,7 @@
         measuredWidth = 0;
     }
 
-    glyphOverflow.setFromBounds(glyphBounds, font.fontMetrics().floatAscent(), font.fontMetrics().floatDescent(), measuredWidth);
+    glyphOverflow.setFromBounds(glyphBounds, font.getFontMetrics().floatAscent(), font.getFontMetrics().floatDescent(), measuredWidth);
 
     run->m_box->setLogicalWidth(LayoutUnit(measuredWidth) + hyphenWidth);
     if (!fallbackFonts.isEmpty()) {
@@ -634,7 +634,7 @@
 
             if (rt.textLength()) {
                 if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt.characterAt(r->m_start)))
-                    totalLogicalWidth += rt.style(lineInfo.isFirstLine())->font().fontDescription().wordSpacing();
+                    totalLogicalWidth += rt.style(lineInfo.isFirstLine())->font().getFontDescription().wordSpacing();
                 needsWordSpacing = !isSpaceOrNewline(rt.characterAt(r->m_stop - 1));
             }
 
@@ -1186,7 +1186,7 @@
         TextRun run = constructTextRun(font, &trailingWhitespaceChar, 1,
             text->styleRef(), text->style()->direction());
         float spaceWidth = font.width(run);
-        inlineMax -= LayoutUnit::fromFloatCeil(spaceWidth + font.fontDescription().wordSpacing());
+        inlineMax -= LayoutUnit::fromFloatCeil(spaceWidth + font.getFontDescription().wordSpacing());
         if (inlineMin > inlineMax)
             inlineMin = inlineMax;
     }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index c48220c9..71fc424 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -256,7 +256,7 @@
     // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
     // new zoomed coordinate space.
     if (hasOverflowClip() && oldStyle && oldStyle->effectiveZoom() != newStyle.effectiveZoom()) {
-        PaintLayerScrollableArea* scrollableArea = this->scrollableArea();
+        PaintLayerScrollableArea* scrollableArea = this->getScrollableArea();
         ASSERT(scrollableArea);
         if (int left = scrollableArea->scrollXOffset()) {
             left = (left / oldStyle->effectiveZoom()) * newStyle.effectiveZoom();
@@ -281,7 +281,7 @@
         document().view()->recalculateScrollbarOverlayStyle(document().view()->documentBackgroundColor());
         document().view()->recalculateCustomScrollbarStyle();
         if (LayoutView* layoutView = view()) {
-            if (PaintLayerScrollableArea* scrollableArea = layoutView->scrollableArea()) {
+            if (PaintLayerScrollableArea* scrollableArea = layoutView->getScrollableArea()) {
                 if (scrollableArea->horizontalScrollbar() && scrollableArea->horizontalScrollbar()->isCustomScrollbar())
                     scrollableArea->horizontalScrollbar()->styleChanged();
                 if (scrollableArea->verticalScrollbar() && scrollableArea->verticalScrollbar()->isCustomScrollbar())
@@ -439,7 +439,7 @@
 LayoutUnit LayoutBox::scrollWidth() const
 {
     if (hasOverflowClip())
-        return scrollableArea()->scrollWidth();
+        return getScrollableArea()->scrollWidth();
     // For objects with visible overflow, this matches IE.
     // FIXME: Need to work right with writing modes.
     if (style()->isLeftToRightDirection())
@@ -450,7 +450,7 @@
 LayoutUnit LayoutBox::scrollHeight() const
 {
     if (hasOverflowClip())
-        return scrollableArea()->scrollHeight();
+        return getScrollableArea()->scrollHeight();
     // For objects with visible overflow, this matches IE.
     // FIXME: Need to work right with writing modes.
     return std::max(clientHeight(), layoutOverflowRect().maxY() - borderTop());
@@ -458,12 +458,12 @@
 
 LayoutUnit LayoutBox::scrollLeft() const
 {
-    return hasOverflowClip() ? LayoutUnit(scrollableArea()->scrollXOffset()) : LayoutUnit();
+    return hasOverflowClip() ? LayoutUnit(getScrollableArea()->scrollXOffset()) : LayoutUnit();
 }
 
 LayoutUnit LayoutBox::scrollTop() const
 {
-    return hasOverflowClip() ? LayoutUnit(scrollableArea()->scrollYOffset()) : LayoutUnit();
+    return hasOverflowClip() ? LayoutUnit(getScrollableArea()->scrollYOffset()) : LayoutUnit();
 }
 
 int LayoutBox::pixelSnappedScrollWidth() const
@@ -474,7 +474,7 @@
 int LayoutBox::pixelSnappedScrollHeight() const
 {
     if (hasOverflowClip())
-        return snapSizeToPixel(scrollableArea()->scrollHeight(), location().y() + clientTop());
+        return snapSizeToPixel(getScrollableArea()->scrollHeight(), location().y() + clientTop());
     // For objects with visible overflow, this matches IE.
     // FIXME: Need to work right with writing modes.
     return snapSizeToPixel(scrollHeight(), location().y() + clientTop());
@@ -487,7 +487,7 @@
     DisableCompositingQueryAsserts disabler;
 
     if (hasOverflowClip())
-        scrollableArea()->scrollToXOffset(newLeft, ScrollOffsetClamped, ScrollBehaviorAuto);
+        getScrollableArea()->scrollToXOffset(newLeft, ScrollOffsetClamped, ScrollBehaviorAuto);
 }
 
 void LayoutBox::setScrollTop(LayoutUnit newTop)
@@ -496,7 +496,7 @@
     DisableCompositingQueryAsserts disabler;
 
     if (hasOverflowClip())
-        scrollableArea()->scrollToYOffset(newTop, ScrollOffsetClamped, ScrollBehaviorAuto);
+        getScrollableArea()->scrollToYOffset(newTop, ScrollOffsetClamped, ScrollBehaviorAuto);
 }
 
 void LayoutBox::scrollToOffset(const DoubleSize& offset, ScrollBehavior scrollBehavior)
@@ -506,7 +506,7 @@
     DisableCompositingQueryAsserts disabler;
 
     if (hasOverflowClip())
-        scrollableArea()->scrollToOffset(offset, ScrollOffsetClamped, scrollBehavior);
+        getScrollableArea()->scrollToOffset(offset, ScrollOffsetClamped, scrollBehavior);
 }
 
 // Returns true iff we are attempting an autoscroll inside an iframe with scrolling="no".
@@ -540,13 +540,13 @@
     if (hasOverflowClip() && !restrictedByLineClamp) {
         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
         // This will prevent us from revealing text hidden by the slider in Safari RSS.
-        newRect = scrollableArea()->scrollIntoView(rect, alignX, alignY, scrollType);
+        newRect = getScrollableArea()->scrollIntoView(rect, alignX, alignY, scrollType);
     } else if (!parentBox && canBeProgramaticallyScrolled()) {
         if (FrameView* frameView = this->frameView()) {
             HTMLFrameOwnerElement* ownerElement = document().ownerElement();
             if (!isDisallowedAutoscroll(ownerElement, frameView)) {
                 if (makeVisibleInVisualViewport) {
-                    frameView->scrollableArea()->scrollIntoView(rect, alignX, alignY, scrollType);
+                    frameView->getScrollableArea()->scrollIntoView(rect, alignX, alignY, scrollType);
                 } else {
                     frameView->layoutViewportScrollableArea()->scrollIntoView(rect, alignX, alignY, scrollType);
                 }
@@ -644,7 +644,7 @@
         IntSize oldPixelSnappedBorderRectSize = pixelSnappedBorderBoxRect().size();
         setLocation(location);
         if (pixelSnappedBorderBoxRect().size() != oldPixelSnappedBorderRectSize)
-            scrollableArea()->updateAfterLayout();
+            getScrollableArea()->updateAfterLayout();
         return;
     }
 
@@ -737,7 +737,7 @@
     if (!hasOverflowClip() || style()->overflowY() == OverflowOverlay)
         return 0;
 
-    return scrollableArea()->verticalScrollbarWidth();
+    return getScrollableArea()->verticalScrollbarWidth();
 }
 
 int LayoutBox::horizontalScrollbarHeight() const
@@ -745,7 +745,7 @@
     if (!hasOverflowClip() || style()->overflowX() == OverflowOverlay)
         return 0;
 
-    return scrollableArea()->horizontalScrollbarHeight();
+    return getScrollableArea()->horizontalScrollbarHeight();
 }
 
 int LayoutBox::intrinsicScrollbarLogicalWidth() const
@@ -753,16 +753,16 @@
     if (!hasOverflowClip())
         return 0;
 
-    ASSERT(scrollableArea());
+    ASSERT(getScrollableArea());
 
     if (isHorizontalWritingMode() && style()->overflowY() == OverflowScroll) {
         // Even with OverflowScroll, the scrollbar may not exist (crbug.com/415031).
-        return scrollableArea()->hasVerticalScrollbar() ? verticalScrollbarWidth() : 0;
+        return getScrollableArea()->hasVerticalScrollbar() ? verticalScrollbarWidth() : 0;
     }
 
     if (!isHorizontalWritingMode() && style()->overflowX() == OverflowScroll) {
         // Even with OverflowScroll, the scrollbar may not exist (crbug.com/415031).
-        return scrollableArea()->hasHorizontalScrollbar() ? horizontalScrollbarHeight() : 0;
+        return getScrollableArea()->hasHorizontalScrollbar() ? horizontalScrollbarHeight() : 0;
     }
 
     return 0;
@@ -773,10 +773,10 @@
     // Presumably the same issue as in setScrollTop. See crbug.com/343132.
     DisableCompositingQueryAsserts disabler;
 
-    if (!scrollableArea())
+    if (!getScrollableArea())
         return ScrollResult();
 
-    return scrollableArea()->userScroll(granularity, delta);
+    return getScrollableArea()->userScroll(granularity, delta);
 }
 
 bool LayoutBox::canBeScrolledAndHasScrollableArea() const
@@ -920,7 +920,7 @@
         restrictedByLineClamp = !parent()->style()->lineClamp().isNone();
 
     if (hasOverflowClip() && !restrictedByLineClamp) {
-        PaintLayerScrollableArea* scrollableArea = this->scrollableArea();
+        PaintLayerScrollableArea* scrollableArea = this->getScrollableArea();
         ASSERT(scrollableArea);
 
         DoubleSize newScrollOffset = scrollableArea->adjustedScrollOffset() + delta;
@@ -957,7 +957,7 @@
     ASSERT(hasOverflowClip());
     ASSERT(hasLayer());
     // FIXME: Return DoubleSize here. crbug.com/414283.
-    return flooredIntSize(scrollableArea()->scrollOffset());
+    return flooredIntSize(getScrollableArea()->scrollOffset());
 }
 
 void LayoutBox::mapScrollingContentsRectToBoxSpace(LayoutRect& rect) const
@@ -1456,7 +1456,7 @@
         return false;
     for (const FillLayer* curLayer = &layers; curLayer; curLayer = curLayer->next()) {
         if (curLayer->image() && image == curLayer->image()->data()) {
-            bool maybeAnimated = curLayer->image()->cachedImage() && curLayer->image()->cachedImage()->image() && curLayer->image()->cachedImage()->image()->maybeAnimated();
+            bool maybeAnimated = curLayer->image()->cachedImage() && curLayer->image()->cachedImage()->getImage() && curLayer->image()->cachedImage()->getImage()->maybeAnimated();
             if (maybeAnimated && drawingBackground)
                 setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull);
             else
@@ -1477,7 +1477,7 @@
     while (layoutView->frame()->ownerLayoutObject())
         layoutView = layoutView->frame()->ownerLayoutObject()->view();
     mapToVisibleRectInAncestorSpace(layoutView, rect, nullptr);
-    return rect.intersects(LayoutRect(layoutView->frameView()->scrollableArea()->visibleContentRectDouble()));
+    return rect.intersects(LayoutRect(layoutView->frameView()->getScrollableArea()->visibleContentRectDouble()));
 }
 
 PaintInvalidationReason LayoutBox::invalidatePaintIfNeeded(PaintInvalidationState& paintInvalidationState, const LayoutBoxModelObject& paintInvalidationContainer)
@@ -1487,7 +1487,7 @@
 
     if (hasBoxDecorationBackground()
         // We also paint overflow controls in background phase.
-        || (hasOverflowClip() && scrollableArea()->hasOverflowControls())) {
+        || (hasOverflowClip() && getScrollableArea()->hasOverflowControls())) {
         PaintLayer& layer = paintInvalidationState.enclosingSelfPaintingLayer(*this);
         if (layer.layoutObject() != this)
             layer.setNeedsPaintPhaseDescendantBlockBackgrounds();
@@ -1510,7 +1510,7 @@
     if (!view()->doingFullPaintInvalidation() && !isFullPaintInvalidationReason(reason))
         invalidatePaintForOverflowIfNeeded();
 
-    if (PaintLayerScrollableArea* area = scrollableArea())
+    if (PaintLayerScrollableArea* area = getScrollableArea())
         area->invalidatePaintOfScrollControlsIfNeeded(paintInvalidationState, paintInvalidationContainer);
 
     // This is for the next invalidatePaintIfNeeded so must be at the end.
@@ -1543,7 +1543,7 @@
 
 void LayoutBox::excludeScrollbars(LayoutRect& rect, OverlayScrollbarSizeRelevancy relevancy) const
 {
-    if (PaintLayerScrollableArea* scrollableArea = this->scrollableArea()) {
+    if (PaintLayerScrollableArea* scrollableArea = this->getScrollableArea()) {
         if (shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
             rect.move(scrollableArea->verticalScrollbarWidth(relevancy), 0);
         rect.contract(scrollableArea->verticalScrollbarWidth(relevancy), scrollableArea->horizontalScrollbarHeight(relevancy));
@@ -3628,7 +3628,7 @@
     // <rdar://problem/3777804> Deleting all content in a document can result in giant tall-as-window insertion point
     //
     // FIXME: ignoring :first-line, missing good reason to take care of
-    LayoutUnit fontHeight = LayoutUnit(style()->fontMetrics().height());
+    LayoutUnit fontHeight = LayoutUnit(style()->getFontMetrics().height());
     if (fontHeight > rect.height() || (!isAtomicInlineLevel() && !isTable()))
         rect.setHeight(fontHeight);
 
@@ -3759,7 +3759,7 @@
 
 bool LayoutBox::hasNonCompositedScrollbars() const
 {
-    if (PaintLayerScrollableArea* scrollableArea = this->scrollableArea()) {
+    if (PaintLayerScrollableArea* scrollableArea = this->getScrollableArea()) {
         if (scrollableArea->hasHorizontalScrollbar() && !scrollableArea->layerForHorizontalScrollbar())
             return true;
         if (scrollableArea->hasVerticalScrollbar() && !scrollableArea->layerForVerticalScrollbar())
@@ -3840,7 +3840,7 @@
         // we need to fully invalidate to cover the changed radius.
         FloatRoundedRect oldRoundedRect = style()->getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), oldBorderBoxSize));
         FloatRoundedRect newRoundedRect = style()->getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), newBorderBoxSize));
-        if (oldRoundedRect.radii() != newRoundedRect.radii())
+        if (oldRoundedRect.getRadii() != newRoundedRect.getRadii())
             return PaintInvalidationBorderBoxChange;
     }
 
@@ -4646,7 +4646,7 @@
 void LayoutBox::clearPreviousPaintInvalidationRects()
 {
     LayoutBoxModelObject::clearPreviousPaintInvalidationRects();
-    if (PaintLayerScrollableArea* scrollableArea = this->scrollableArea())
+    if (PaintLayerScrollableArea* scrollableArea = this->getScrollableArea())
         scrollableArea->clearPreviousPaintInvalidationRects();
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index cc61a139..d862aeb 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -115,7 +115,7 @@
 
 bool LayoutBoxModelObject::usesCompositedScrolling() const
 {
-    return hasOverflowClip() && hasLayer() && layer()->scrollableArea()->usesCompositedScrolling();
+    return hasOverflowClip() && hasLayer() && layer()->getScrollableArea()->usesCompositedScrolling();
 }
 
 LayoutBoxModelObject::~LayoutBoxModelObject()
@@ -322,9 +322,9 @@
     return m_layer && m_layer->isSelfPaintingLayer();
 }
 
-PaintLayerScrollableArea* LayoutBoxModelObject::scrollableArea() const
+PaintLayerScrollableArea* LayoutBoxModelObject::getScrollableArea() const
 {
-    return m_layer ? m_layer->scrollableArea() : 0;
+    return m_layer ? m_layer->getScrollableArea() : 0;
 }
 
 void LayoutBoxModelObject::addLayerHitTestRects(LayerHitTestRects& rects, const PaintLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const
@@ -839,7 +839,7 @@
     }
     x = std::min(x, (maxX - caretWidth()).clampNegativeToZero());
 
-    LayoutUnit height = LayoutUnit(style()->fontMetrics().height());
+    LayoutUnit height = LayoutUnit(style()->getFontMetrics().height());
     LayoutUnit verticalSpace = lineHeight(true, currentStyle.isHorizontalWritingMode() ? HorizontalLine : VerticalLine,  PositionOfInteriorLineBoxes) - height;
     LayoutUnit y = paddingTop() + borderTop() + (verticalSpace / 2);
     return currentStyle.isHorizontalWritingMode() ? LayoutRect(x, y, caretWidth(), height) : LayoutRect(y, x, height, caretWidth());
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
index 1301c75..497e748c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
@@ -157,7 +157,7 @@
 
     bool hasSelfPaintingLayer() const;
     PaintLayer* layer() const { return m_layer.get(); }
-    PaintLayerScrollableArea* scrollableArea() const;
+    PaintLayerScrollableArea* getScrollableArea() const;
 
     virtual void updateFromStyle();
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutImage.cpp b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
index 194897c2..a68042e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImage.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
@@ -247,7 +247,7 @@
         return false;
     // Check for image with alpha.
     TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(this, *m_imageResource->cachedImage()));
-    return m_imageResource->cachedImage()->image()->currentFrameKnownToBeOpaque(Image::PreCacheMetadata);
+    return m_imageResource->cachedImage()->getImage()->currentFrameKnownToBeOpaque(Image::PreCacheMetadata);
 }
 
 bool LayoutImage::computeBackgroundIsKnownToBeObscured() const
@@ -318,8 +318,8 @@
         return nullptr;
 
     ImageResource* cachedImage = m_imageResource->cachedImage();
-    if (cachedImage && cachedImage->image() && cachedImage->image()->isSVGImage())
-        return toSVGImage(cachedImage->image())->embeddedContentBox();
+    if (cachedImage && cachedImage->getImage() && cachedImage->getImage()->isSVGImage())
+        return toSVGImage(cachedImage->getImage())->embeddedContentBox();
 
     return nullptr;
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
index 2037457c..a873c99 100644
--- a/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutImageResource.cpp
@@ -84,7 +84,7 @@
     if (!m_cachedImage)
         return;
 
-    m_cachedImage->image()->resetAnimation();
+    m_cachedImage->getImage()->resetAnimation();
 
     m_layoutObject->setShouldDoFullPaintInvalidation();
 }
@@ -104,11 +104,11 @@
     if (!m_cachedImage)
         return Image::nullImage();
 
-    if (!m_cachedImage->image()->isSVGImage())
-        return m_cachedImage->image();
+    if (!m_cachedImage->getImage()->isSVGImage())
+        return m_cachedImage->getImage();
 
     KURL url;
-    SVGImage* svgImage = toSVGImage(m_cachedImage->image());
+    SVGImage* svgImage = toSVGImage(m_cachedImage->getImage());
     Node* node = m_layoutObject->node();
     if (node && node->isElementNode()) {
         const AtomicString& urlString = toElement(node)->imageSourceURL();
@@ -119,7 +119,7 @@
 
 bool LayoutImageResource::maybeAnimated() const
 {
-    Image* image = m_cachedImage ? m_cachedImage->image() : Image::nullImage();
+    Image* image = m_cachedImage ? m_cachedImage->getImage() : Image::nullImage();
     return image->maybeAnimated();
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
index c1337bf..897fc332 100644
--- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -212,14 +212,14 @@
         || (parentLayoutInline && parentStyle.verticalAlign() != VerticalAlignBaseline)
         || style()->verticalAlign() != VerticalAlignBaseline
         || style()->getTextEmphasisMark() != TextEmphasisMarkNone
-        || (checkFonts && (!parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(style()->font().fontMetrics())
+        || (checkFonts && (!parentStyle.font().getFontMetrics().hasIdenticalAscentDescentAndLineGap(style()->font().getFontMetrics())
         || parentStyle.lineHeight() != style()->lineHeight()));
 
     if (!alwaysCreateLineBoxesNew && checkFonts && document().styleEngine().usesFirstLineRules()) {
         // Have to check the first line style as well.
         const ComputedStyle& firstLineParentStyle = parent()->styleRef(true);
         const ComputedStyle& childStyle = styleRef(true);
-        alwaysCreateLineBoxesNew = !firstLineParentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics())
+        alwaysCreateLineBoxesNew = !firstLineParentStyle.font().getFontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().getFontMetrics())
         || childStyle.verticalAlign() != VerticalAlignBaseline
         || firstLineParentStyle.lineHeight() != childStyle.lineHeight();
     }
@@ -564,8 +564,8 @@
             LayoutBox* currBox = toLayoutBox(curr);
             if (currBox->inlineBoxWrapper()) {
                 RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root();
-                LayoutUnit logicalTop = rootBox.logicalTop() + (rootBox.getLineLayoutItem().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
-                LayoutUnit logicalHeight(container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height());
+                LayoutUnit logicalTop = rootBox.logicalTop() + (rootBox.getLineLayoutItem().style(rootBox.isFirstLineStyle())->font().getFontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().getFontMetrics().ascent());
+                LayoutUnit logicalHeight(container->style(rootBox.isFirstLineStyle())->font().getFontMetrics().height());
                 if (isHorizontal) {
                     yield(LayoutRect(LayoutUnit(currBox->inlineBoxWrapper()->x() - currBox->marginLeft()), LayoutUnit(logicalTop),
                         LayoutUnit(currBox->size().width() + currBox->marginWidth()), LayoutUnit(logicalHeight)));
@@ -582,8 +582,8 @@
             } else {
                 for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) {
                     RootInlineBox& rootBox = childLine->root();
-                    LayoutUnit logicalTop = rootBox.logicalTop() + (rootBox.getLineLayoutItem().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
-                    LayoutUnit logicalHeight(container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height());
+                    LayoutUnit logicalTop = rootBox.logicalTop() + (rootBox.getLineLayoutItem().style(rootBox.isFirstLineStyle())->font().getFontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().getFontMetrics().ascent());
+                    LayoutUnit logicalHeight(container->style(rootBox.isFirstLineStyle())->font().getFontMetrics().height());
                     if (isHorizontal) {
                         yield(LayoutRect(LayoutUnit(childLine->x() - childLine->marginLogicalLeft()),
                             logicalTop,
@@ -602,9 +602,9 @@
             for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox()) {
                 RootInlineBox& rootBox = childText->root();
                 LayoutUnit logicalTop = LayoutUnit(rootBox.logicalTop()
-                    + (rootBox.getLineLayoutItem().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent()
-                    - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent()));
-                LayoutUnit logicalHeight(container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height());
+                    + (rootBox.getLineLayoutItem().style(rootBox.isFirstLineStyle())->font().getFontMetrics().ascent()
+                    - container->style(rootBox.isFirstLineStyle())->font().getFontMetrics().ascent()));
+                LayoutUnit logicalHeight(container->style(rootBox.isFirstLineStyle())->font().getFontMetrics().height());
                 if (isHorizontal)
                     yield(LayoutRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight));
                 else
@@ -1257,7 +1257,7 @@
 int LayoutInline::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
     ASSERT(linePositionMode == PositionOnContainingLine);
-    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
+    const FontMetrics& fontMetrics = style(firstLine)->getFontMetrics();
     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutListBox.cpp b/third_party/WebKit/Source/core/layout/LayoutListBox.cpp
index 13548dbb..51f9e71 100644
--- a/third_party/WebKit/Source/core/layout/LayoutListBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutListBox.cpp
@@ -96,7 +96,7 @@
 
 LayoutUnit LayoutListBox::defaultItemHeight() const
 {
-    return LayoutUnit(style()->fontMetrics().height() + defaultPaddingBottom);
+    return LayoutUnit(style()->getFontMetrics().height() + defaultPaddingBottom);
 }
 
 LayoutUnit LayoutListBox::itemHeight() const
@@ -147,8 +147,8 @@
 {
     if (hasOverflowClip()) {
         ASSERT(layer());
-        ASSERT(layer()->scrollableArea());
-        layer()->scrollableArea()->scrollIntoView(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
+        ASSERT(layer()->getScrollableArea());
+        layer()->getScrollableArea()->scrollIntoView(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
index 0cc2c5c6..d540fa1 100644
--- a/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutListMarker.cpp
@@ -71,7 +71,7 @@
     // FIXME: This is a somewhat arbitrary default width. Generated images for markers really won't
     // become particularly useful until we support the CSS3 marker pseudoclass to allow control over
     // the width and height of the marker box.
-    LayoutUnit bulletWidth = style()->fontMetrics().ascent() / LayoutUnit(2);
+    LayoutUnit bulletWidth = style()->getFontMetrics().ascent() / LayoutUnit(2);
     return m_image->imageSize(this, style()->effectiveZoom(), LayoutSize(bulletWidth, bulletWidth));
 }
 
@@ -140,7 +140,7 @@
         setHeight(imageSize.height());
     } else {
         setLogicalWidth(minPreferredLogicalWidth());
-        setLogicalHeight(LayoutUnit(style()->fontMetrics().height()));
+        setLogicalHeight(LayoutUnit(style()->getFontMetrics().height()));
     }
 
     setMarginStart(LayoutUnit());
@@ -233,7 +233,7 @@
     case ListStyleCategory::None:
         break;
     case ListStyleCategory::Symbol:
-        logicalWidth = LayoutUnit((font.fontMetrics().ascent() * 2 / 3 + 1) / 2 + 2);
+        logicalWidth = LayoutUnit((font.getFontMetrics().ascent() * 2 / 3 + 1) / 2 + 2);
         break;
     case ListStyleCategory::Language:
         logicalWidth = getWidthOfTextWithSuffix();
@@ -250,7 +250,7 @@
 
 void LayoutListMarker::updateMargins()
 {
-    const FontMetrics& fontMetrics = style()->fontMetrics();
+    const FontMetrics& fontMetrics = style()->getFontMetrics();
 
     LayoutUnit marginStart;
     LayoutUnit marginEnd;
@@ -411,14 +411,14 @@
     case ListStyleCategory::Symbol: {
         // TODO(wkorman): Review and clean up/document the calculations below.
         // http://crbug.com/543193
-        const FontMetrics& fontMetrics = style()->fontMetrics();
+        const FontMetrics& fontMetrics = style()->getFontMetrics();
         int ascent = fontMetrics.ascent();
         int bulletWidth = (ascent * 2 / 3 + 1) / 2;
         relativeRect = IntRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth);
         }
         break;
     case ListStyleCategory::Language:
-        relativeRect = IntRect(0, 0, getWidthOfTextWithSuffix(), style()->font().fontMetrics().height());
+        relativeRect = IntRect(0, 0, getWidthOfTextWithSuffix(), style()->font().getFontMetrics().height());
         break;
     }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
index 18069a5..95802c0 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnSet.cpp
@@ -376,7 +376,7 @@
 {
     LayoutBlockFlow* parentBlock = multiColumnBlockFlow();
     if (parentBlock->style()->hasNormalColumnGap())
-        return LayoutUnit(parentBlock->style()->fontDescription().computedPixelSize()); // "1em" is recommended as the normal gap setting. Matches <p> margins.
+        return LayoutUnit(parentBlock->style()->getFontDescription().computedPixelSize()); // "1em" is recommended as the normal gap setting. Matches <p> margins.
     return LayoutUnit(parentBlock->style()->columnGap());
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 33b4a56e..ef6a026 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -1211,7 +1211,7 @@
     if (paintRect.isEmpty())
         return;
 
-    if (HostWindow* window = frameView->hostWindow())
+    if (HostWindow* window = frameView->getHostWindow())
         window->invalidateRect(frameView->contentsToRootFrame(paintRect));
 }
 
@@ -2769,7 +2769,7 @@
 
     // Walk up the layer tree to clear any scroll anchors that reference us.
     while (layer) {
-        if (PaintLayerScrollableArea* scrollableArea = layer->scrollableArea()) {
+        if (PaintLayerScrollableArea* scrollableArea = layer->getScrollableArea()) {
             ScrollAnchor& anchor = scrollableArea->scrollAnchor();
             if (anchor.anchorObject() == layoutObject) {
                 found = true;
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
index b06405ef..ed38b36 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
@@ -212,7 +212,7 @@
     }
 
     // This LayoutScrollbarPart belongs to a PaintLayerScrollableArea.
-    toLayoutBox(parent())->scrollableArea()->setScrollCornerNeedsPaintInvalidation();
+    toLayoutBox(parent())->getScrollableArea()->setScrollCornerNeedsPaintInvalidation();
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutText.cpp b/third_party/WebKit/Source/core/layout/LayoutText.cpp
index c32c99aa..1ff2599 100644
--- a/third_party/WebKit/Source/core/layout/LayoutText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutText.cpp
@@ -794,7 +794,7 @@
             float spaceWidth = font.width(run);
             floatMaxWidth -= spaceWidth;
         } else {
-            floatMaxWidth += font.fontDescription().wordSpacing();
+            floatMaxWidth += font.getFontDescription().wordSpacing();
         }
     }
 
@@ -1006,7 +1006,7 @@
             // Non-zero only when kerning is enabled, in which case we measure words with their trailing
             // space, then subtract its width.
             float wordTrailingSpaceWidth = 0;
-            if (isSpace && (f.fontDescription().getTypesettingFeatures() & Kerning)) {
+            if (isSpace && (f.getFontDescription().getTypesettingFeatures() & Kerning)) {
                 ASSERT(textDirection >=0 && textDirection <= 1);
                 if (!cachedWordTrailingSpaceWidth[textDirection])
                     cachedWordTrailingSpaceWidth[textDirection] = f.width(constructTextRun(f, &spaceCharacter, 1, styleToUse, textDirection)) + wordSpacing;
@@ -1110,7 +1110,7 @@
     }
 
     GlyphOverflow glyphOverflow;
-    glyphOverflow.setFromBounds(glyphBounds, f.fontMetrics().floatAscent(), f.fontMetrics().floatDescent(), m_maxWidth);
+    glyphOverflow.setFromBounds(glyphBounds, f.getFontMetrics().floatAscent(), f.getFontMetrics().floatDescent(), m_maxWidth);
     // We shouldn't change our mind once we "know".
     ASSERT(!m_knownToHaveNoOverflowAndNoFallbackFonts || (fallbackFonts.isEmpty() && glyphOverflow.isApproximatelyZero()));
     m_knownToHaveNoOverflowAndNoFallbackFonts = fallbackFonts.isEmpty() && glyphOverflow.isApproximatelyZero();
@@ -1500,7 +1500,7 @@
                 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts)
                     const_cast<LayoutText*>(this)->computePreferredLogicalWidths(0, *fallbackFonts, *glyphBounds);
                 else
-                    *glyphBounds = FloatRect(0, -f.fontMetrics().floatAscent(), m_maxWidth, f.fontMetrics().floatHeight());
+                    *glyphBounds = FloatRect(0, -f.getFontMetrics().floatAscent(), m_maxWidth, f.getFontMetrics().floatHeight());
                 w = m_maxWidth;
             } else {
                 w = maxLogicalWidth();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextCombine.cpp b/third_party/WebKit/Source/core/layout/LayoutTextCombine.cpp
index 37b5828..1f9f8aa 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextCombine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextCombine.cpp
@@ -60,7 +60,7 @@
         return 0;
 
     if (m_isCombined)
-        return font.fontDescription().computedSize();
+        return font.getFontDescription().computedSize();
 
     return LayoutText::width(from, length, font, xPosition, direction, fallbackFonts, glyphBounds);
 }
@@ -132,7 +132,7 @@
 
     unsigned offset = 0;
     TextRun run = constructTextRun(originalFont(), this, offset, textLength(), styleRef(), style()->direction());
-    FontDescription description = originalFont().fontDescription();
+    FontDescription description = originalFont().getFontDescription();
     float emWidth = description.computedSize();
     if (!(style()->textDecorationsInEffect() & (TextDecorationUnderline | TextDecorationOverline)))
         emWidth *= textCombineMargin;
@@ -140,7 +140,7 @@
     description.setOrientation(FontOrientation::Horizontal); // We are going to draw combined text horizontally.
     m_combinedTextWidth = originalFont().width(run);
 
-    FontSelector* fontSelector = style()->font().fontSelector();
+    FontSelector* fontSelector = style()->font().getFontSelector();
 
     bool shouldUpdateFont = mutableStyleRef().setFontDescription(description); // Need to change font orientation to horizontal.
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextCombine.h b/third_party/WebKit/Source/core/layout/LayoutTextCombine.h
index e704b4c5..dd852fb 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextCombine.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTextCombine.h
@@ -35,7 +35,7 @@
 
     void updateFont();
     bool isCombined() const { return m_isCombined; }
-    float combinedTextWidth(const Font& font) const { return font.fontDescription().computedSize(); }
+    float combinedTextWidth(const Font& font) const { return font.getFontDescription().computedSize(); }
     const Font& originalFont() const { return parent()->style()->font(); }
     void transformToInlineCoordinates(GraphicsContext&, const LayoutRect& boxRect, bool clip = false) const;
     LayoutUnit inlineWidthForLayout() const;
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
index 9fb9c4e..470f1531 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextControl.cpp
@@ -227,13 +227,13 @@
 {
     // This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
     float unitsPerEm = 2048.0f;
-    return roundf(style()->font().fontDescription().computedSize() * x / unitsPerEm);
+    return roundf(style()->font().getFontDescription().computedSize() * x / unitsPerEm);
 }
 
 void LayoutTextControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
 {
     // Use average character width. Matches IE.
-    AtomicString family = style()->font().fontDescription().family().family();
+    AtomicString family = style()->font().getFontDescription().family().family();
     maxLogicalWidth = preferredContentLogicalWidth(const_cast<LayoutTextControl*>(this)->getAvgCharWidth(family));
     if (LayoutBox* innerEditorLayoutBox = innerEditorElement()->layoutBox())
         maxLogicalWidth += innerEditorLayoutBox->paddingStart() + innerEditorLayoutBox->paddingEnd();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
index df2aee28..820c0a70e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTextControlSingleLine.cpp
@@ -231,7 +231,7 @@
     LayoutUnit result = LayoutUnit::fromFloatCeil(charWidth * factor);
 
     float maxCharWidth = 0.f;
-    AtomicString family = styleRef().font().fontDescription().family().family();
+    AtomicString family = styleRef().font().getFontDescription().family().family();
     // Match the default system font to the width of MS Shell Dlg, the default
     // font for textareas in Firefox, Safari Win and IE for some encodings (in
     // IE, the default font is encoding specific). 4027 is the (xMax - xMin)
diff --git a/third_party/WebKit/Source/core/layout/LayoutTheme.cpp b/third_party/WebKit/Source/core/layout/LayoutTheme.cpp
index 1d494106..0ce8b4e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTheme.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTheme.cpp
@@ -117,7 +117,7 @@
         case ButtonPart: {
             // Border
             LengthBox borderBox(style.borderTopWidth(), style.borderRightWidth(), style.borderBottomWidth(), style.borderLeftWidth());
-            borderBox = m_platformTheme->controlBorder(part, style.font().fontDescription(), borderBox, style.effectiveZoom());
+            borderBox = m_platformTheme->controlBorder(part, style.font().getFontDescription(), borderBox, style.effectiveZoom());
             if (borderBox.top().value() != static_cast<int>(style.borderTopWidth())) {
                 if (borderBox.top().value())
                     style.setBorderTopWidth(borderBox.top().value());
@@ -146,7 +146,7 @@
             }
 
             // Padding
-            LengthBox paddingBox = m_platformTheme->controlPadding(part, style.font().fontDescription(), style.paddingBox(), style.effectiveZoom());
+            LengthBox paddingBox = m_platformTheme->controlPadding(part, style.font().getFontDescription(), style.paddingBox(), style.effectiveZoom());
             if (paddingBox != style.paddingBox())
                 style.setPaddingBox(paddingBox);
 
@@ -157,22 +157,22 @@
             // Width / Height
             // The width and height here are affected by the zoom.
             // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
-            LengthSize controlSize = m_platformTheme->controlSize(part, style.font().fontDescription(), LengthSize(style.width(), style.height()), style.effectiveZoom());
+            LengthSize controlSize = m_platformTheme->controlSize(part, style.font().getFontDescription(), LengthSize(style.width(), style.height()), style.effectiveZoom());
             if (controlSize.width() != style.width())
                 style.setWidth(controlSize.width());
             if (controlSize.height() != style.height())
                 style.setHeight(controlSize.height());
 
             // Min-Width / Min-Height
-            LengthSize minControlSize = m_platformTheme->minimumControlSize(part, style.font().fontDescription(), style.effectiveZoom());
+            LengthSize minControlSize = m_platformTheme->minimumControlSize(part, style.font().getFontDescription(), style.effectiveZoom());
             if (minControlSize.width() != style.minWidth())
                 style.setMinWidth(minControlSize.width());
             if (minControlSize.height() != style.minHeight())
                 style.setMinHeight(minControlSize.height());
 
             // Font
-            FontDescription controlFont = m_platformTheme->controlFont(part, style.font().fontDescription(), style.effectiveZoom());
-            if (controlFont != style.font().fontDescription()) {
+            FontDescription controlFont = m_platformTheme->controlFont(part, style.font().getFontDescription(), style.effectiveZoom());
+            if (controlFont != style.font().getFontDescription()) {
                 // Reset our line-height
                 style.setLineHeight(ComputedStyle::initialLineHeight());
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm b/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
index 27649cc..ce4beb4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
+++ b/third_party/WebKit/Source/core/layout/LayoutThemeMac.mm
@@ -611,7 +611,7 @@
     style.setLineHeight(ComputedStyle::initialLineHeight());
 
     // TODO(esprehn): The fontSelector manual management is buggy and error prone.
-    FontSelector* fontSelector = style.font().fontSelector();
+    FontSelector* fontSelector = style.font().getFontSelector();
     if (style.setFontDescription(fontDescription))
         style.font().update(fontSelector);
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
index 4b40c57..985b2d01 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTreeAsText.cpp
@@ -600,7 +600,7 @@
         if (reportFrameScrollInfo)
             scrollableArea = toLayoutView(layer.layoutObject())->frameView();
         else
-            scrollableArea = layer.scrollableArea();
+            scrollableArea = layer.getScrollableArea();
 
         DoublePoint adjustedScrollOffset = scrollableArea->scrollPositionDouble() + toDoubleSize(scrollableArea->scrollOrigin());
         if (adjustedScrollOffset.x())
diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp
index 205b3c6..0f7a5e0 100644
--- a/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp
+++ b/third_party/WebKit/Source/core/layout/ScrollAnchorTest.cpp
@@ -31,7 +31,7 @@
 
     ScrollableArea* scrollerForElement(Element* element)
     {
-        return toLayoutBox(element->layoutObject())->scrollableArea();
+        return toLayoutBox(element->layoutObject())->getScrollableArea();
     }
 
     ScrollAnchor& scrollAnchor(ScrollableArea* scroller)
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index e555738..8a80122 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -737,8 +737,8 @@
     updateScrollingLayerGeometry(localCompositingBounds);
     updateChildClippingMaskLayerGeometry();
 
-    if (m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->scrollsOverflow())
-        m_owningLayer.scrollableArea()->positionOverflowControls();
+    if (m_owningLayer.getScrollableArea() && m_owningLayer.getScrollableArea()->scrollsOverflow())
+        m_owningLayer.getScrollableArea()->positionOverflowControls();
 
     if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
         updateLayerBlendMode(layoutObject()->styleRef());
@@ -804,7 +804,7 @@
     if (compositingContainer && compositingContainer->needsCompositedScrolling()) {
         LayoutBox* layoutBox = toLayoutBox(compositingContainer->layoutObject());
         IntSize scrollOffset = layoutBox->scrolledContentOffset();
-        IntPoint scrollOrigin = compositingContainer->scrollableArea()->scrollOrigin();
+        IntPoint scrollOrigin = compositingContainer->getScrollableArea()->scrollOrigin();
         scrollOrigin.move(-layoutBox->borderLeft(), -layoutBox->borderTop());
         graphicsLayerParentLocation = -(scrollOrigin + scrollOffset);
     }
@@ -857,7 +857,7 @@
             m_owningLayer.layoutObject()->mapLocalToAncestor(compositingStackingContext->layoutObject(), transformState, ApplyContainerFlip);
             transformState.flatten();
             hostLayerPosition = LayoutPoint(transformState.lastPlanarPoint());
-            if (PaintLayerScrollableArea* scrollableArea = compositingStackingContext->scrollableArea())
+            if (PaintLayerScrollableArea* scrollableArea = compositingStackingContext->getScrollableArea())
                 hostLayerPosition.move(LayoutSize(scrollableArea->adjustedScrollOffset()));
         }
     }
@@ -965,7 +965,7 @@
     ASSERT(m_scrollingContentsLayer);
     LayoutBox* layoutBox = toLayoutBox(layoutObject());
     IntRect overflowClipRect = enclosingIntRect(layoutBox->overflowClipRect(LayoutPoint()));
-    DoubleSize adjustedScrollOffset = m_owningLayer.scrollableArea()->adjustedScrollOffset();
+    DoubleSize adjustedScrollOffset = m_owningLayer.getScrollableArea()->adjustedScrollOffset();
     m_scrollingLayer->setPosition(FloatPoint(overflowClipRect.location() - localCompositingBounds.location() + roundedIntSize(m_owningLayer.subpixelAccumulation())));
     m_scrollingLayer->setSize(FloatSize(overflowClipRect.size()));
 
@@ -1309,7 +1309,7 @@
         return false;
     layer = needsLayer ? createGraphicsLayer(reason) : nullptr;
 
-    if (PaintLayerScrollableArea* scrollableArea = m_owningLayer.scrollableArea()) {
+    if (PaintLayerScrollableArea* scrollableArea = m_owningLayer.getScrollableArea()) {
         if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
             if (reason == CompositingReasonLayerForHorizontalScrollbar)
                 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(scrollableArea, HorizontalScrollbar);
@@ -1322,7 +1322,7 @@
 
 bool CompositedLayerMapping::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer, bool needsAncestorClip)
 {
-    if (PaintLayerScrollableArea* scrollableArea = m_owningLayer.scrollableArea()) {
+    if (PaintLayerScrollableArea* scrollableArea = m_owningLayer.getScrollableArea()) {
         // If the scrollable area is marked as needing a new scrollbar layer,
         // destroy the layer now so that it will be created again below.
         if (m_layerForHorizontalScrollbar && needsHorizontalScrollbarLayer && scrollableArea->shouldRebuildHorizontalScrollbarLayer())
@@ -1353,7 +1353,7 @@
 void CompositedLayerMapping::positionOverflowControlsLayers()
 {
     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
-        Scrollbar* hBar = m_owningLayer.scrollableArea()->horizontalScrollbar();
+        Scrollbar* hBar = m_owningLayer.getScrollableArea()->horizontalScrollbar();
         if (hBar) {
             layer->setPosition(hBar->frameRect().location());
             layer->setSize(FloatSize(hBar->frameRect().size()));
@@ -1364,7 +1364,7 @@
     }
 
     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
-        Scrollbar* vBar = m_owningLayer.scrollableArea()->verticalScrollbar();
+        Scrollbar* vBar = m_owningLayer.getScrollableArea()->verticalScrollbar();
         if (vBar) {
             layer->setPosition(vBar->frameRect().location());
             layer->setSize(FloatSize(vBar->frameRect().size()));
@@ -1375,7 +1375,7 @@
     }
 
     if (GraphicsLayer* layer = layerForScrollCorner()) {
-        const IntRect& scrollCornerAndResizer = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect();
+        const IntRect& scrollCornerAndResizer = m_owningLayer.getScrollableArea()->scrollCornerAndResizerRect();
         layer->setPosition(FloatPoint(scrollCornerAndResizer.location()));
         layer->setSize(FloatSize(scrollCornerAndResizer.size()));
         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
@@ -1614,7 +1614,7 @@
 
             layerChanged = true;
             if (scrollingCoordinator) {
-                scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
+                scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.getScrollableArea());
                 scrollingCoordinator->scrollableAreasDidChange();
             }
         }
@@ -1623,7 +1623,7 @@
         m_scrollingContentsLayer = nullptr;
         layerChanged = true;
         if (scrollingCoordinator) {
-            scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
+            scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.getScrollableArea());
             scrollingCoordinator->scrollableAreasDidChange();
         }
     }
@@ -1885,7 +1885,7 @@
         if (!cachedImage->hasImage())
             return false;
 
-        Image* image = cachedImage->image();
+        Image* image = cachedImage->getImage();
         if (!image->isBitmapImage())
             return false;
 
@@ -1917,7 +1917,7 @@
     if (!cachedImage)
         return;
 
-    Image* image = cachedImage->image();
+    Image* image = cachedImage->getImage();
     if (!image)
         return;
 
@@ -1964,9 +1964,9 @@
 
 bool CompositedLayerMapping::needsToReparentOverflowControls() const
 {
-    return m_owningLayer.scrollableArea()
-        && m_owningLayer.scrollableArea()->hasOverlayScrollbars()
-        && m_owningLayer.scrollableArea()->topmostScrollChild();
+    return m_owningLayer.getScrollableArea()
+        && m_owningLayer.getScrollableArea()->hasOverlayScrollbars()
+        && m_owningLayer.getScrollableArea()->topmostScrollChild();
 }
 
 GraphicsLayer* CompositedLayerMapping::detachLayerForOverflowControls(const PaintLayer& enclosingLayer)
@@ -2171,10 +2171,10 @@
         // FIXME: Is it correct to clip to dirtyRect in slimming paint mode?
         // FIXME: Combine similar code here and LayerClipRecorder.
         dirtyRect.intersect(paintInfo.localClipRectForSquashedLayer);
-        context.paintController().createAndAppend<ClipDisplayItem>(graphicsLayer, DisplayItem::ClipLayerOverflowControls, dirtyRect);
+        context.getPaintController().createAndAppend<ClipDisplayItem>(graphicsLayer, DisplayItem::ClipLayerOverflowControls, dirtyRect);
 
         PaintLayerPainter(*paintInfo.paintLayer).paintLayer(context, paintingInfo, paintLayerFlags);
-        context.paintController().endItem<EndClipDisplayItem>(graphicsLayer, DisplayItem::clipTypeToEndClipType(DisplayItem::ClipLayerOverflowControls));
+        context.getPaintController().endItem<EndClipDisplayItem>(graphicsLayer, DisplayItem::clipTypeToEndClipType(DisplayItem::ClipLayerOverflowControls));
     }
 }
 
@@ -2365,14 +2365,14 @@
         for (size_t i = 0; i < m_squashedLayers.size(); ++i)
             doPaintTask(m_squashedLayers[i], *graphicsLayer, paintLayerFlags, context, interestRect);
     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
-        paintScrollbar(m_owningLayer.scrollableArea()->horizontalScrollbar(), context, interestRect);
+        paintScrollbar(m_owningLayer.getScrollableArea()->horizontalScrollbar(), context, interestRect);
     } else if (graphicsLayer == layerForVerticalScrollbar()) {
-        paintScrollbar(m_owningLayer.scrollableArea()->verticalScrollbar(), context, interestRect);
+        paintScrollbar(m_owningLayer.getScrollableArea()->verticalScrollbar(), context, interestRect);
     } else if (graphicsLayer == layerForScrollCorner()) {
-        IntPoint scrollCornerAndResizerLocation = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().location();
+        IntPoint scrollCornerAndResizerLocation = m_owningLayer.getScrollableArea()->scrollCornerAndResizerRect().location();
         CullRect cullRect(enclosingIntRect(interestRect));
-        ScrollableAreaPainter(*m_owningLayer.scrollableArea()).paintScrollCorner(context, -scrollCornerAndResizerLocation, cullRect);
-        ScrollableAreaPainter(*m_owningLayer.scrollableArea()).paintResizer(context, -scrollCornerAndResizerLocation, cullRect);
+        ScrollableAreaPainter(*m_owningLayer.getScrollableArea()).paintScrollCorner(context, -scrollCornerAndResizerLocation, cullRect);
+        ScrollableAreaPainter(*m_owningLayer.getScrollableArea()).paintResizer(context, -scrollCornerAndResizerLocation, cullRect);
     }
     InspectorInstrumentation::didPaint(m_owningLayer.layoutObject(), graphicsLayer, context, LayoutRect(interestRect));
 #if ENABLE(ASSERT)
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index b4288e7..76c99ceb 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -254,9 +254,9 @@
     bool updateBackgroundLayer(bool needsBackgroundLayer);
     bool updateMaskLayer(bool needsMaskLayer);
     void updateChildClippingMaskLayer(bool needsChildClippingMaskLayer);
-    bool requiresHorizontalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->horizontalScrollbar(); }
-    bool requiresVerticalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->verticalScrollbar(); }
-    bool requiresScrollCornerLayer() const { return m_owningLayer.scrollableArea() && !m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
+    bool requiresHorizontalScrollbarLayer() const { return m_owningLayer.getScrollableArea() && m_owningLayer.getScrollableArea()->horizontalScrollbar(); }
+    bool requiresVerticalScrollbarLayer() const { return m_owningLayer.getScrollableArea() && m_owningLayer.getScrollableArea()->verticalScrollbar(); }
+    bool requiresScrollCornerLayer() const { return m_owningLayer.getScrollableArea() && !m_owningLayer.getScrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
     bool updateScrollingLayers(bool scrollingLayers);
     void updateScrollParent(const PaintLayer*);
     void updateClipParent(const PaintLayer* scrollParent);
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp
index 51f2e62..c832901 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp
@@ -299,10 +299,10 @@
     }
 
     if (layer->scrollParent())
-        layer->scrollParent()->scrollableArea()->setTopmostScrollChild(layer);
+        layer->scrollParent()->getScrollableArea()->setTopmostScrollChild(layer);
 
     if (layer->needsCompositedScrolling())
-        layer->scrollableArea()->setTopmostScrollChild(nullptr);
+        layer->getScrollableArea()->setTopmostScrollChild(nullptr);
 
     PaintLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
     while (PaintLayerStackingNode* curNode = iterator.next())
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
index d84cf874..8ae2819 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
@@ -248,7 +248,7 @@
             // both opaque and may only have an integer translation as its
             // transform. Both opacity and screen space transform are inherited
             // properties, so this cannot be determined from local information.
-            layer->scrollableArea()->updateNeedsCompositedScrolling(PaintLayerScrollableArea::IgnoreLCDText);
+            layer->getScrollableArea()->updateNeedsCompositedScrolling(PaintLayerScrollableArea::IgnoreLCDText);
             if (layer->needsCompositedScrolling())
                 reasonsToComposite |= CompositingReasonOverflowScrollingTouch;
         }
diff --git a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp
index 73c1782e..4a5a437 100644
--- a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerTreeBuilder.cpp
@@ -108,7 +108,7 @@
     if (layer.scrollParent()
         && layer.scrollParent()->hasCompositedLayerMapping()
         && layer.scrollParent()->compositedLayerMapping()->needsToReparentOverflowControls()
-        && layer.scrollParent()->scrollableArea()->topmostScrollChild() == &layer)
+        && layer.scrollParent()->getScrollableArea()->topmostScrollChild() == &layer)
         info.childLayersOfEnclosingCompositedLayer->append(layer.scrollParent()->compositedLayerMapping()->detachLayerForOverflowControls(*info.enclosingCompositedLayer));
 }
 
diff --git a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp
index e84417a..2f402c24 100644
--- a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp
@@ -99,7 +99,7 @@
                 m_needsRebuildTree = true;
 
             mapping->updateGraphicsLayerGeometry(compositingContainer, context.compositingStackingContext(), layersNeedingPaintInvalidation);
-            if (PaintLayerScrollableArea* scrollableArea = layer.scrollableArea())
+            if (PaintLayerScrollableArea* scrollableArea = layer.getScrollableArea())
                 scrollableArea->positionOverflowControls();
             updateType = mapping->updateTypeForChildren(updateType);
             mapping->clearNeedsGraphicsLayerUpdate();
diff --git a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
index 0635acd1..fe5bff3 100644
--- a/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/PaintLayerCompositor.cpp
@@ -232,7 +232,7 @@
 
     DocumentAnimations::updateCompositorAnimations(m_layoutView.document());
 
-    m_layoutView.frameView()->scrollableArea()->updateCompositorScrollAnimations();
+    m_layoutView.frameView()->getScrollableArea()->updateCompositorScrollAnimations();
     if (const FrameView::ScrollableAreaSet* animatingScrollableAreas = m_layoutView.frameView()->animatingScrollableAreas()) {
         for (ScrollableArea* scrollableArea : *animatingScrollableAreas)
             scrollableArea->updateCompositorScrollAnimations();
@@ -623,7 +623,7 @@
 bool PaintLayerCompositor::scrollingLayerDidChange(PaintLayer* layer)
 {
     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-        return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
+        return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->getScrollableArea());
     return false;
 }
 
@@ -707,7 +707,7 @@
 
 GraphicsLayer* PaintLayerCompositor::scrollLayer() const
 {
-    if (ScrollableArea* scrollableArea = m_layoutView.frameView()->scrollableArea())
+    if (ScrollableArea* scrollableArea = m_layoutView.frameView()->getScrollableArea())
         return scrollableArea->layerForScrolling();
     return nullptr;
 }
diff --git a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
index f5a1e42..66ed841 100644
--- a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
+++ b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
@@ -185,7 +185,7 @@
     if (flow.document().inNoQuirksMode()
         && (flow.style(lineInfo.isFirstLine())->lineHeight() != parent.style(lineInfo.isFirstLine())->lineHeight()
         || flow.style()->verticalAlign() != parent.style()->verticalAlign()
-        || !parent.style()->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(flow.style()->font().fontMetrics())))
+        || !parent.style()->font().getFontMetrics().hasIdenticalAscentDescentAndLineGap(flow.style()->font().getFontMetrics())))
         return true;
     return false;
 }
@@ -602,7 +602,7 @@
 
     // Non-zero only when kerning is enabled, in which case we measure
     // words with their trailing space, then subtract its width.
-    float wordTrailingSpaceWidth = (font.fontDescription().getTypesettingFeatures() & Kerning) ?
+    float wordTrailingSpaceWidth = (font.getFontDescription().getTypesettingFeatures() & Kerning) ?
         font.width(constructTextRun(font, &spaceCharacter, 1, style, style.direction())) + wordSpacing
         : 0;
 
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
index 51644d2d..3f3c4566 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
@@ -144,13 +144,13 @@
         return virtualLogicalHeight();
 
     if (getLineLayoutItem().isText())
-        return m_bitfields.isText() ? LayoutUnit(getLineLayoutItem().style(isFirstLineStyle())->fontMetrics().height()) : LayoutUnit();
+        return m_bitfields.isText() ? LayoutUnit(getLineLayoutItem().style(isFirstLineStyle())->getFontMetrics().height()) : LayoutUnit();
     if (getLineLayoutItem().isBox() && parent())
         return isHorizontal() ? toLayoutBox(layoutObject()).size().height() : toLayoutBox(layoutObject()).size().width();
 
     ASSERT(isInlineFlowBox());
     LineLayoutBoxModel flowObject = boxModelObject();
-    const FontMetrics& fontMetrics = getLineLayoutItem().style(isFirstLineStyle())->fontMetrics();
+    const FontMetrics& fontMetrics = getLineLayoutItem().style(isFirstLineStyle())->getFontMetrics();
     LayoutUnit result(fontMetrics.height());
     if (parent())
         result += flowObject.borderAndPaddingLogicalHeight();
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index f4412ee..26508e0 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -123,7 +123,7 @@
             shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
         } else if (child->isText()) {
             if (child->getLineLayoutItem().isBR() || (child->getLineLayoutItem().parent() != getLineLayoutItem())) {
-                if (!parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics())
+                if (!parentStyle.font().getFontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().getFontMetrics())
                     || parentStyle.lineHeight() != childStyle.lineHeight()
                     || (parentStyle.verticalAlign() != VerticalAlignBaseline && !isRootInlineBox()) || childStyle.verticalAlign() != VerticalAlignBaseline)
                     shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
@@ -140,7 +140,7 @@
                 InlineFlowBox* childFlowBox = toInlineFlowBox(child);
                 // Check the child's bit, and then also check for differences in font, line-height, vertical-align
                 if (!childFlowBox->descendantsHaveSameLineHeightAndBaseline()
-                    || !parentStyle.font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().fontMetrics())
+                    || !parentStyle.font().getFontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.font().getFontMetrics())
                     || parentStyle.lineHeight() != childStyle.lineHeight()
                     || (parentStyle.verticalAlign() != VerticalAlignBaseline && !isRootInlineBox()) || childStyle.verticalAlign() != VerticalAlignBaseline
                     || childStyle.hasBorder() || childStyle.hasPadding() || childStyle.hasTextCombine())
@@ -389,7 +389,7 @@
             LayoutUnit space;
             if (rt.textLength()) {
                 if (needsWordSpacing && isSpaceOrNewline(rt.characterAt(text->start())))
-                    space = LayoutUnit(rt.style(isFirstLineStyle())->font().fontDescription().wordSpacing());
+                    space = LayoutUnit(rt.style(isFirstLineStyle())->font().getFontDescription().wordSpacing());
                 needsWordSpacing = !isSpaceOrNewline(rt.characterAt(text->end()));
             }
             if (isLeftToRightDirection()) {
@@ -458,7 +458,7 @@
 {
     // Use "central" (Ideographic) baseline if writing-mode is vertical-* and text-orientation is not sideways-*.
     // http://dev.w3.org/csswg/css-writing-modes-3/#text-baselines
-    if (!isHorizontal() && getLineLayoutItem().style(isFirstLineStyle())->fontDescription().isVerticalAnyUpright())
+    if (!isHorizontal() && getLineLayoutItem().style(isFirstLineStyle())->getFontDescription().isVerticalAnyUpright())
         return IdeographicBaseline;
     return AlphabeticBaseline;
 }
@@ -583,7 +583,7 @@
 {
     bool isRootBox = isRootInlineBox();
     if (isRootBox) {
-        const FontMetrics& fontMetrics = getLineLayoutItem().style(isFirstLineStyle())->fontMetrics();
+        const FontMetrics& fontMetrics = getLineLayoutItem().style(isFirstLineStyle())->getFontMetrics();
         // RootInlineBoxes are always placed at pixel boundaries in their logical y direction. Not doing
         // so results in incorrect layout of text decorations, most notably underlines.
         setLogicalTop(LayoutUnit(roundToInt(top + maxAscent - fontMetrics.ascent(baselineType))));
@@ -625,7 +625,7 @@
         LayoutUnit boxHeightIncludingMargins = boxHeight;
         LayoutUnit borderPaddingHeight;
         if (curr->isText() || curr->isInlineFlowBox()) {
-            const FontMetrics& fontMetrics = curr->getLineLayoutItem().style(isFirstLineStyle())->fontMetrics();
+            const FontMetrics& fontMetrics = curr->getLineLayoutItem().style(isFirstLineStyle())->getFontMetrics();
             newLogicalTop += curr->baselinePosition(baselineType) - fontMetrics.ascent(baselineType);
             if (curr->isInlineFlowBox()) {
                 LineLayoutBoxModel boxObject = LineLayoutBoxModel(curr->getLineLayoutItem());
@@ -843,7 +843,7 @@
 
     // If letter-spacing is negative, we should factor that into right layout overflow. Even in RTL, letter-spacing is
     // applied to the right, so this is not an issue with left overflow.
-    rightGlyphOverflow -= std::min(0.0f, style.font().fontDescription().letterSpacing());
+    rightGlyphOverflow -= std::min(0.0f, style.font().getFontDescription().letterSpacing());
 
     LayoutRectOutsets textShadowLogicalOutsets;
     if (ShadowList* textShadow = style.textShadow())
diff --git a/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp b/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
index dfac26e..d25f755 100644
--- a/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/RootInlineBox.cpp
@@ -573,7 +573,7 @@
     if (usedFonts && !usedFonts->isEmpty() && (box->getLineLayoutItem().style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading)) {
         usedFonts->append(box->getLineLayoutItem().style(isFirstLineStyle())->font().primaryFont());
         for (size_t i = 0; i < usedFonts->size(); ++i) {
-            const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics();
+            const FontMetrics& fontMetrics = usedFonts->at(i)->getFontMetrics();
             int usedFontAscent = fontMetrics.ascent(baselineType());
             int usedFontDescent = fontMetrics.descent(baselineType());
             int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height()) / 2;
@@ -639,8 +639,8 @@
 
     if (verticalAlign != VerticalAlignBaseline) {
         const Font& font = parent.style(firstLine)->font();
-        const FontMetrics& fontMetrics = font.fontMetrics();
-        int fontSize = font.fontDescription().computedPixelSize();
+        const FontMetrics& fontMetrics = font.getFontMetrics();
+        int fontSize = font.getFontDescription().computedPixelSize();
 
         LineDirectionMode lineDirection = parent.isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
 
diff --git a/third_party/WebKit/Source/core/layout/shapes/BoxShape.cpp b/third_party/WebKit/Source/core/layout/shapes/BoxShape.cpp
index 5d53809..b94c840b 100644
--- a/third_party/WebKit/Source/core/layout/shapes/BoxShape.cpp
+++ b/third_party/WebKit/Source/core/layout/shapes/BoxShape.cpp
@@ -97,9 +97,9 @@
 
 void BoxShape::buildDisplayPaths(DisplayPaths& paths) const
 {
-    paths.shape.addRoundedRect(m_bounds.rect(), m_bounds.radii().topLeft(), m_bounds.radii().topRight(), m_bounds.radii().bottomLeft(), m_bounds.radii().bottomRight());
+    paths.shape.addRoundedRect(m_bounds.rect(), m_bounds.getRadii().topLeft(), m_bounds.getRadii().topRight(), m_bounds.getRadii().bottomLeft(), m_bounds.getRadii().bottomRight());
     if (shapeMargin())
-        paths.marginShape.addRoundedRect(shapeMarginBounds().rect(), shapeMarginBounds().radii().topLeft(), shapeMarginBounds().radii().topRight(), shapeMarginBounds().radii().bottomLeft(), shapeMarginBounds().radii().bottomRight());
+        paths.marginShape.addRoundedRect(shapeMarginBounds().rect(), shapeMarginBounds().getRadii().topLeft(), shapeMarginBounds().getRadii().topRight(), shapeMarginBounds().getRadii().bottomLeft(), shapeMarginBounds().getRadii().bottomRight());
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/shapes/Shape.cpp b/third_party/WebKit/Source/core/layout/shapes/Shape.cpp
index cefa46b..bd49b75 100644
--- a/third_party/WebKit/Source/core/layout/shapes/Shape.cpp
+++ b/third_party/WebKit/Source/core/layout/shapes/Shape.cpp
@@ -243,7 +243,7 @@
 PassOwnPtr<Shape> Shape::createLayoutBoxShape(const FloatRoundedRect& roundedRect, WritingMode writingMode, float margin)
 {
     FloatRect rect(0, 0, roundedRect.rect().width(), roundedRect.rect().height());
-    FloatRoundedRect bounds(rect, roundedRect.radii());
+    FloatRoundedRect bounds(rect, roundedRect.getRadii());
     OwnPtr<Shape> shape = createInsetShape(bounds);
     shape->m_writingMode = writingMode;
     shape->m_margin = margin;
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
index 6867fe7..7c8d826 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp
@@ -157,7 +157,7 @@
         return createPositionWithAffinity(0);
 
     ASSERT(m_scalingFactor);
-    float baseline = m_scaledFont.fontMetrics().floatAscent() / m_scalingFactor;
+    float baseline = m_scaledFont.getFontMetrics().floatAscent() / m_scalingFactor;
 
     LayoutBlock* containingBlock = this->containingBlock();
     ASSERT(containingBlock);
@@ -218,10 +218,10 @@
         return;
     }
 
-    if (style->fontDescription().textRendering() == GeometricPrecision)
+    if (style->getFontDescription().textRendering() == GeometricPrecision)
         scalingFactor = 1;
 
-    FontDescription fontDescription(style->fontDescription());
+    FontDescription fontDescription(style->getFontDescription());
 
     Document& document = layoutObject->document();
     // FIXME: We need to better handle the case when we compute very small fonts below (below 1pt).
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
index 89ae149..b8c1dca40 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
@@ -115,7 +115,7 @@
 
         // Second clip shape => start using the builder.
         if (!usingBuilder) {
-            clipPathBuilder.add(m_clipContentPath.skPath(), kUnion_SkPathOp);
+            clipPathBuilder.add(m_clipContentPath.getSkPath(), kUnion_SkPathOp);
             usingBuilder = true;
         }
 
@@ -125,7 +125,7 @@
         else if (isSVGUseElement(childElement))
             toSVGUseElement(childElement)->toClipPath(subPath);
 
-        clipPathBuilder.add(subPath.skPath(), kUnion_SkPathOp);
+        clipPathBuilder.add(subPath.getSkPath(), kUnion_SkPathOp);
     }
 
     if (usingBuilder) {
diff --git a/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp
index 350a708..29472583 100644
--- a/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/ReferenceFilterBuilder.cpp
@@ -112,7 +112,7 @@
     Filter::UnitScaling unitScaling = primitiveBoundingBoxMode ? Filter::BoundingBox : Filter::UserSpace;
     RefPtrWillBeRawPtr<Filter> result(Filter::create(referenceBox, filterRegion, zoom, unitScaling));
     if (!previousEffect)
-        previousEffect = result->sourceGraphic();
+        previousEffect = result->getSourceGraphic();
 
     SVGFilterBuilder builder(previousEffect, nullptr, fillPaint, strokePaint);
     builder.buildGraph(result.get(), filterElement, referenceBox);
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutTreeAsText.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutTreeAsText.cpp
index 40c0516..638ad91 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutTreeAsText.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutTreeAsText.cpp
@@ -507,7 +507,7 @@
         // Creating a placeholder filter which is passed to the builder.
         FloatRect dummyRect;
         RefPtrWillBeRawPtr<Filter> dummyFilter = Filter::create(dummyRect, dummyRect, 1, Filter::BoundingBox);
-        SVGFilterBuilder builder(dummyFilter->sourceGraphic());
+        SVGFilterBuilder builder(dummyFilter->getSourceGraphic());
         builder.buildGraph(dummyFilter.get(), toSVGFilterElement(*filter->element()), dummyRect);
         if (FilterEffect* lastEffect = builder.lastEffect())
             lastEffect->externalRepresentation(ts, indent + 1);
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
index 2b584b6..68f4a4c0 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
@@ -122,8 +122,8 @@
     FloatRect glyphOverflowBounds;
 
     float width = scaledFont.width(run, nullptr, &glyphOverflowBounds);
-    float ascent = scaledFont.fontMetrics().floatAscent();
-    float descent = scaledFont.fontMetrics().floatDescent();
+    float ascent = scaledFont.getFontMetrics().floatAscent();
+    float descent = scaledFont.getFontMetrics().floatDescent();
     textFragment.glyphOverflow.setFromBounds(glyphOverflowBounds, ascent, descent, width);
     textFragment.glyphOverflow.top /= scalingFactor;
     textFragment.glyphOverflow.left /= scalingFactor;
@@ -403,7 +403,7 @@
         // Font::width() calculates the resolved FontOrientation for each character,
         // but is not exposed today to avoid the API complexity.
         UChar32 currentCharacter = textLineLayout.codepointAt(m_visualMetricsIterator.characterOffset());
-        FontOrientation fontOrientation = font.fontDescription().orientation();
+        FontOrientation fontOrientation = font.getFontDescription().orientation();
         fontOrientation = adjustOrientationForCharacterInMixedVertical(fontOrientation, currentCharacter);
 
         // Calculate glyph advance.
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineBaseline.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineBaseline.cpp
index 0728c4f..709ea20 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineBaseline.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineBaseline.cpp
@@ -41,11 +41,11 @@
 
     switch (svgStyle.baselineShift()) {
     case BS_LENGTH:
-        return SVGLengthContext::valueForLength(svgStyle.baselineShiftValue(), style, m_font.fontDescription().computedPixelSize() / m_effectiveZoom);
+        return SVGLengthContext::valueForLength(svgStyle.baselineShiftValue(), style, m_font.getFontDescription().computedPixelSize() / m_effectiveZoom);
     case BS_SUB:
-        return -m_font.fontMetrics().floatHeight() / 2 / m_effectiveZoom;
+        return -m_font.getFontMetrics().floatHeight() / 2 / m_effectiveZoom;
     case BS_SUPER:
-        return m_font.fontMetrics().floatHeight() / 2 / m_effectiveZoom;
+        return m_font.getFontMetrics().floatHeight() / 2 / m_effectiveZoom;
     default:
         ASSERT_NOT_REACHED();
         return 0;
@@ -116,7 +116,7 @@
         ASSERT(baseline != AB_AUTO && baseline != AB_BASELINE);
     }
 
-    const FontMetrics& fontMetrics = m_font.fontMetrics();
+    const FontMetrics& fontMetrics = m_font.getFontMetrics();
     float ascent = fontMetrics.floatAscent() / m_effectiveZoom;
     float descent = fontMetrics.floatDescent() / m_effectiveZoom;
     float xheight = fontMetrics.xHeight() / m_effectiveZoom;
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineSpacing.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineSpacing.cpp
index 2e0d778..80aa8af 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngineSpacing.cpp
@@ -37,13 +37,13 @@
     UChar lastCharacter = m_lastCharacter;
     m_lastCharacter = currentCharacter;
 
-    if (!m_font.fontDescription().letterSpacing() && !m_font.fontDescription().wordSpacing())
+    if (!m_font.getFontDescription().letterSpacing() && !m_font.getFontDescription().wordSpacing())
         return 0;
 
-    float spacing = m_font.fontDescription().letterSpacing();
-    if (currentCharacter && lastCharacter && m_font.fontDescription().wordSpacing()) {
+    float spacing = m_font.getFontDescription().letterSpacing();
+    if (currentCharacter && lastCharacter && m_font.getFontDescription().wordSpacing()) {
         if (Character::treatAsSpace(currentCharacter) && !Character::treatAsSpace(lastCharacter))
-            spacing += m_font.fontDescription().wordSpacing();
+            spacing += m_font.getFontDescription().wordSpacing();
     }
 
     if (m_effectiveZoom != 1)
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.cpp
index ef77233..cff72c3 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.cpp
@@ -50,7 +50,7 @@
 
     // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
     m_width = scaledFont.width(run) / scalingFactor;
-    m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
+    m_height = scaledFont.getFontMetrics().floatHeight() / scalingFactor;
 
     ASSERT(run.length() >= 0);
     m_length = static_cast<unsigned>(run.length());
@@ -84,12 +84,6 @@
     return run;
 }
 
-SVGTextMetrics SVGTextMetrics::measureCharacterRange(LineLayoutSVGInlineText textLayoutItem, unsigned position, unsigned length, TextDirection textDirection)
-{
-    ASSERT(textLayoutItem);
-    return SVGTextMetrics(textLayoutItem, constructTextRun(textLayoutItem, position, length, textDirection));
-}
-
 SVGTextMetrics::SVGTextMetrics(LineLayoutSVGInlineText textLayoutItem, unsigned length, float width)
 {
     ASSERT(textLayoutItem);
@@ -98,7 +92,7 @@
     ASSERT(scalingFactor);
 
     m_width = width / scalingFactor;
-    m_height = textLayoutItem.scaledFont().fontMetrics().floatHeight() / scalingFactor;
+    m_height = textLayoutItem.scaledFont().getFontMetrics().floatHeight() / scalingFactor;
 
     m_length = length;
 }
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.h b/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.h
index 17e743a1..dc0bdd6 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.h
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextMetrics.h
@@ -40,7 +40,6 @@
     SVGTextMetrics(MetricsType);
     SVGTextMetrics(LineLayoutSVGInlineText, unsigned length, float width);
 
-    static SVGTextMetrics measureCharacterRange(LineLayoutSVGInlineText, unsigned position, unsigned length, TextDirection);
     static TextRun constructTextRun(LineLayoutSVGInlineText, unsigned position, unsigned length, TextDirection);
 
     bool isEmpty() const { return !m_width && !m_height && m_length <= 1; }
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp
index 70d014dc..284b2aec 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp
@@ -24,8 +24,7 @@
 #include "core/layout/svg/LayoutSVGInlineText.h"
 #include "core/layout/svg/LayoutSVGText.h"
 #include "core/layout/svg/SVGTextMetrics.h"
-#include "platform/fonts/GlyphBuffer.h"
-#include "platform/fonts/shaping/SimpleShaper.h"
+#include "platform/fonts/CharacterRange.h"
 #include "platform/text/BidiCharacterRun.h"
 #include "platform/text/BidiResolver.h"
 #include "platform/text/TextDirection.h"
@@ -41,34 +40,52 @@
     SVGTextMetricsCalculator(LayoutSVGInlineText*);
     ~SVGTextMetricsCalculator();
 
-    SVGTextMetrics computeMetricsForCharacter(unsigned textPosition);
-    unsigned textLength() const { return static_cast<unsigned>(m_run.charactersLength()); }
+    bool advancePosition();
+    unsigned currentPosition() const { return m_currentPosition; }
 
-    bool characterStartsSurrogatePair(unsigned textPosition) const
+    SVGTextMetrics currentCharacterMetrics();
+
+    // TODO(pdr): Character-based iteration is ambiguous and error-prone. It
+    // should be unified under a single concept. See: https://crbug.com/593570
+    bool currentCharacterStartsSurrogatePair() const
     {
-        return U16_IS_LEAD(m_run[textPosition]) && textPosition + 1 < textLength() && U16_IS_TRAIL(m_run[textPosition + 1]);
+        return U16_IS_LEAD(m_run[m_currentPosition]) && m_currentPosition + 1 < characterCount() && U16_IS_TRAIL(m_run[m_currentPosition + 1]);
     }
-    bool characterIsWhiteSpace(unsigned textPosition) const
+    bool currentCharacterIsWhiteSpace() const
     {
-        return m_run[textPosition] == ' ';
+        return m_run[m_currentPosition] == ' ';
+    }
+    unsigned characterCount() const
+    {
+        return static_cast<unsigned>(m_run.charactersLength());
     }
 
 private:
     void setupBidiRuns();
 
+    // Ensure |m_subrunRanges| is updated for the current bidi run, or the
+    // complete m_run if no bidi runs are present. Returns the current position
+    // in the subrun which can be used to index into |m_subrunRanges|.
+    unsigned updateSubrunRangesForCurrentPosition();
+
+    // Current character position in m_text.
+    unsigned m_currentPosition;
+
     LineLayoutSVGInlineText m_text;
-    BidiCharacterRun* m_bidiRun;
     TextRun m_run;
+
+    BidiCharacterRun* m_bidiRun;
     BidiResolver<TextRunIterator, BidiCharacterRun> m_bidiResolver;
-    float m_totalWidth;
-    TextDirection m_textDirection;
+
+    // Ranges for the current bidi run if present, or the entire run otherwise.
+    Vector<CharacterRange> m_subrunRanges;
 };
 
 SVGTextMetricsCalculator::SVGTextMetricsCalculator(LayoutSVGInlineText* text)
-    : m_text(LineLayoutSVGInlineText(text))
-    , m_bidiRun(nullptr)
+    : m_currentPosition(0)
+    , m_text(LineLayoutSVGInlineText(text))
     , m_run(SVGTextMetrics::constructTextRun(m_text, 0, m_text.textLength(), m_text.styleRef().direction()))
-    , m_totalWidth(0)
+    , m_bidiRun(nullptr)
 {
     setupBidiRuns();
 }
@@ -81,11 +98,8 @@
 
 void SVGTextMetricsCalculator::setupBidiRuns()
 {
-    const ComputedStyle& style = m_text.styleRef();
-    m_textDirection = style.direction();
-    if (isOverride(style.unicodeBidi()))
+    if (isOverride(m_text.styleRef().unicodeBidi()))
         return;
-
     BidiStatus status(LTR, false);
     status.last = status.lastStrong = WTF::Unicode::OtherNeutral;
     m_bidiResolver.setStatus(status);
@@ -97,36 +111,66 @@
     m_bidiRun = bidiRuns.firstRun();
 }
 
-SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacter(unsigned textPosition)
+bool SVGTextMetricsCalculator::advancePosition()
+{
+    m_currentPosition += currentCharacterStartsSurrogatePair() ? 2 : 1;
+    return m_currentPosition < characterCount();
+}
+
+unsigned SVGTextMetricsCalculator::updateSubrunRangesForCurrentPosition()
 {
     if (m_bidiRun) {
-        if (textPosition >= static_cast<unsigned>(m_bidiRun->stop())) {
+        if (m_currentPosition >= static_cast<unsigned>(m_bidiRun->stop())) {
             m_bidiRun = m_bidiRun->next();
-            // New BiDi run means new reference position for measurements, so reset |m_totalWidth|.
-            m_totalWidth = 0;
+            // Ensure new subrange ranges are computed below.
+            m_subrunRanges.clear();
         }
         ASSERT(m_bidiRun);
-        ASSERT(static_cast<int>(textPosition) < m_bidiRun->stop());
-        m_textDirection = m_bidiRun->direction();
+        ASSERT(static_cast<int>(m_currentPosition) < m_bidiRun->stop());
     }
 
-    unsigned metricsLength = characterStartsSurrogatePair(textPosition) ? 2 : 1;
-    SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength, m_textDirection);
-    ASSERT(metrics.length() == metricsLength);
+    unsigned positionInRun = m_bidiRun ? m_currentPosition - m_bidiRun->start() : m_currentPosition;
+    if (positionInRun >= m_subrunRanges.size()) {
+        unsigned subrunStart = m_bidiRun ? m_bidiRun->start() : 0;
+        unsigned subrunEnd = m_bidiRun ? m_bidiRun->stop() : m_run.charactersLength();
+        TextDirection subrunDirection = m_bidiRun ? m_bidiRun->direction() : m_text.styleRef().direction();
+        TextRun subRun = SVGTextMetrics::constructTextRun(m_text, subrunStart, subrunEnd - subrunStart, subrunDirection);
+        m_subrunRanges = m_text.scaledFont().individualCharacterRanges(subRun, 0, subRun.length() - 1);
 
-    unsigned startPosition = m_bidiRun ? m_bidiRun->start() : 0;
-    ASSERT(startPosition <= textPosition);
-    SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, startPosition, textPosition - startPosition + metricsLength, m_textDirection);
-    // Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
-    // when laying out the glyph "in context" (with it's surrounding characters) it changes due to shaping.
-    // So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is
-    // not equal to the sum of the individual lengths of the glyphs, when measuring them isolated.
-    float currentWidth = complexStartToCurrentMetrics.width() - m_totalWidth;
-    if (currentWidth != metrics.width())
-        metrics.setWidth(currentWidth);
+        // TODO(pdr): We only have per-glyph data so we need to synthesize per-
+        // grapheme data. E.g., if 'fi' is shaped into a single glyph, we do not
+        // know the 'i' position. The code below synthesizes an average glyph
+        // width when characters share a position. This will incorrectly split
+        // combining diacritics. See: https://crbug.com/473476.
+        unsigned distributeCount = 0;
+        for (int rangeIndex = static_cast<int>(m_subrunRanges.size()) - 1; rangeIndex >= 0; --rangeIndex) {
+            CharacterRange& currentRange = m_subrunRanges[rangeIndex];
+            if (currentRange.width() == 0) {
+                distributeCount++;
+            } else if (distributeCount != 0) {
+                distributeCount++;
+                float newWidth = currentRange.width() / distributeCount;
+                currentRange.end = currentRange.start + newWidth;
+                for (unsigned distribute = 1; distribute < distributeCount; distribute++) {
+                    unsigned distributeIndex = rangeIndex + distribute;
+                    float newStartPosition = m_subrunRanges[distributeIndex - 1].end;
+                    m_subrunRanges[distributeIndex].start = newStartPosition;
+                    m_subrunRanges[distributeIndex].end = newStartPosition + newWidth;
+                }
+                distributeCount = 0;
+            }
+        }
+    }
 
-    m_totalWidth = complexStartToCurrentMetrics.width();
-    return metrics;
+    return positionInRun;
+}
+
+SVGTextMetrics SVGTextMetricsCalculator::currentCharacterMetrics()
+{
+    unsigned currentSubrunPosition = updateSubrunRangesForCurrentPosition();
+    unsigned length = currentCharacterStartsSurrogatePair() ? 2 : 1;
+    float width = m_subrunRanges[currentSubrunPosition].width();
+    return SVGTextMetrics(m_text, length, width);
 }
 
 struct MeasureTextData {
@@ -155,47 +199,46 @@
             textMetricsValues->clear();
     }
 
+    // TODO(pdr): This loop is too tightly coupled to SVGTextMetricsCalculator.
+    // We should refactor SVGTextMetricsCalculator to be a simple bidi run
+    // iterator and move all subrun logic to a single function.
     SVGTextMetricsCalculator calculator(text);
     bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
     unsigned surrogatePairCharacters = 0;
     unsigned skippedCharacters = 0;
-    unsigned textPosition = 0;
-    unsigned textLength = calculator.textLength();
-
-    SVGTextMetrics currentMetrics;
-    for (; textPosition < textLength; textPosition += currentMetrics.length()) {
-        currentMetrics = calculator.computeMetricsForCharacter(textPosition);
-        if (!currentMetrics.length())
+    do {
+        SVGTextMetrics metrics = calculator.currentCharacterMetrics();
+        if (!metrics.length())
             break;
 
-        bool characterIsWhiteSpace = calculator.characterIsWhiteSpace(textPosition);
+        bool characterIsWhiteSpace = calculator.currentCharacterIsWhiteSpace();
         if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) {
             if (processLayoutObject)
                 textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
             if (data->allCharactersMap)
-                skippedCharacters += currentMetrics.length();
+                skippedCharacters += metrics.length();
             continue;
         }
 
         if (processLayoutObject) {
             if (data->allCharactersMap) {
-                const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + textPosition - skippedCharacters - surrogatePairCharacters + 1);
+                const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + calculator.currentPosition() - skippedCharacters - surrogatePairCharacters + 1);
                 if (it != data->allCharactersMap->end())
-                    attributes->characterDataMap().set(textPosition + 1, it->value);
+                    attributes->characterDataMap().set(calculator.currentPosition() + 1, it->value);
             }
-            textMetricsValues->append(currentMetrics);
+            textMetricsValues->append(metrics);
         }
 
-        if (data->allCharactersMap && calculator.characterStartsSurrogatePair(textPosition))
+        if (data->allCharactersMap && calculator.currentCharacterStartsSurrogatePair())
             surrogatePairCharacters++;
 
         data->lastCharacterWasWhiteSpace = characterIsWhiteSpace;
-    }
+    } while (calculator.advancePosition());
 
     if (!data->allCharactersMap)
         return;
 
-    data->valueListPosition += textPosition - skippedCharacters;
+    data->valueListPosition += calculator.currentPosition() - skippedCharacters;
 }
 
 static void walkTree(LayoutSVGText* start, LayoutSVGInlineText* stopAtLeaf, MeasureTextData* data)
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp
index a65a7db00..8b2556c2 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp
@@ -465,7 +465,7 @@
     ASSERT(scalingFactor);
 
     FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, startPosition);
-    glyphPosition.move(0, -queryData->textLineLayout.scaledFont().fontMetrics().floatAscent() / scalingFactor);
+    glyphPosition.move(0, -queryData->textLineLayout.scaledFont().getFontMetrics().floatAscent() / scalingFactor);
     extent.setLocation(glyphPosition);
 
     // Use the SVGTextMetrics computed by SVGTextMetricsBuilder (which spends
@@ -497,7 +497,7 @@
 {
     float scalingFactor = textLineLayout.scalingFactor();
     ASSERT(scalingFactor);
-    float baseline = textLineLayout.scaledFont().fontMetrics().floatAscent() / scalingFactor;
+    float baseline = textLineLayout.scaledFont().getFontMetrics().floatAscent() / scalingFactor;
     return fragment.boundingBox(baseline);
 }
 
diff --git a/third_party/WebKit/Source/core/layout/svg/line/SVGInlineTextBox.cpp b/third_party/WebKit/Source/core/layout/svg/line/SVGInlineTextBox.cpp
index 1456c03..d2a2287b 100644
--- a/third_party/WebKit/Source/core/layout/svg/line/SVGInlineTextBox.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/line/SVGInlineTextBox.cpp
@@ -113,7 +113,7 @@
     ASSERT(scalingFactor);
 
     const Font& scaledFont = lineLayoutItem.scaledFont();
-    const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
+    const FontMetrics& scaledFontMetrics = scaledFont.getFontMetrics();
     FloatPoint textOrigin(fragment.x, fragment.y);
     if (scalingFactor != 1)
         textOrigin.scale(scalingFactor, scalingFactor);
@@ -233,7 +233,7 @@
     LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText(this->getLineLayoutItem());
     float scalingFactor = lineLayoutItem.scalingFactor();
     ASSERT(scalingFactor);
-    LayoutUnit baseline(lineLayoutItem.scaledFont().fontMetrics().floatAscent() / scalingFactor);
+    LayoutUnit baseline(lineLayoutItem.scaledFont().getFontMetrics().floatAscent() / scalingFactor);
 
     LayoutRect textBoundingRect;
     for (const SVGTextFragment& fragment : m_textFragments)
@@ -259,7 +259,7 @@
             if (locationInContainer.intersects(rect)) {
                 LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText(this->getLineLayoutItem());
                 ASSERT(lineLayoutItem.scalingFactor());
-                float baseline = lineLayoutItem.scaledFont().fontMetrics().floatAscent() / lineLayoutItem.scalingFactor();
+                float baseline = lineLayoutItem.scaledFont().getFontMetrics().floatAscent() / lineLayoutItem.scalingFactor();
 
                 FloatPoint floatLocation = FloatPoint(locationInContainer.point());
                 for (const SVGTextFragment& fragment : m_textFragments) {
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index d86e4554..c5b90833 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -326,12 +326,6 @@
     clearMainResourceHandle();
 }
 
-void DocumentLoader::updateRequest(Resource* resource, const ResourceRequest& request)
-{
-    ASSERT_UNUSED(resource, resource == m_mainResource);
-    m_request = request;
-}
-
 void DocumentLoader::redirectReceived(Resource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse)
 {
     ASSERT_UNUSED(resource, resource == m_mainResource);
@@ -593,11 +587,6 @@
     m_redirectChain.append(url);
 }
 
-bool DocumentLoader::loadingMultipartContent() const
-{
-    return mainResourceLoader() ? mainResourceLoader()->loadingMultipartContent() : false;
-}
-
 void DocumentLoader::detachFromFrame()
 {
     ASSERT(m_frame);
@@ -691,11 +680,10 @@
 
     m_applicationCacheHost->willStartLoadingMainResource(m_request);
 
-    ResourceRequest request(m_request);
     DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
         (DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, CheckContentSecurityPolicy, DocumentContext));
-    FetchRequest cachedResourceRequest(request, FetchInitiatorTypeNames::document, mainResourceLoadOptions);
-    m_mainResource = RawResource::fetchMainResource(cachedResourceRequest, fetcher(), m_substituteData);
+    FetchRequest fetchRequest(m_request, FetchInitiatorTypeNames::document, mainResourceLoadOptions);
+    m_mainResource = RawResource::fetchMainResource(fetchRequest, fetcher(), m_substituteData);
     if (!m_mainResource) {
         m_request = ResourceRequest();
         // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
@@ -707,20 +695,13 @@
         maybeLoadEmpty();
         return;
     }
-    if (mainResourceLoader()) {
-        // A bunch of headers are set when the underlying ResourceLoader
-        // is created, and m_request needs to include those.
-        request = mainResourceLoader()->originalRequest();
-    } else {
-        // Even when using a cached resource, we may make some modification
-        // to the request, e.g. adding the referer header.
-        request = cachedResourceRequest.resourceRequest();
-    }
+    // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
+    // Even when using a cached resource, we may make some modification to the request, e.g. adding the referer header.
+    m_request = mainResourceLoader() ? m_mainResource->resourceRequest() : fetchRequest.resourceRequest();
     // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
     // the fragment identifier, so add that back in.
-    if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
-        request.setURL(m_request.url());
-    m_request = request;
+    if (equalIgnoringFragmentIdentifier(m_request.url(), fetchRequest.url()))
+        m_request.setURL(fetchRequest.url());
     m_mainResource->addClient(this);
 }
 
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h
index 16d968c..ec20778 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.h
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -144,8 +144,6 @@
 
     String suboriginName() const { return m_suboriginName; }
 
-    bool loadingMultipartContent() const;
-
     Resource* startPreload(Resource::Type, FetchRequest&);
 
     DECLARE_VIRTUAL_TRACE();
@@ -175,7 +173,6 @@
     void mainReceivedError(const ResourceError&);
     void cancelLoadAfterXFrameOptionsOrCSPDenied(const ResourceResponse&);
     void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&) final;
-    void updateRequest(Resource*, const ResourceRequest&) final;
     void responseReceived(Resource*, const ResourceResponse&, PassOwnPtr<WebDataConsumerHandle>) final;
     void dataReceived(Resource*, const char* data, size_t length) final;
     void processData(const char* data, size_t length);
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index 5bdfcb1..21f219ea 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -119,8 +119,11 @@
     if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
         return;
 
+    if (frame()->loader().loadType() == FrameLoadTypeReload)
+        request.clearHTTPHeaderField("Save-Data");
+
     if (frame()->settings() && frame()->settings()->dataSaverEnabled())
-        request.addHTTPHeaderField("Save-Data", "on");
+        request.setHTTPHeaderField("Save-Data", "on");
 
     frame()->loader().applyUserAgent(request);
 }
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
index c000b80..22c206f 100644
--- a/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameFetchContextTest.cpp
@@ -564,6 +564,11 @@
     ResourceRequest resourceRequest("http://www.example.com");
     fetchContext->addAdditionalRequestHeaders(resourceRequest, FetchMainResource);
     EXPECT_STREQ("on", resourceRequest.httpHeaderField("Save-Data").utf8().data());
+
+    // Subsequent call to addAdditionalRequestHeaders should not append to the
+    // save-data header.
+    fetchContext->addAdditionalRequestHeaders(resourceRequest, FetchMainResource);
+    EXPECT_STREQ("on", resourceRequest.httpHeaderField("Save-Data").utf8().data());
 }
 
 TEST_F(FrameFetchContextTest, DisabledDataSaver)
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index f13a418e..98e34319 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -469,8 +469,8 @@
 
     updateLayoutObject();
 
-    if (m_image && m_image->image() && m_image->image()->isSVGImage())
-        toSVGImage(m_image->image())->updateUseCounters(element()->document());
+    if (m_image && m_image->getImage() && m_image->getImage()->isSVGImage())
+        toSVGImage(m_image->getImage())->updateUseCounters(element()->document());
 
     if (!m_hasPendingLoadEvent)
         return;
diff --git a/third_party/WebKit/Source/core/loader/LinkHeader.cpp b/third_party/WebKit/Source/core/loader/LinkHeader.cpp
index 12abedf3..952566cb 100644
--- a/third_party/WebKit/Source/core/loader/LinkHeader.cpp
+++ b/third_party/WebKit/Source/core/loader/LinkHeader.cpp
@@ -300,6 +300,7 @@
 
         setValue(parameterName, parameterValue);
     }
+    findNextHeader(position, end);
 }
 
 LinkHeaderSet::LinkHeaderSet(const String& header)
diff --git a/third_party/WebKit/Source/core/loader/LinkHeaderTest.cpp b/third_party/WebKit/Source/core/loader/LinkHeaderTest.cpp
index 21680b7..2c918c1 100644
--- a/third_party/WebKit/Source/core/loader/LinkHeaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/LinkHeaderTest.cpp
@@ -8,6 +8,7 @@
 #include <base/macros.h>
 
 namespace blink {
+namespace {
 
 TEST(LinkHeaderTest, Empty)
 {
@@ -19,160 +20,186 @@
     ASSERT_EQ(emptyHeaderSet.size(), unsigned(0));
 }
 
-TEST(LinkHeaderTest, Single)
+struct SingleTestCase {
+    const char* headerValue;
+    const char* url;
+    const char* rel;
+    const char* as;
+    bool valid;
+} singleTestCases[] = {
+    {"</images/cat.jpg>; rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>;rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>   ;rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"< /images/cat.jpg>   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg >   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg wutwut>   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg wutwut  \t >   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; Rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; Rel=PReFetCh   ", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; rel=prefetch; rel=somethingelse", "/images/cat.jpg", "prefetch", "", true},
+    {"  </images/cat.jpg>; rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
+    {"\t  </images/cat.jpg>; rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>\t\t ; \trel=prefetch \t  ", "/images/cat.jpg", "prefetch", "", true},
+    {"\f</images/cat.jpg>\t\t ; \trel=prefetch \t  ", "", "", "", false},
+    {"</images/cat.jpg>; rel= prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"<../images/cat.jpg?dog>; rel= prefetch", "../images/cat.jpg?dog", "prefetch", "", true},
+    {"</images/cat.jpg>; rel =prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; rel pel=prefetch", "/images/cat.jpg", "", "", false},
+    {"< /images/cat.jpg>", "/images/cat.jpg", "", "", true},
+    {"</images/cat.jpg>; rel =", "/images/cat.jpg", "", "", false},
+    {"</images/cat.jpg>; wut=sup; rel =prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; wut=sup ; rel =prefetch", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; wut=sup ; rel =prefetch  \t  ;", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg> wut=sup ; rel =prefetch  \t  ;", "/images/cat.jpg", "", "", false},
+    {"<   /images/cat.jpg", "", "", "", false},
+    {"<   http://wut.com/  sdfsdf ?sd>; rel=dns-prefetch", "http://wut.com/", "dns-prefetch", "", true},
+    {"<   http://wut.com/%20%20%3dsdfsdf?sd>; rel=dns-prefetch", "http://wut.com/%20%20%3dsdfsdf?sd", "dns-prefetch", "", true},
+    {"<   http://wut.com/dfsdf?sdf=ghj&wer=rty>; rel=prefetch", "http://wut.com/dfsdf?sdf=ghj&wer=rty", "prefetch", "", true},
+    {"<   http://wut.com/dfsdf?sdf=ghj&wer=rty>;;;;; rel=prefetch", "http://wut.com/dfsdf?sdf=ghj&wer=rty", "prefetch", "", true},
+    {"<   http://wut.com/%20%20%3dsdfsdf?sd>; rel=preload;as=image", "http://wut.com/%20%20%3dsdfsdf?sd", "preload", "image", true},
+    {"<   http://wut.com/%20%20%3dsdfsdf?sd>; rel=preload;as=whatever", "http://wut.com/%20%20%3dsdfsdf?sd", "preload", "whatever", true},
+    {"</images/cat.jpg>; anchor=foo; rel=prefetch;", "/images/cat.jpg", "", "", false},
+    {"</images/cat.jpg>; rel=prefetch;anchor=foo ", "/images/cat.jpg", "prefetch", "", false},
+    {"</images/cat.jpg>; anchor='foo'; rel=prefetch;", "/images/cat.jpg", "", "", false},
+    {"</images/cat.jpg>; rel=prefetch;anchor='foo' ", "/images/cat.jpg", "prefetch", "", false},
+    {"</images/cat.jpg>; rel=prefetch;anchor='' ", "/images/cat.jpg", "prefetch", "", false},
+    {"</images/cat.jpg>; rel=prefetch;", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/cat.jpg>; rel=prefetch    ;", "/images/cat.jpg", "prefetch", "", true},
+    {"</images/ca,t.jpg>; rel=prefetch    ;", "/images/ca,t.jpg", "prefetch", "", true},
+    {"<simple.css>; rel=stylesheet; title=\"title with a DQUOTE and backslash\"", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; rel=stylesheet; title=\"title with a DQUOTE \\\" and backslash: \\\"", "simple.css", "stylesheet", "", false},
+    {"<simple.css>; title=\"title with a DQUOTE \\\" and backslash: \"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; title=\'title with a DQUOTE \\\' and backslash: \'; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; title=\"title with a DQUOTE \\\" and ;backslash,: \"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; title=\"title with a DQUOTE \' and ;backslash,: \"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; title=\"\"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; title=\"\"; rel=\"stylesheet\"; ", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; rel=stylesheet; title=\"", "simple.css", "stylesheet", "", false},
+    {"<simple.css>; rel=stylesheet; title=\"\"", "simple.css", "stylesheet", "", true},
+    {"<simple.css>; rel=\"stylesheet\"; title=\"", "simple.css", "stylesheet", "", false},
+    {"<simple.css>; rel=\";style,sheet\"; title=\"", "simple.css", ";style,sheet", "", false},
+    {"<simple.css>; rel=\"bla'sdf\"; title=\"", "simple.css", "bla'sdf", "", false},
+    {"<simple.css>; rel=\"\"; title=\"\"", "simple.css", "", "", true},
+    {"<simple.css>; rel=''; title=\"\"", "simple.css", "", "", true},
+    {"<simple.css>; rel=''; title=", "simple.css", "", "", false},
+    {"<simple.css>; rel=''; title", "simple.css", "", "", false},
+    {"<simple.css>; rel=''; media", "simple.css", "", "", false},
+    {"<simple.css>; rel=''; hreflang", "simple.css", "", "", false},
+    {"<simple.css>; rel=''; type", "simple.css", "", "", false},
+    {"<simple.css>; rel=''; rev", "simple.css", "", "", false},
+    {"<simple.css>; rel=''; bla", "simple.css", "", "", true},
+    {"<simple.css>; rel='prefetch", "simple.css", "", "", false},
+    {"<simple.css>; rel=\"prefetch", "simple.css", "", "", false},
+    {"<simple.css>; rel=\"", "simple.css", "", "", false},
+    {"<http://whatever.com>; rel=preconnect; valid!", "http://whatever.com", "preconnect", "", true},
+    {"<http://whatever.com>; rel=preconnect; valid$", "http://whatever.com", "preconnect", "", true},
+    {"<http://whatever.com>; rel=preconnect; invalid@", "http://whatever.com", "preconnect", "", false},
+    {"<http://whatever.com>; rel=preconnect; invalid*", "http://whatever.com", "preconnect", "", false},
+};
+
+void PrintTo(const SingleTestCase& test, std::ostream* os)
 {
-    struct TestCase {
-        const char* headerValue;
-        const char* url;
-        const char* rel;
-        const char* as;
-        bool valid;
-    } cases[] = {
-        {"</images/cat.jpg>; rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>;rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>   ;rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"< /images/cat.jpg>   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg >   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg wutwut>   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg wutwut  \t >   ;   rel=prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; Rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; Rel=PReFetCh   ", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; rel=prefetch; rel=somethingelse", "/images/cat.jpg", "prefetch", "", true},
-        {"  </images/cat.jpg>; rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
-        {"\t  </images/cat.jpg>; rel=prefetch   ", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>\t\t ; \trel=prefetch \t  ", "/images/cat.jpg", "prefetch", "", true},
-        {"\f</images/cat.jpg>\t\t ; \trel=prefetch \t  ", "", "", "", false},
-        {"</images/cat.jpg>; rel= prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"<../images/cat.jpg?dog>; rel= prefetch", "../images/cat.jpg?dog", "prefetch", "", true},
-        {"</images/cat.jpg>; rel =prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; rel pel=prefetch", "/images/cat.jpg", "", "", false},
-        {"< /images/cat.jpg>", "/images/cat.jpg", "", "", true},
-        {"</images/cat.jpg>; rel =", "/images/cat.jpg", "", "", false},
-        {"</images/cat.jpg>; wut=sup; rel =prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; wut=sup ; rel =prefetch", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; wut=sup ; rel =prefetch  \t  ;", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg> wut=sup ; rel =prefetch  \t  ;", "/images/cat.jpg", "", "", false},
-        {"<   /images/cat.jpg", "", "", "", false},
-        {"<   http://wut.com/  sdfsdf ?sd>; rel=dns-prefetch", "http://wut.com/", "dns-prefetch", "", true},
-        {"<   http://wut.com/%20%20%3dsdfsdf?sd>; rel=dns-prefetch", "http://wut.com/%20%20%3dsdfsdf?sd", "dns-prefetch", "", true},
-        {"<   http://wut.com/dfsdf?sdf=ghj&wer=rty>; rel=prefetch", "http://wut.com/dfsdf?sdf=ghj&wer=rty", "prefetch", "", true},
-        {"<   http://wut.com/dfsdf?sdf=ghj&wer=rty>;;;;; rel=prefetch", "http://wut.com/dfsdf?sdf=ghj&wer=rty", "prefetch", "", true},
-        {"<   http://wut.com/%20%20%3dsdfsdf?sd>; rel=preload;as=image", "http://wut.com/%20%20%3dsdfsdf?sd", "preload", "image", true},
-        {"<   http://wut.com/%20%20%3dsdfsdf?sd>; rel=preload;as=whatever", "http://wut.com/%20%20%3dsdfsdf?sd", "preload", "whatever", true},
-        {"</images/cat.jpg>; anchor=foo; rel=prefetch;", "/images/cat.jpg", "", "", false},
-        {"</images/cat.jpg>; rel=prefetch;anchor=foo ", "/images/cat.jpg", "prefetch", "", false},
-        {"</images/cat.jpg>; anchor='foo'; rel=prefetch;", "/images/cat.jpg", "", "", false},
-        {"</images/cat.jpg>; rel=prefetch;anchor='foo' ", "/images/cat.jpg", "prefetch", "", false},
-        {"</images/cat.jpg>; rel=prefetch;anchor='' ", "/images/cat.jpg", "prefetch", "", false},
-        {"</images/cat.jpg>; rel=prefetch;", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/cat.jpg>; rel=prefetch    ;", "/images/cat.jpg", "prefetch", "", true},
-        {"</images/ca,t.jpg>; rel=prefetch    ;", "/images/ca,t.jpg", "prefetch", "", true},
-        {"<simple.css>; rel=stylesheet; title=\"title with a DQUOTE and backslash\"", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; rel=stylesheet; title=\"title with a DQUOTE \\\" and backslash: \\\"", "simple.css", "stylesheet", "", false},
-        {"<simple.css>; title=\"title with a DQUOTE \\\" and backslash: \"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; title=\'title with a DQUOTE \\\' and backslash: \'; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; title=\"title with a DQUOTE \\\" and ;backslash,: \"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; title=\"title with a DQUOTE \' and ;backslash,: \"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; title=\"\"; rel=stylesheet; ", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; title=\"\"; rel=\"stylesheet\"; ", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; rel=stylesheet; title=\"", "simple.css", "stylesheet", "", false},
-        {"<simple.css>; rel=stylesheet; title=\"\"", "simple.css", "stylesheet", "", true},
-        {"<simple.css>; rel=\"stylesheet\"; title=\"", "simple.css", "stylesheet", "", false},
-        {"<simple.css>; rel=\";style,sheet\"; title=\"", "simple.css", ";style,sheet", "", false},
-        {"<simple.css>; rel=\"bla'sdf\"; title=\"", "simple.css", "bla'sdf", "", false},
-        {"<simple.css>; rel=\"\"; title=\"\"", "simple.css", "", "", true},
-        {"<simple.css>; rel=''; title=\"\"", "simple.css", "", "", true},
-        {"<simple.css>; rel=''; title=", "simple.css", "", "", false},
-        {"<simple.css>; rel=''; title", "simple.css", "", "", false},
-        {"<simple.css>; rel=''; media", "simple.css", "", "", false},
-        {"<simple.css>; rel=''; hreflang", "simple.css", "", "", false},
-        {"<simple.css>; rel=''; type", "simple.css", "", "", false},
-        {"<simple.css>; rel=''; rev", "simple.css", "", "", false},
-        {"<simple.css>; rel=''; bla", "simple.css", "", "", true},
-        {"<simple.css>; rel='prefetch", "simple.css", "", "", false},
-        {"<simple.css>; rel=\"prefetch", "simple.css", "", "", false},
-        {"<simple.css>; rel=\"", "simple.css", "", "", false},
-    };
-
-
-    // Test the cases with a single header
-    for (auto& testCase : cases) {
-        LinkHeaderSet headerSet(testCase.headerValue);
-        LinkHeader& header = headerSet[0];
-        ASSERT_STREQ(testCase.url, header.url().ascii().data());
-        ASSERT_STREQ(testCase.rel, header.rel().ascii().data());
-        ASSERT_EQ(testCase.valid, header.valid());
-    }
+    *os << ::testing::PrintToString(test.headerValue);
 }
 
-TEST(LinkHeaderTest, Double)
-{
-    struct DoubleTestCase {
-        const char* headerValue;
-        const char* url;
-        const char* rel;
-        bool valid;
-        const char* url2;
-        const char* rel2;
-        bool valid2;
-    } cases[] = {
-        {"<ybg.css>; rel=stylesheet, <simple.css>; rel=stylesheet", "ybg.css", "stylesheet", true, "simple.css", "stylesheet", true},
-        {"<ybg.css>; rel=stylesheet,<simple.css>; rel=stylesheet", "ybg.css", "stylesheet", true, "simple.css", "stylesheet", true},
-        {"<ybg.css>; rel=stylesheet;crossorigin,<simple.css>; rel=stylesheet", "ybg.css", "stylesheet", true, "simple.css", "stylesheet", true},
-    };
+class SingleLinkHeaderTest : public ::testing::TestWithParam<SingleTestCase> {};
 
-    for (auto& testCase : cases) {
-        LinkHeaderSet headerSet(testCase.headerValue);
-        LinkHeader& header1 = headerSet[0];
-        LinkHeader& header2 = headerSet[1];
-        ASSERT_STREQ(testCase.url, header1.url().ascii().data());
-        ASSERT_STREQ(testCase.rel, header1.rel().ascii().data());
-        ASSERT_EQ(testCase.valid, header1.valid());
-        ASSERT_STREQ(testCase.url2, header2.url().ascii().data());
-        ASSERT_STREQ(testCase.rel2, header2.rel().ascii().data());
-        ASSERT_EQ(testCase.valid2, header2.valid());
-    }
+// Test the cases with a single header
+TEST_P(SingleLinkHeaderTest, Single)
+{
+    const SingleTestCase testCase = GetParam();
+    LinkHeaderSet headerSet(testCase.headerValue);
+    ASSERT_EQ(1u, headerSet.size());
+    LinkHeader& header = headerSet[0];
+    EXPECT_STREQ(testCase.url, header.url().ascii().data());
+    EXPECT_STREQ(testCase.rel, header.rel().ascii().data());
+    EXPECT_EQ(testCase.valid, header.valid());
 }
 
-TEST(LinkHeaderTest, CrossOrigin)
+INSTANTIATE_TEST_CASE_P(LinkHeaderTest, SingleLinkHeaderTest, testing::ValuesIn(singleTestCases));
+
+struct DoubleTestCase {
+    const char* headerValue;
+    const char* url;
+    const char* rel;
+    bool valid;
+    const char* url2;
+    const char* rel2;
+    bool valid2;
+} doubleTestCases[] = {
+    {"<ybg.css>; rel=stylesheet, <simple.css>; rel=stylesheet", "ybg.css", "stylesheet", true, "simple.css", "stylesheet", true},
+    {"<ybg.css>; rel=stylesheet,<simple.css>; rel=stylesheet", "ybg.css", "stylesheet", true, "simple.css", "stylesheet", true},
+    {"<ybg.css>; rel=stylesheet;crossorigin,<simple.css>; rel=stylesheet", "ybg.css", "stylesheet", true, "simple.css", "stylesheet", true},
+};
+
+void PrintTo(const DoubleTestCase& test, std::ostream* os)
 {
-    struct TestCase {
-        const char* headerValue;
-        const char* url;
-        const char* rel;
-        const CrossOriginAttributeValue crossorigin;
-        bool valid;
-    } cases[] = {
-        {"<http://whatever.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin=", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin ", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin;", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin, <http://whatever2.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin , <http://whatever2.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin,<http://whatever2.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin=anonymous", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin=use-credentials", "http://whatever.com", "preconnect", CrossOriginAttributeUseCredentials, true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin=whatever", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous,  true},
-        {"<http://whatever.com>; rel=preconnect; crossorig|in=whatever", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet,  true},
-        {"<http://whatever.com>; rel=preconnect; crossorigin|=whatever", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet,  true},
-        {"<http://whatever.com>; rel=preconnect; valid!", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet,  true},
-        {"<http://whatever.com>; rel=preconnect; valid$", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet,  true},
-        {"<http://whatever.com>; rel=preconnect; invalid@", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet,  false},
-        {"<http://whatever.com>; rel=preconnect; invalid*", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet,  false},
-    };
-
-
-    // Test the cases with a single header
-    for (auto& testCase : cases) {
-        LinkHeaderSet headerSet(testCase.headerValue);
-        LinkHeader& header = headerSet[0];
-        ASSERT_STREQ(testCase.url, header.url().ascii().data());
-        ASSERT_STREQ(testCase.rel, header.rel().ascii().data());
-        ASSERT_EQ(testCase.crossorigin, header.crossOrigin());
-        ASSERT_EQ(testCase.valid, header.valid());
-    }
+    *os << ::testing::PrintToString(test.headerValue);
 }
+
+class DoubleLinkHeaderTest : public ::testing::TestWithParam<DoubleTestCase> {};
+
+TEST_P(DoubleLinkHeaderTest, Double)
+{
+    const DoubleTestCase testCase = GetParam();
+    LinkHeaderSet headerSet(testCase.headerValue);
+    ASSERT_EQ(2u, headerSet.size());
+    LinkHeader& header1 = headerSet[0];
+    LinkHeader& header2 = headerSet[1];
+    EXPECT_STREQ(testCase.url, header1.url().ascii().data());
+    EXPECT_STREQ(testCase.rel, header1.rel().ascii().data());
+    EXPECT_EQ(testCase.valid, header1.valid());
+    EXPECT_STREQ(testCase.url2, header2.url().ascii().data());
+    EXPECT_STREQ(testCase.rel2, header2.rel().ascii().data());
+    EXPECT_EQ(testCase.valid2, header2.valid());
+}
+
+INSTANTIATE_TEST_CASE_P(LinkHeaderTest, DoubleLinkHeaderTest, testing::ValuesIn(doubleTestCases));
+
+struct CrossOriginTestCase {
+    const char* headerValue;
+    const char* url;
+    const char* rel;
+    const CrossOriginAttributeValue crossorigin;
+    bool valid;
+} crossOriginTestCases[] = {
+    {"<http://whatever.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin=", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin ", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin;", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin, <http://whatever2.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin , <http://whatever2.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin,<http://whatever2.com>; rel=preconnect", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin=anonymous", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin=use-credentials", "http://whatever.com", "preconnect", CrossOriginAttributeUseCredentials, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin=whatever", "http://whatever.com", "preconnect", CrossOriginAttributeAnonymous, true},
+    {"<http://whatever.com>; rel=preconnect; crossorig|in=whatever", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet, true},
+    {"<http://whatever.com>; rel=preconnect; crossorigin|=whatever", "http://whatever.com", "preconnect", CrossOriginAttributeNotSet, true},
+};
+
+void PrintTo(const CrossOriginTestCase& test, std::ostream* os)
+{
+    *os << ::testing::PrintToString(test.headerValue);
+}
+
+class CrossOriginLinkHeaderTest : public ::testing::TestWithParam<CrossOriginTestCase> {};
+
+TEST_P(CrossOriginLinkHeaderTest, CrossOrigin)
+{
+    const CrossOriginTestCase testCase = GetParam();
+    LinkHeaderSet headerSet(testCase.headerValue);
+    ASSERT_GE(headerSet.size(), 1u);
+    LinkHeader& header = headerSet[0];
+    EXPECT_STREQ(testCase.url, header.url().ascii().data());
+    EXPECT_STREQ(testCase.rel, header.rel().ascii().data());
+    EXPECT_EQ(testCase.crossorigin, header.crossOrigin());
+    EXPECT_EQ(testCase.valid, header.valid());
+}
+
+INSTANTIATE_TEST_CASE_P(LinkHeaderTest, CrossOriginLinkHeaderTest, testing::ValuesIn(crossOriginTestCases));
+
+} // namespace
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/LinkLoader.cpp b/third_party/WebKit/Source/core/loader/LinkLoader.cpp
index 024c817..4f4e00e 100644
--- a/third_party/WebKit/Source/core/loader/LinkLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/LinkLoader.cpp
@@ -171,17 +171,18 @@
 
 bool LinkLoader::getResourceTypeFromAsAttribute(const String& as, Resource::Type& type)
 {
-    if (equalIgnoringCase(as, "image")) {
+    ASSERT(as.lower() == as);
+    if (as == "image") {
         type = Resource::Image;
-    } else if (equalIgnoringCase(as, "script")) {
+    } else if (as == "script") {
         type = Resource::Script;
-    } else if (equalIgnoringCase(as, "style")) {
+    } else if (as == "style") {
         type = Resource::CSSStyleSheet;
-    } else if (equalIgnoringCase(as, "audio") || equalIgnoringCase(as, "video")) {
+    } else if (as == "media") {
         type = Resource::Media;
-    } else if (equalIgnoringCase(as, "font")) {
+    } else if (as == "font") {
         type = Resource::Font;
-    } else if (equalIgnoringCase(as, "track")) {
+    } else if (as == "track") {
         type = Resource::TextTrack;
     } else {
         type = Resource::LinkPreload;
diff --git a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
index 10c1d77..bd12d90 100644
--- a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
@@ -98,8 +98,8 @@
         {"data://example.test/cat.js", "script", "", ResourceLoadPriorityMedium, WebURLRequest::RequestContextScript, true, true, "*/*"},
         {"data://example.test/cat.css", "style", "", ResourceLoadPriorityHigh, WebURLRequest::RequestContextStyle, true, true, "text/css,*/*;q=0.1"},
         // TODO(yoav): It doesn't seem like the audio context is ever used. That should probably be fixed (or we can consolidate audio and video).
-        {"data://example.test/cat.wav", "audio", "", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
-        {"data://example.test/cat.mp4", "video", "", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
+        {"data://example.test/cat.wav", "media", "", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
+        {"data://example.test/cat.mp4", "media", "", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
         {"data://example.test/cat.vtt", "track", "", ResourceLoadPriorityLow, WebURLRequest::RequestContextTrack, true, true, ""},
         {"data://example.test/cat.woff", "font", "", ResourceLoadPriorityMedium, WebURLRequest::RequestContextFont, true, true, ""},
         // TODO(yoav): subresource should be *very* low priority (rather than low).
@@ -114,10 +114,10 @@
         {"data://example.test/cat.js", "script", "text/coffeescript", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextScript, false, false, ""},
         {"data://example.test/cat.css", "style", "text/css", ResourceLoadPriorityHigh, WebURLRequest::RequestContextStyle, true, true, "text/css,*/*;q=0.1"},
         {"data://example.test/cat.css", "style", "text/sass", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextStyle, false, false, ""},
-        {"data://example.test/cat.wav", "audio", "audio/wav", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
-        {"data://example.test/cat.wav", "audio", "audio/mp57", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextVideo, false, false, ""},
-        {"data://example.test/cat.webm", "video", "video/webm", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
-        {"data://example.test/cat.mp199", "video", "video/mp199", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextVideo, false, false, ""},
+        {"data://example.test/cat.wav", "media", "audio/wav", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
+        {"data://example.test/cat.wav", "media", "audio/mp57", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextVideo, false, false, ""},
+        {"data://example.test/cat.webm", "media", "video/webm", ResourceLoadPriorityLow, WebURLRequest::RequestContextVideo, true, true, ""},
+        {"data://example.test/cat.mp199", "media", "video/mp199", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextVideo, false, false, ""},
         {"data://example.test/cat.vtt", "track", "text/vtt", ResourceLoadPriorityLow, WebURLRequest::RequestContextTrack, true, true, ""},
         {"data://example.test/cat.vtt", "track", "text/subtitlething", ResourceLoadPriorityUnresolved, WebURLRequest::RequestContextTrack, false, false, ""},
         {"data://example.test/cat.woff", "font", "font/woff2", ResourceLoadPriorityMedium, WebURLRequest::RequestContextFont, true, true, ""},
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
index ae76e45..6d3f81d 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
@@ -11,17 +11,13 @@
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebSecurityOrigin.h"
 #include "public/platform/WebTrialTokenValidator.h"
 
 namespace blink {
 
 namespace {
 
-String getCurrentOrigin(ExecutionContext* executionContext)
-{
-    return executionContext->getSecurityOrigin()->toString();
-}
-
 String getDisabledMessage(const String& featureName)
 {
     // TODO(chasej): Update message with URL to experiments site, when live
@@ -74,7 +70,7 @@
 
 bool OriginTrialContext::hasValidToken(Vector<String> tokens, const String& featureName, String* errorMessage, WebTrialTokenValidator* validator)
 {
-    String origin = getCurrentOrigin(getExecutionContext());
+    WebSecurityOrigin origin(getExecutionContext()->getSecurityOrigin());
 
     for (const String& token : tokens) {
         // Check with the validator service to verify the signature.
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp b/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
index cad84e14..c7ebd46 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
@@ -40,7 +40,7 @@
     ~MockTokenValidator() override {}
 
     // blink::WebTrialTokenValidator implementation
-    bool validateToken(const blink::WebString& token, const blink::WebString& origin, const blink::WebString& featureName) override
+    bool validateToken(const blink::WebString& token, const blink::WebSecurityOrigin& origin, const blink::WebString& featureName) override
     {
         m_callCount++;
         return m_response;
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index 0abda3e..9ec2a23 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -699,7 +699,7 @@
     ASSERT(element);
     ImageResource* cachedImage = getImageResource(element);
     return (cachedImage && !cachedImage->errorOccurred()) ?
-        cachedImage->image() : nullptr;
+        cachedImage->getImage() : nullptr;
 }
 
 static void prepareDataTransferForImageDrag(LocalFrame* source, DataTransfer* dataTransfer, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
diff --git a/third_party/WebKit/Source/core/page/PageAnimator.cpp b/third_party/WebKit/Source/core/page/PageAnimator.cpp
index 1ef8264f..ee1d79ba 100644
--- a/third_party/WebKit/Source/core/page/PageAnimator.cpp
+++ b/third_party/WebKit/Source/core/page/PageAnimator.cpp
@@ -48,7 +48,7 @@
         if (document->view()) {
             if (document->view()->shouldThrottleRendering())
                 continue;
-            document->view()->scrollableArea()->serviceScrollAnimations(monotonicAnimationStartTime);
+            document->view()->getScrollableArea()->serviceScrollAnimations(monotonicAnimationStartTime);
 
             if (const FrameView::ScrollableAreaSet* animatingScrollableAreas = document->view()->animatingScrollableAreas()) {
                 // Iterate over a copy, since ScrollableAreas may deregister
diff --git a/third_party/WebKit/Source/core/page/PrintContext.cpp b/third_party/WebKit/Source/core/page/PrintContext.cpp
index 205a8a6..16605c0 100644
--- a/third_party/WebKit/Source/core/page/PrintContext.cpp
+++ b/third_party/WebKit/Source/core/page/PrintContext.cpp
@@ -275,9 +275,9 @@
     if (!strcmp(propertyName, "line-height"))
         return String::number(style->lineHeight().value());
     if (!strcmp(propertyName, "font-size"))
-        return String::number(style->fontDescription().computedPixelSize());
+        return String::number(style->getFontDescription().computedPixelSize());
     if (!strcmp(propertyName, "font-family"))
-        return style->fontDescription().family().family().string();
+        return style->getFontDescription().family().family().string();
     if (!strcmp(propertyName, "size"))
         return String::number(style->pageSize().width()) + ' ' + String::number(style->pageSize().height());
 
diff --git a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
index 78be6ff..a3efe2d 100644
--- a/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
+++ b/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
@@ -159,7 +159,7 @@
     // exposed after we scroll. Adjust the viewport to post-scrolling position.
     // If the container has overflow:hidden, we cannot scroll, so we do not pass direction
     // and we do not adjust for scrolling.
-    int pixelsPerLineStep = ScrollableArea::pixelsPerLineStep(frameView->hostWindow());
+    int pixelsPerLineStep = ScrollableArea::pixelsPerLineStep(frameView->getHostWindow());
     switch (type) {
     case WebFocusTypeLeft:
         containerViewportRect.setX(containerViewportRect.x() - pixelsPerLineStep);
@@ -197,7 +197,7 @@
     if (frame && canScrollInDirection(frame->document(), type)) {
         int dx = 0;
         int dy = 0;
-        int pixelsPerLineStep = ScrollableArea::pixelsPerLineStep(frame->view()->hostWindow());
+        int pixelsPerLineStep = ScrollableArea::pixelsPerLineStep(frame->view()->getHostWindow());
         switch (type) {
         case WebFocusTypeLeft:
             dx = - pixelsPerLineStep;
@@ -236,7 +236,7 @@
         int dy = 0;
         // TODO(leviw): Why are these values truncated (toInt) instead of rounding?
         FrameView* frameView = container->document().view();
-        int pixelsPerLineStep = ScrollableArea::pixelsPerLineStep(frameView ? frameView->hostWindow() : nullptr);
+        int pixelsPerLineStep = ScrollableArea::pixelsPerLineStep(frameView ? frameView->getHostWindow() : nullptr);
         switch (type) {
         case WebFocusTypeLeft:
             dx = - std::min(pixelsPerLineStep, container->layoutBox()->scrollLeft().toInt());
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index b9b19b90..a301b9e 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -675,7 +675,7 @@
     if (WebLayer* scrollLayer = toWebLayer(layer)) {
         m_lastMainThreadScrollingReasons = mainThreadScrollingReasons;
         if (mainThreadScrollingReasons) {
-            if (ScrollAnimatorBase* scrollAnimator = layer->scrollableArea()->existingScrollAnimator())
+            if (ScrollAnimatorBase* scrollAnimator = layer->getScrollableArea()->existingScrollAnimator())
                 scrollAnimator->takeoverCompositorAnimation();
             scrollLayer->addMainThreadScrollingReasons(mainThreadScrollingReasons);
         } else {
@@ -754,7 +754,7 @@
     if (const FrameView::ResizerAreaSet* resizerAreas = frameView->resizerAreas()) {
         for (const LayoutBox* box : *resizerAreas) {
             IntRect bounds = box->absoluteBoundingBoxRect();
-            IntRect corner = box->layer()->scrollableArea()->touchResizerCornerRect(bounds);
+            IntRect corner = box->layer()->getScrollableArea()->touchResizerCornerRect(bounds);
             corner.moveBy(offset);
             shouldHandleScrollGestureOnMainThreadRegion.unite(corner);
         }
@@ -895,7 +895,7 @@
 
     // FIXME(305811): Refactor for OOPI.
     LayoutView* layoutView = m_page->deprecatedLocalMainFrame()->view()->layoutView();
-    return layoutView ? scrollableArea == layoutView->layer()->scrollableArea() : false;
+    return layoutView ? scrollableArea == layoutView->layer()->getScrollableArea() : false;
 }
 
 bool ScrollingCoordinator::isForMainFrame(ScrollableArea* scrollableArea) const
diff --git a/third_party/WebKit/Source/core/paint/BlockPainter.cpp b/third_party/WebKit/Source/core/paint/BlockPainter.cpp
index a830546..1a2509c 100644
--- a/third_party/WebKit/Source/core/paint/BlockPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BlockPainter.cpp
@@ -82,7 +82,7 @@
             clipRect.moveBy(paintOffset);
             clipRecorder.emplace(paintInfo.context, m_layoutBlock, DisplayItem::ClipScrollbarsToBoxBounds, clipRect);
         }
-        ScrollableAreaPainter(*m_layoutBlock.layer()->scrollableArea()).paintOverflowControls(paintInfo.context, roundedIntPoint(paintOffset), paintInfo.cullRect(), false /* paintingOverlayControls */);
+        ScrollableAreaPainter(*m_layoutBlock.layer()->getScrollableArea()).paintOverflowControls(paintInfo.context, roundedIntPoint(paintOffset), paintInfo.cullRect(), false /* paintingOverlayControls */);
     }
 }
 
@@ -162,9 +162,9 @@
         if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
             const auto* objectProperties = m_layoutBlock.objectPaintProperties();
             if (auto* scrollTranslation = objectProperties ? objectProperties->scrollTranslation() : nullptr) {
-                PaintChunkProperties properties(paintInfo.context.paintController().currentPaintChunkProperties());
+                PaintChunkProperties properties(paintInfo.context.getPaintController().currentPaintChunkProperties());
                 properties.transform = scrollTranslation;
-                m_scopedScrollProperty.emplace(paintInfo.context.paintController(), properties);
+                m_scopedScrollProperty.emplace(paintInfo.context.getPaintController(), properties);
                 scrolledPaintInfo.emplace(paintInfo);
                 scrolledPaintInfo->updateCullRect(scrollTranslation->matrix().toAffineTransform());
             }
diff --git a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
index 853ab4f..78113f9d 100644
--- a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
@@ -167,7 +167,7 @@
     // Expand the inner border as necessary to make it a rounded rect (i.e. radii contained within each edge).
     // This function relies on the fact we only get radii not contained within each edge if one of the radii
     // for an edge is zero, so we can shift the arc towards the zero radius corner.
-    FloatRoundedRect::Radii newRadii = innerBorder.radii();
+    FloatRoundedRect::Radii newRadii = innerBorder.getRadii();
     FloatRect newRect = innerBorder.rect();
 
     float overshoot;
@@ -729,7 +729,7 @@
     switch (side) {
     case BSTop: {
         bool usePath = m_isRounded && (borderStyleHasInnerDetail(edge.borderStyle())
-            || borderWillArcInnerEdge(m_inner.radii().topLeft(), m_inner.radii().topRight()));
+            || borderWillArcInnerEdge(m_inner.getRadii().topLeft(), m_inner.getRadii().topRight()));
         if (usePath)
             path = &borderInfo.roundedBorderPath;
         else
@@ -741,7 +741,7 @@
     }
     case BSBottom: {
         bool usePath = m_isRounded && (borderStyleHasInnerDetail(edge.borderStyle())
-            || borderWillArcInnerEdge(m_inner.radii().bottomLeft(), m_inner.radii().bottomRight()));
+            || borderWillArcInnerEdge(m_inner.getRadii().bottomLeft(), m_inner.getRadii().bottomRight()));
         if (usePath)
             path = &borderInfo.roundedBorderPath;
         else
@@ -753,7 +753,7 @@
     }
     case BSLeft: {
         bool usePath = m_isRounded && (borderStyleHasInnerDetail(edge.borderStyle())
-            || borderWillArcInnerEdge(m_inner.radii().bottomLeft(), m_inner.radii().topLeft()));
+            || borderWillArcInnerEdge(m_inner.getRadii().bottomLeft(), m_inner.getRadii().topLeft()));
         if (usePath)
             path = &borderInfo.roundedBorderPath;
         else
@@ -765,7 +765,7 @@
     }
     case BSRight: {
         bool usePath = m_isRounded && (borderStyleHasInnerDetail(edge.borderStyle())
-            || borderWillArcInnerEdge(m_inner.radii().bottomRight(), m_inner.radii().topRight()));
+            || borderWillArcInnerEdge(m_inner.getRadii().bottomRight(), m_inner.getRadii().topRight()));
         if (usePath)
             path = &borderInfo.roundedBorderPath;
         else
@@ -1042,25 +1042,25 @@
         quad[2] = FloatPoint(innerRect.maxXMinYCorner());
         quad[3] = FloatPoint(outerRect.maxXMinYCorner());
 
-        if (!m_inner.radii().topLeft().isZero()) {
+        if (!m_inner.getRadii().topLeft().isZero()) {
             findIntersection(quad[0], quad[1],
                 FloatPoint(
-                    quad[1].x() + m_inner.radii().topLeft().width(),
+                    quad[1].x() + m_inner.getRadii().topLeft().width(),
                     quad[1].y()),
                 FloatPoint(
                     quad[1].x(),
-                    quad[1].y() + m_inner.radii().topLeft().height()),
+                    quad[1].y() + m_inner.getRadii().topLeft().height()),
                 quad[1]);
         }
 
-        if (!m_inner.radii().topRight().isZero()) {
+        if (!m_inner.getRadii().topRight().isZero()) {
             findIntersection(quad[3], quad[2],
                 FloatPoint(
-                    quad[2].x() - m_inner.radii().topRight().width(),
+                    quad[2].x() - m_inner.getRadii().topRight().width(),
                     quad[2].y()),
                 FloatPoint(
                     quad[2].x(),
-                    quad[2].y() + m_inner.radii().topRight().height()),
+                    quad[2].y() + m_inner.getRadii().topRight().height()),
                 quad[2]);
         }
         break;
@@ -1071,25 +1071,25 @@
         quad[2] = FloatPoint(innerRect.minXMaxYCorner());
         quad[3] = FloatPoint(outerRect.minXMaxYCorner());
 
-        if (!m_inner.radii().topLeft().isZero()) {
+        if (!m_inner.getRadii().topLeft().isZero()) {
             findIntersection(quad[0], quad[1],
                 FloatPoint(
-                    quad[1].x() + m_inner.radii().topLeft().width(),
+                    quad[1].x() + m_inner.getRadii().topLeft().width(),
                     quad[1].y()),
                 FloatPoint(
                     quad[1].x(),
-                    quad[1].y() + m_inner.radii().topLeft().height()),
+                    quad[1].y() + m_inner.getRadii().topLeft().height()),
                 quad[1]);
         }
 
-        if (!m_inner.radii().bottomLeft().isZero()) {
+        if (!m_inner.getRadii().bottomLeft().isZero()) {
             findIntersection(quad[3], quad[2],
                 FloatPoint(
-                    quad[2].x() + m_inner.radii().bottomLeft().width(),
+                    quad[2].x() + m_inner.getRadii().bottomLeft().width(),
                     quad[2].y()),
                 FloatPoint(
                     quad[2].x(),
-                    quad[2].y() - m_inner.radii().bottomLeft().height()),
+                    quad[2].y() - m_inner.getRadii().bottomLeft().height()),
                 quad[2]);
         }
         break;
@@ -1100,25 +1100,25 @@
         quad[2] = FloatPoint(innerRect.maxXMaxYCorner());
         quad[3] = FloatPoint(outerRect.maxXMaxYCorner());
 
-        if (!m_inner.radii().bottomLeft().isZero()) {
+        if (!m_inner.getRadii().bottomLeft().isZero()) {
             findIntersection(quad[0], quad[1],
                 FloatPoint(
-                    quad[1].x() + m_inner.radii().bottomLeft().width(),
+                    quad[1].x() + m_inner.getRadii().bottomLeft().width(),
                     quad[1].y()),
                 FloatPoint(
                     quad[1].x(),
-                    quad[1].y() - m_inner.radii().bottomLeft().height()),
+                    quad[1].y() - m_inner.getRadii().bottomLeft().height()),
                 quad[1]);
         }
 
-        if (!m_inner.radii().bottomRight().isZero()) {
+        if (!m_inner.getRadii().bottomRight().isZero()) {
             findIntersection(quad[3], quad[2],
                 FloatPoint(
-                    quad[2].x() - m_inner.radii().bottomRight().width(),
+                    quad[2].x() - m_inner.getRadii().bottomRight().width(),
                     quad[2].y()),
                 FloatPoint(
                     quad[2].x(),
-                    quad[2].y() - m_inner.radii().bottomRight().height()),
+                    quad[2].y() - m_inner.getRadii().bottomRight().height()),
                 quad[2]);
         }
         break;
@@ -1129,25 +1129,25 @@
         quad[2] = FloatPoint(innerRect.maxXMaxYCorner());
         quad[3] = FloatPoint(outerRect.maxXMaxYCorner());
 
-        if (!m_inner.radii().topRight().isZero()) {
+        if (!m_inner.getRadii().topRight().isZero()) {
             findIntersection(quad[0], quad[1],
                 FloatPoint(
-                    quad[1].x() - m_inner.radii().topRight().width(),
+                    quad[1].x() - m_inner.getRadii().topRight().width(),
                     quad[1].y()),
                 FloatPoint(
                     quad[1].x(),
-                    quad[1].y() + m_inner.radii().topRight().height()),
+                    quad[1].y() + m_inner.getRadii().topRight().height()),
                 quad[1]);
         }
 
-        if (!m_inner.radii().bottomRight().isZero()) {
+        if (!m_inner.getRadii().bottomRight().isZero()) {
             findIntersection(quad[3], quad[2],
                 FloatPoint(
-                    quad[2].x() - m_inner.radii().bottomRight().width(),
+                    quad[2].x() - m_inner.getRadii().bottomRight().width(),
                     quad[2].y()),
                 FloatPoint(
                     quad[2].x(),
-                    quad[2].y() - m_inner.radii().bottomRight().height()),
+                    quad[2].y() - m_inner.getRadii().bottomRight().height()),
                 quad[2]);
         }
         break;
diff --git a/third_party/WebKit/Source/core/paint/BoxClipper.cpp b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
index ec86a5a..0e767d5 100644
--- a/third_party/WebKit/Source/core/paint/BoxClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxClipper.cpp
@@ -28,9 +28,9 @@
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
         const auto* objectProperties = m_box.objectPaintProperties();
         if (objectProperties && objectProperties->overflowClip()) {
-            PaintChunkProperties properties(paintInfo.context.paintController().currentPaintChunkProperties());
+            PaintChunkProperties properties(paintInfo.context.getPaintController().currentPaintChunkProperties());
             properties.clip = objectProperties->overflowClip();
-            m_scopedClipProperty.emplace(paintInfo.context.paintController(), properties);
+            m_scopedClipProperty.emplace(paintInfo.context.getPaintController(), properties);
         }
         return;
     }
@@ -63,12 +63,12 @@
             return;
     }
 
-    if (!m_paintInfo.context.paintController().displayItemConstructionIsDisabled()) {
+    if (!m_paintInfo.context.getPaintController().displayItemConstructionIsDisabled()) {
         m_clipType = m_paintInfo.displayItemTypeForClipping();
         Vector<FloatRoundedRect> roundedRects;
         if (hasBorderRadius)
             roundedRects.append(clipRoundedRect);
-        m_paintInfo.context.paintController().createAndAppend<ClipDisplayItem>(m_box, m_clipType, pixelSnappedIntRect(clipRect), roundedRects);
+        m_paintInfo.context.getPaintController().createAndAppend<ClipDisplayItem>(m_box, m_clipType, pixelSnappedIntRect(clipRect), roundedRects);
     }
 }
 
@@ -78,7 +78,7 @@
         return;
 
     ASSERT(m_box.hasControlClip() || (m_box.hasOverflowClip() && !m_box.layer()->isSelfPaintingLayer()) || m_box.style()->containsPaint());
-    m_paintInfo.context.paintController().endItem<EndClipDisplayItem>(m_box, DisplayItem::clipTypeToEndClipType(m_clipType));
+    m_paintInfo.context.getPaintController().endItem<EndClipDisplayItem>(m_box, DisplayItem::clipTypeToEndClipType(m_clipType));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/BoxPainter.cpp b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
index d1d135e..609fa400 100644
--- a/third_party/WebKit/Source/core/paint/BoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxPainter.cpp
@@ -230,7 +230,7 @@
     if (box && (box->nextLineBox() || box->prevLineBox())) {
         FloatRoundedRect segmentBorder = obj.style()->getRoundedBorderFor(LayoutRect(0, 0, inlineBoxWidth, inlineBoxHeight),
             includeLogicalLeftEdge, includeLogicalRightEdge);
-        border.setRadii(segmentBorder.radii());
+        border.setRadii(segmentBorder.getRadii());
     }
     return border;
 }
@@ -267,7 +267,7 @@
             includeLogicalLeftEdge, includeLogicalRightEdge);
         FloatRect insetRect(backgroundRoundedRect.rect());
         insetRect.expand(insets);
-        FloatRoundedRect::Radii insetRadii(backgroundRoundedRect.radii());
+        FloatRoundedRect::Radii insetRadii(backgroundRoundedRect.getRadii());
         insetRadii.shrink(-insets.top(), -insets.bottom(), -insets.left(), -insets.right());
         return FloatRoundedRect(insetRect, insetRadii);
     }
@@ -651,7 +651,7 @@
             context.setShadow(shadowOffset, shadowBlur, shadowColor, DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha, DrawShadowOnly);
 
             if (hasBorderRadius) {
-                FloatRoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(shadowRect)), border.radii());
+                FloatRoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(shadowRect)), border.getRadii());
                 float changeAmount = 2 * shadowBlur + shadowSpread;
                 if (changeAmount >= 0)
                     influenceRect.expandRadii(changeAmount);
diff --git a/third_party/WebKit/Source/core/paint/EllipsisBoxPainter.cpp b/third_party/WebKit/Source/core/paint/EllipsisBoxPainter.cpp
index 1e44f600..835cc37 100644
--- a/third_party/WebKit/Source/core/paint/EllipsisBoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/EllipsisBoxPainter.cpp
@@ -59,7 +59,7 @@
         textStyle = TextPainter::selectionPaintingStyle(m_ellipsisBox.getLineLayoutItem(), true, paintInfo, textStyle);
 
     TextRun textRun = constructTextRun(font, m_ellipsisBox.ellipsisStr(), style, TextRun::AllowTrailingExpansion);
-    LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());
+    LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.getFontMetrics().ascent());
     TextPainter textPainter(context, font, textRun, textOrigin, boxRect, m_ellipsisBox.isHorizontal());
     textPainter.paint(0, m_ellipsisBox.ellipsisStr().length(), m_ellipsisBox.ellipsisStr().length(), textStyle);
 }
diff --git a/third_party/WebKit/Source/core/paint/EmbeddedObjectPainter.cpp b/third_party/WebKit/Source/core/paint/EmbeddedObjectPainter.cpp
index 1991d67..3b142e0e 100644
--- a/third_party/WebKit/Source/core/paint/EmbeddedObjectPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/EmbeddedObjectPainter.cpp
@@ -59,7 +59,7 @@
     if (!font.primaryFont())
         return;
     TextRun textRun(m_layoutEmbeddedObject.unavailablePluginReplacementText());
-    FloatSize textGeometry(font.width(textRun), font.fontMetrics().height());
+    FloatSize textGeometry(font.width(textRun), font.getFontMetrics().height());
 
     LayoutRect backgroundRect(0, 0, textGeometry.width() + 2 * replacementTextRoundedRectLeftRightTextMargin, replacementTextRoundedRectHeight);
     backgroundRect.move(contentRect.center() - backgroundRect.center());
@@ -75,7 +75,7 @@
     TextRunPaintInfo runInfo(textRun);
     runInfo.bounds = floatBackgroundRect;
     context.setFillColor(scaleAlpha(Color::black, replacementTextTextOpacity));
-    context.drawBidiText(font, runInfo, textRect.location() + FloatSize(0, font.fontMetrics().ascent()));
+    context.drawBidiText(font, runInfo, textRect.location() + FloatSize(0, font.getFontMetrics().ascent()));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/FileUploadControlPainter.cpp b/third_party/WebKit/Source/core/paint/FileUploadControlPainter.cpp
index e7fa7320..2c113ab 100644
--- a/third_party/WebKit/Source/core/paint/FileUploadControlPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/FileUploadControlPainter.cpp
@@ -62,8 +62,8 @@
             textY = LayoutUnit(m_layoutFileUploadControl.baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine));
         TextRunPaintInfo textRunPaintInfo(textRun);
         // FIXME: Shouldn't these offsets be rounded? crbug.com/350474
-        textRunPaintInfo.bounds = FloatRect(textX.toFloat(), textY.toFloat() - m_layoutFileUploadControl.style()->fontMetrics().ascent(),
-            textWidth, m_layoutFileUploadControl.style()->fontMetrics().height());
+        textRunPaintInfo.bounds = FloatRect(textX.toFloat(), textY.toFloat() - m_layoutFileUploadControl.style()->getFontMetrics().ascent(),
+            textWidth, m_layoutFileUploadControl.style()->getFontMetrics().height());
 
         // Draw the filename.
         LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutFileUploadControl, paintInfo.phase, textRunPaintInfo.bounds);
diff --git a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
index 5240e44..0f986aaf 100644
--- a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
@@ -134,7 +134,7 @@
 {
     // Create a parent filter for shorthand filters. These have already been scaled by the CSS code for page zoom, so scale is 1.0 here.
     RefPtrWillBeRawPtr<Filter> parentFilter = Filter::create(1.0f);
-    RefPtrWillBeRawPtr<FilterEffect> previousEffect = parentFilter->sourceGraphic();
+    RefPtrWillBeRawPtr<FilterEffect> previousEffect = parentFilter->getSourceGraphic();
     for (size_t i = 0; i < operations.operations().size(); ++i) {
         RefPtrWillBeRawPtr<FilterEffect> effect = nullptr;
         FilterOperation* filterOperation = operations.operations().at(i).get();
diff --git a/third_party/WebKit/Source/core/paint/FilterPainter.cpp b/third_party/WebKit/Source/core/paint/FilterPainter.cpp
index 04fa83e..b646c22 100644
--- a/third_party/WebKit/Source/core/paint/FilterPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/FilterPainter.cpp
@@ -60,7 +60,7 @@
     }
 
     ASSERT(m_layoutObject);
-    if (!context.paintController().displayItemConstructionIsDisabled()) {
+    if (!context.getPaintController().displayItemConstructionIsDisabled()) {
         FilterOperations filterOperations(layer.computeFilterOperations(m_layoutObject->styleRef()));
         OwnPtr<CompositorFilterOperations> compositorFilterOperations = adoptPtr(CompositorFactory::current().createFilterOperations());
         builder.buildFilterOperations(filterOperations, compositorFilterOperations.get());
@@ -76,7 +76,7 @@
             visualBounds.moveBy(-offsetFromRoot);
             layer.convertFromFlowThreadToVisualBoundingBoxInAncestor(paintingInfo.rootLayer, visualBounds);
         }
-        context.paintController().createAndAppend<BeginFilterDisplayItem>(*m_layoutObject, imageFilter, FloatRect(visualBounds), compositorFilterOperations.release());
+        context.getPaintController().createAndAppend<BeginFilterDisplayItem>(*m_layoutObject, imageFilter, FloatRect(visualBounds), compositorFilterOperations.release());
     }
 
     m_filterInProgress = true;
@@ -87,7 +87,7 @@
     if (!m_filterInProgress)
         return;
 
-    m_context.paintController().endItem<EndFilterDisplayItem>(*m_layoutObject);
+    m_context.getPaintController().endItem<EndFilterDisplayItem>(*m_layoutObject);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp b/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp
index 13648cc..01723f1 100644
--- a/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/FloatClipRecorder.cpp
@@ -15,13 +15,13 @@
     , m_client(client)
     , m_clipType(DisplayItem::paintPhaseToFloatClipType(paintPhase))
 {
-    m_context.paintController().createAndAppend<FloatClipDisplayItem>(m_client, m_clipType, clipRect);
+    m_context.getPaintController().createAndAppend<FloatClipDisplayItem>(m_client, m_clipType, clipRect);
 }
 
 FloatClipRecorder::~FloatClipRecorder()
 {
     DisplayItem::Type endType = DisplayItem::floatClipTypeToEndFloatClipType(m_clipType);
-    m_context.paintController().endItem<EndFloatClipDisplayItem>(m_client, endType);
+    m_context.getPaintController().endItem<EndFloatClipDisplayItem>(m_client, endType);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/FramePainter.cpp b/third_party/WebKit/Source/core/paint/FramePainter.cpp
index 374539a..461c44c 100644
--- a/third_party/WebKit/Source/core/paint/FramePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/FramePainter.cpp
@@ -49,12 +49,12 @@
             TransformPaintPropertyNode* transform = m_frameView->scrollTranslation() ? m_frameView->scrollTranslation() : m_frameView->preTranslation();
             ClipPaintPropertyNode* clip = m_frameView->contentClip();
             if (transform || clip) {
-                PaintChunkProperties properties(context.paintController().currentPaintChunkProperties());
+                PaintChunkProperties properties(context.getPaintController().currentPaintChunkProperties());
                 if (transform)
                     properties.transform = transform;
                 if (clip)
                     properties.clip = clip;
-                scopedPaintChunkProperties.emplace(context.paintController(), properties);
+                scopedPaintChunkProperties.emplace(context.getPaintController(), properties);
             }
         }
 
@@ -76,9 +76,9 @@
         Optional<ScopedPaintChunkProperties> scopedPaintChunkProperties;
         if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
             if (TransformPaintPropertyNode* transform = m_frameView->preTranslation()) {
-                PaintChunkProperties properties(context.paintController().currentPaintChunkProperties());
+                PaintChunkProperties properties(context.getPaintController().currentPaintChunkProperties());
                 properties.transform = transform;
-                scopedPaintChunkProperties.emplace(context.paintController(), properties);
+                scopedPaintChunkProperties.emplace(context.getPaintController(), properties);
             }
         }
 
diff --git a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
index cd1d35b..ccdccfa 100644
--- a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
@@ -151,7 +151,7 @@
     // Set our font.
     const Font& font = styleToUse.font();
 
-    LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());
+    LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.getFontMetrics().ascent());
 
     // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection
     // and composition highlights.
@@ -422,7 +422,7 @@
     // So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so
     // we pin to two pixels under the baseline.
     int lineThickness = misspellingLineThickness;
-    int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isFirstLineStyle())->fontMetrics().ascent();
+    int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isFirstLineStyle())->getFontMetrics().ascent();
     int descent = m_inlineTextBox.logicalHeight() - baseline;
     int underlineOffset;
     if (descent <= (lineThickness + 2)) {
@@ -753,14 +753,14 @@
     bool isPrinting = paintInfo.isPrinting();
 
     const ComputedStyle& styleToUse = textBoxLayoutObject.styleRef(m_inlineTextBox.isFirstLineStyle());
-    float baseline = styleToUse.fontMetrics().ascent();
+    float baseline = styleToUse.getFontMetrics().ascent();
 
     // Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px.
     // Using computedFontSize should take care of zoom as well.
 
     // Update Underline thickness, in case we have Faulty Font Metrics calculating underline thickness by old method.
-    float textDecorationThickness = styleToUse.fontMetrics().underlineThickness();
-    int fontHeightInt  = (int)(styleToUse.fontMetrics().floatHeight() + 0.5);
+    float textDecorationThickness = styleToUse.getFontMetrics().underlineThickness();
+    int fontHeightInt  = (int)(styleToUse.getFontMetrics().floatHeight() + 0.5);
     if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHeightInt >> 1)))
         textDecorationThickness = std::max(1.f, styleToUse.computedFontSize() / 10.f);
 
@@ -772,7 +772,7 @@
     float doubleOffset = textDecorationThickness + 1.f;
 
     if (deco & TextDecorationUnderline) {
-        const int underlineOffset = computeUnderlineOffset(styleToUse.getTextUnderlinePosition(), styleToUse.fontMetrics(), &m_inlineTextBox, textDecorationThickness);
+        const int underlineOffset = computeUnderlineOffset(styleToUse.getTextUnderlinePosition(), styleToUse.getFontMetrics(), &m_inlineTextBox, textDecorationThickness);
         paintAppliedDecoration(context, FloatPoint(localOrigin) + FloatPoint(0, underlineOffset), width.toFloat(), doubleOffset, 1, underline, textDecorationThickness, antialiasDecoration, isPrinting);
     }
     if (deco & TextDecorationOverline) {
@@ -813,7 +813,7 @@
     // All other marked text underlines are 1px thick.
     // If there's not enough space the underline will touch or overlap characters.
     int lineThickness = 1;
-    int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isFirstLineStyle())->fontMetrics().ascent();
+    int baseline = m_inlineTextBox.getLineLayoutItem().style(m_inlineTextBox.isFirstLineStyle())->getFontMetrics().ascent();
     if (underline.thick && m_inlineTextBox.logicalHeight() - baseline >= 2)
         lineThickness = 2;
 
@@ -846,7 +846,7 @@
     textStyle.shadow = 0;
 
     LayoutRect boxRect(boxOrigin, LayoutSize(m_inlineTextBox.logicalWidth(), m_inlineTextBox.logicalHeight()));
-    LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());
+    LayoutPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.getFontMetrics().ascent());
     TextPainter textPainter(paintInfo.context, font, run, textOrigin, boxRect, m_inlineTextBox.isHorizontal());
 
     textPainter.paint(sPos, ePos, m_inlineTextBox.len(), textStyle, 0);
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
index 5bd6b53b..44470cc 100644
--- a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
@@ -27,7 +27,7 @@
         collectRoundedRectClips(*layoutObject.layer(), *localPaintingInfo, graphicsContext, fragmentOffset, paintFlags, rule, roundedRects);
     }
 
-    m_graphicsContext.paintController().createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, snappedClipRect, roundedRects);
+    m_graphicsContext.getPaintController().createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, snappedClipRect, roundedRects);
 }
 
 static bool inContainingBlockChain(PaintLayer* startLayer, PaintLayer* endLayer)
@@ -75,7 +75,7 @@
 
 LayerClipRecorder::~LayerClipRecorder()
 {
-    m_graphicsContext.paintController().endItem<EndClipDisplayItem>(m_layoutObject, DisplayItem::clipTypeToEndClipType(m_clipType));
+    m_graphicsContext.getPaintController().endItem<EndClipDisplayItem>(m_layoutObject, DisplayItem::clipTypeToEndClipType(m_clipType));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp
index d72f483..11538857 100644
--- a/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/LayerClipRecorderTest.cpp
@@ -24,7 +24,7 @@
 
 protected:
     LayoutView& layoutView() { return *m_layoutView; }
-    PaintController& rootPaintController() { return layoutView().layer()->graphicsLayerBacking()->paintController(); }
+    PaintController& rootPaintController() { return layoutView().layer()->graphicsLayerBacking()->getPaintController(); }
 
 private:
     void SetUp() override
@@ -62,25 +62,25 @@
     rootPaintController().invalidateAll();
     GraphicsContext context(rootPaintController());
     LayoutRect bound = layoutView().viewRect();
-    EXPECT_EQ((size_t)0, rootPaintController().displayItemList().size());
+    EXPECT_EQ((size_t)0, rootPaintController().getDisplayItemList().size());
 
     drawRectInClip(context, layoutView(), PaintPhaseForeground, bound);
     rootPaintController().commitNewDisplayItems();
-    EXPECT_EQ((size_t)3, rootPaintController().displayItemList().size());
-    EXPECT_TRUE(DisplayItem::isClipType(rootPaintController().displayItemList()[0].getType()));
-    EXPECT_TRUE(DisplayItem::isDrawingType(rootPaintController().displayItemList()[1].getType()));
-    EXPECT_TRUE(DisplayItem::isEndClipType(rootPaintController().displayItemList()[2].getType()));
+    EXPECT_EQ((size_t)3, rootPaintController().getDisplayItemList().size());
+    EXPECT_TRUE(DisplayItem::isClipType(rootPaintController().getDisplayItemList()[0].getType()));
+    EXPECT_TRUE(DisplayItem::isDrawingType(rootPaintController().getDisplayItemList()[1].getType()));
+    EXPECT_TRUE(DisplayItem::isEndClipType(rootPaintController().getDisplayItemList()[2].getType()));
 }
 
 TEST_F(LayerClipRecorderTest, Empty)
 {
     rootPaintController().invalidateAll();
     GraphicsContext context(rootPaintController());
-    EXPECT_EQ((size_t)0, rootPaintController().displayItemList().size());
+    EXPECT_EQ((size_t)0, rootPaintController().getDisplayItemList().size());
 
     drawEmptyClip(context, layoutView(), PaintPhaseForeground);
     rootPaintController().commitNewDisplayItems();
-    EXPECT_EQ((size_t)0, rootPaintController().displayItemList().size());
+    EXPECT_EQ((size_t)0, rootPaintController().getDisplayItemList().size());
 }
 
 } // namespace
diff --git a/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp b/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp
index f71616f..5bd3b81 100644
--- a/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp
+++ b/third_party/WebKit/Source/core/paint/LayoutObjectDrawingRecorderTest.cpp
@@ -44,9 +44,9 @@
     LayoutRect bound = layoutView().viewRect();
     drawNothing(context, layoutView(), PaintPhaseForeground, bound);
     rootPaintController().commitNewDisplayItems();
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 1,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 1,
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground)));
-    EXPECT_FALSE(static_cast<const DrawingDisplayItem&>(rootPaintController().displayItemList()[0]).picture());
+    EXPECT_FALSE(static_cast<const DrawingDisplayItem&>(rootPaintController().getDisplayItemList()[0]).picture());
 }
 
 TEST_F(LayoutObjectDrawingRecorderTest, Rect)
@@ -56,7 +56,7 @@
     LayoutRect bound = layoutView().viewRect();
     drawRect(context, layoutView(), PaintPhaseForeground, bound);
     rootPaintController().commitNewDisplayItems();
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 1,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 1,
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground)));
 }
 
@@ -69,7 +69,7 @@
     drawRect(context, layoutView(), PaintPhaseForeground, bound);
     rootPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseSelfBlockBackgroundOnly)),
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground)));
 
@@ -82,7 +82,7 @@
 
     rootPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseSelfBlockBackgroundOnly)),
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground)));
 }
@@ -98,7 +98,7 @@
         context.drawRect(enclosedIntRect(FloatRect(bounds)));
     }
     controller.commitNewDisplayItems();
-    const auto& drawing = static_cast<const DrawingDisplayItem&>(controller.displayItemList()[0]);
+    const auto& drawing = static_cast<const DrawingDisplayItem&>(controller.getDisplayItemList()[0]);
     return drawing.picture()->cullRect();
 }
 
@@ -135,7 +135,7 @@
     }
 
     rootPaintController().commitNewDisplayItems();
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 1,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 1,
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground)));
 
     // Ensure we cannot use the cache with a new paint offset.
@@ -150,7 +150,7 @@
     }
 
     rootPaintController().commitNewDisplayItems();
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 1,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 1,
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground)));
 
     // Ensure the old paint offset cannot be used.
@@ -159,7 +159,7 @@
     // Ensure the new paint offset can be used.
     EXPECT_TRUE(LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, layoutView(), PaintPhaseForeground));
     rootPaintController().commitNewDisplayItems();
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 1,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 1,
         TestDisplayItem(layoutView(), DisplayItem::paintPhaseToDrawingType(PaintPhaseForeground)));
 }
 #endif
diff --git a/third_party/WebKit/Source/core/paint/LineBoxListPainter.cpp b/third_party/WebKit/Source/core/paint/LineBoxListPainter.cpp
index e89d9a9..8b1b926 100644
--- a/third_party/WebKit/Source/core/paint/LineBoxListPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/LineBoxListPainter.cpp
@@ -75,7 +75,7 @@
 
 void LineBoxListPainter::invalidateLineBoxPaintOffsets(const PaintInfo& paintInfo) const
 {
-    PaintController& paintController = paintInfo.context.paintController();
+    PaintController& paintController = paintInfo.context.getPaintController();
     for (InlineFlowBox* curr = m_lineBoxList.firstLineBox(); curr; curr = curr->nextLineBox())
         invalidateLineBoxPaintOffsetsInternal(paintController, curr);
 }
diff --git a/third_party/WebKit/Source/core/paint/ListMarkerPainter.cpp b/third_party/WebKit/Source/core/paint/ListMarkerPainter.cpp
index e55d405..5eda540 100644
--- a/third_party/WebKit/Source/core/paint/ListMarkerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ListMarkerPainter.cpp
@@ -113,7 +113,7 @@
 
     TextRunPaintInfo textRunPaintInfo(textRun);
     textRunPaintInfo.bounds = marker;
-    IntPoint textOrigin = IntPoint(marker.x(), marker.y() + m_layoutListMarker.style()->fontMetrics().ascent());
+    IntPoint textOrigin = IntPoint(marker.x(), marker.y() + m_layoutListMarker.style()->getFontMetrics().ascent());
 
     // Text is not arbitrary. We can judge whether it's RTL from the first character,
     // and we only need to handle the direction RightToLeft for now.
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
index afed2ed3..6f0e06e5 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -25,14 +25,14 @@
     LayoutObject& divLayoutObject = *document().body()->firstChild()->layoutObject();
     InlineTextBox& textInlineBox = *toLayoutText(div.firstChild()->layoutObject())->firstTextBox();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(textInlineBox, foregroundType));
 
     div.focus();
     document().view()->updateAllLifecyclePhases();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 3,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(textInlineBox, foregroundType),
         TestDisplayItem(divLayoutObject, DisplayItem::Caret)); // New!
@@ -46,7 +46,7 @@
     LayoutText& text = *toLayoutText(divBlock.firstChild());
     InlineTextBox& firstTextBox = *text.firstTextBox();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(firstTextBox, foregroundType));
 
@@ -57,7 +57,7 @@
     InlineTextBox& newFirstTextBox = *newText.firstTextBox();
     InlineTextBox& secondTextBox = *newText.firstTextBox()->nextTextBox();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 3,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(newFirstTextBox, foregroundType),
         TestDisplayItem(secondTextBox, foregroundType));
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
index 3476321..b0243e81 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.h
@@ -25,7 +25,7 @@
 
 protected:
     LayoutView& layoutView() { return *document().layoutView(); }
-    PaintController& rootPaintController() { return layoutView().layer()->graphicsLayerBacking()->paintController(); }
+    PaintController& rootPaintController() { return layoutView().layer()->graphicsLayerBacking()->getPaintController(); }
 
     void SetUp() override
     {
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index de95f672..6686334 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -2599,7 +2599,7 @@
 
 bool PaintLayer::scrollsOverflow() const
 {
-    if (PaintLayerScrollableArea* scrollableArea = this->scrollableArea())
+    if (PaintLayerScrollableArea* scrollableArea = this->getScrollableArea())
         return scrollableArea->scrollsOverflow();
 
     return false;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h
index c41cc1e..5c0990c 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -500,7 +500,7 @@
     void computeSelfHitTestRects(LayerHitTestRects&) const;
 
     // FIXME: This should probably return a ScrollableArea but a lot of internal methods are mistakenly exposed.
-    PaintLayerScrollableArea* scrollableArea() const { return m_scrollableArea.get(); }
+    PaintLayerScrollableArea* getScrollableArea() const { return m_scrollableArea.get(); }
 
     PaintLayerClipper clipper() const { return PaintLayerClipper(*this); }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index 1dd3743..0a6252b 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -348,13 +348,13 @@
         if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
             ObjectPaintProperties* objectPaintProperties = m_paintLayer.layoutObject()->objectPaintProperties();
             ASSERT(objectPaintProperties && objectPaintProperties->localBorderBoxProperties());
-            PaintChunkProperties properties(context.paintController().currentPaintChunkProperties());
+            PaintChunkProperties properties(context.getPaintController().currentPaintChunkProperties());
             auto& localBorderBoxProperties = *objectPaintProperties->localBorderBoxProperties();
             properties.transform = localBorderBoxProperties.transform;
             properties.clip = localBorderBoxProperties.clip;
             properties.effect = localBorderBoxProperties.effect;
             properties.backfaceHidden = m_paintLayer.layoutObject()->hasHiddenBackface();
-            scopedPaintChunkProperties.emplace(context.paintController(), properties);
+            scopedPaintChunkProperties.emplace(context.getPaintController(), properties);
         }
 
         bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
@@ -588,7 +588,7 @@
 
 void PaintLayerPainter::paintOverflowControlsForFragments(const PaintLayerFragments& layerFragments, GraphicsContext& context, const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags)
 {
-    PaintLayerScrollableArea* scrollableArea = m_paintLayer.scrollableArea();
+    PaintLayerScrollableArea* scrollableArea = m_paintLayer.getScrollableArea();
     if (!scrollableArea)
         return;
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
index a1fb8fe..b7f4bbf 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -39,7 +39,7 @@
     PaintLayer& container2Layer = *toLayoutBoxModelObject(container2).layer();
     LayoutObject& content2 = *document().getElementById("content2")->layoutObject();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 11,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
         TestDisplayItem(container1Layer, DisplayItem::Subsequence),
@@ -69,7 +69,7 @@
     if (needsCommit)
         commit();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 11,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
         TestDisplayItem(container1Layer, DisplayItem::Subsequence),
@@ -118,7 +118,7 @@
     // Container2 is partly (including its stacking chidren) in the interest rect;
     // Content2b is out of the interest rect and output nothing;
     // Container3 is partly in the interest rect.
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 15,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 15,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
         TestDisplayItem(container1Layer, DisplayItem::Subsequence),
@@ -160,7 +160,7 @@
     if (needsCommit)
         commit();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 14,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 14,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
         TestDisplayItem(container1Layer, DisplayItem::Subsequence),
@@ -198,7 +198,7 @@
     PaintLayer& container2Layer = *toLayoutBoxModelObject(container2).layer();
     LayoutObject& content2 = *document().getElementById("content2")->layoutObject();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 11,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
         TestDisplayItem(container1Layer, DisplayItem::Subsequence),
@@ -228,7 +228,7 @@
     if (needsCommit)
         commit();
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 11,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 11,
         TestDisplayItem(layoutView(), documentBackgroundType),
         TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
         TestDisplayItem(container1Layer, DisplayItem::Subsequence),
@@ -273,7 +273,7 @@
     document().view()->updateAllLifecyclePhases();
     EXPECT_FALSE(selfPaintingLayer.needsPaintPhaseDescendantOutlines());
     EXPECT_FALSE(nonSelfPaintingLayer.needsPaintPhaseDescendantOutlines());
-    EXPECT_TRUE(displayItemListContains(rootPaintController().displayItemList(), selfPaintingLayerObject, DisplayItem::paintPhaseToDrawingType(PaintPhaseSelfOutlineOnly)));
+    EXPECT_TRUE(displayItemListContains(rootPaintController().getDisplayItemList(), selfPaintingLayerObject, DisplayItem::paintPhaseToDrawingType(PaintPhaseSelfOutlineOnly)));
 
     // needsPaintPhaseDescendantOutlines should be set when any descendant on the same layer has outline.
     toHTMLElement(outlineDiv.node())->setAttribute(HTMLNames::styleAttr, styleWithOutline);
@@ -281,7 +281,7 @@
     EXPECT_TRUE(selfPaintingLayer.needsPaintPhaseDescendantOutlines());
     EXPECT_FALSE(nonSelfPaintingLayer.needsPaintPhaseDescendantOutlines());
     paint();
-    EXPECT_TRUE(displayItemListContains(rootPaintController().displayItemList(), outlineDiv, DisplayItem::paintPhaseToDrawingType(PaintPhaseSelfOutlineOnly)));
+    EXPECT_TRUE(displayItemListContains(rootPaintController().getDisplayItemList(), outlineDiv, DisplayItem::paintPhaseToDrawingType(PaintPhaseSelfOutlineOnly)));
 }
 
 TEST_P(PaintLayerPainterTest, PaintPhaseFloat)
@@ -316,7 +316,7 @@
     EXPECT_TRUE(selfPaintingLayer.needsPaintPhaseFloat());
     EXPECT_FALSE(nonSelfPaintingLayer.needsPaintPhaseFloat());
     paint();
-    EXPECT_TRUE(displayItemListContains(rootPaintController().displayItemList(), floatDiv, DisplayItem::BoxDecorationBackground));
+    EXPECT_TRUE(displayItemListContains(rootPaintController().getDisplayItemList(), floatDiv, DisplayItem::BoxDecorationBackground));
 }
 
 TEST_P(PaintLayerPainterTest, PaintPhaseBlockBackground)
@@ -350,7 +350,7 @@
     document().view()->updateAllLifecyclePhases();
     EXPECT_FALSE(selfPaintingLayer.needsPaintPhaseDescendantBlockBackgrounds());
     EXPECT_FALSE(nonSelfPaintingLayer.needsPaintPhaseDescendantBlockBackgrounds());
-    EXPECT_TRUE(displayItemListContains(rootPaintController().displayItemList(), selfPaintingLayerObject, DisplayItem::BoxDecorationBackground));
+    EXPECT_TRUE(displayItemListContains(rootPaintController().getDisplayItemList(), selfPaintingLayerObject, DisplayItem::BoxDecorationBackground));
 
     // needsPaintPhaseDescendantBlockBackgrounds should be set when any descendant on the same layer has Background.
     toHTMLElement(backgroundDiv.node())->setAttribute(HTMLNames::styleAttr, styleWithBackground);
@@ -358,7 +358,7 @@
     EXPECT_TRUE(selfPaintingLayer.needsPaintPhaseDescendantBlockBackgrounds());
     EXPECT_FALSE(nonSelfPaintingLayer.needsPaintPhaseDescendantBlockBackgrounds());
     paint();
-    EXPECT_TRUE(displayItemListContains(rootPaintController().displayItemList(), backgroundDiv, DisplayItem::BoxDecorationBackground));
+    EXPECT_TRUE(displayItemListContains(rootPaintController().getDisplayItemList(), backgroundDiv, DisplayItem::BoxDecorationBackground));
 }
 
 TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnLayerRemoval)
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index c6c9a0c..8a38345 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -175,7 +175,7 @@
     ScrollableArea::trace(visitor);
 }
 
-HostWindow* PaintLayerScrollableArea::hostWindow() const
+HostWindow* PaintLayerScrollableArea::getHostWindow() const
 {
     if (Page* page = box().frame()->page())
         return &page->chromeClient();
@@ -1453,7 +1453,7 @@
     return frame->settings()->viewportMetaEnabled();
 }
 
-Widget* PaintLayerScrollableArea::widget()
+Widget* PaintLayerScrollableArea::getWidget()
 {
     return box().frame()->view();
 }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
index 0057830..6e934157 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
@@ -172,7 +172,7 @@
     Scrollbar* horizontalScrollbar() const override { return m_scrollbarManager.horizontalScrollbar(); }
     Scrollbar* verticalScrollbar() const override { return m_scrollbarManager.verticalScrollbar(); }
 
-    HostWindow* hostWindow() const override;
+    HostWindow* getHostWindow() const override;
 
     // For composited scrolling, we allocate an extra GraphicsLayer to hold
     // onto the scrolling content. The layer can be shifted on the GPU and
@@ -332,7 +332,7 @@
     IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const;
     IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const;
 
-    Widget* widget() override;
+    Widget* getWidget() override;
     ScrollAnchor& scrollAnchor() { return m_scrollAnchor; }
     bool isPaintLayerScrollableArea() const override { return true; }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index c8b5e3cd..224f99c3 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -270,7 +270,7 @@
 
     PaintLayer* layer = toLayoutBoxModelObject(object).layer();
     ASSERT(layer);
-    DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset();
+    DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset();
     if (scrollOffset.isZero() && !layer->scrollsOverflow())
         return nullptr;
 
diff --git a/third_party/WebKit/Source/core/paint/PartPainter.cpp b/third_party/WebKit/Source/core/paint/PartPainter.cpp
index 267ce73..9df9f9a 100644
--- a/third_party/WebKit/Source/core/paint/PartPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PartPainter.cpp
@@ -92,7 +92,7 @@
     }
 
     if (m_layoutPart.canResize())
-        ScrollableAreaPainter(*m_layoutPart.layer()->scrollableArea()).paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.cullRect());
+        ScrollableAreaPainter(*m_layoutPart.layer()->getScrollableArea()).paintResizer(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.cullRect());
 }
 
 void PartPainter::paintContents(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
diff --git a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
index fe44f73..1ae620c 100644
--- a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
@@ -22,33 +22,33 @@
         roundedRectClips.append(clipRect);
     } else {
         // We create a rounded rect for each of the corners and clip it, while making sure we clip opposing corners together.
-        if (!clipRect.radii().topLeft().isEmpty() || !clipRect.radii().bottomRight().isEmpty()) {
+        if (!clipRect.getRadii().topLeft().isEmpty() || !clipRect.getRadii().bottomRight().isEmpty()) {
             FloatRect topCorner(clipRect.rect().x(), clipRect.rect().y(), rect.maxX() - clipRect.rect().x(), rect.maxY() - clipRect.rect().y());
             FloatRoundedRect::Radii topCornerRadii;
-            topCornerRadii.setTopLeft(clipRect.radii().topLeft());
+            topCornerRadii.setTopLeft(clipRect.getRadii().topLeft());
             roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii));
 
             FloatRect bottomCorner(rect.x().toFloat(), rect.y().toFloat(), clipRect.rect().maxX() - rect.x().toFloat(), clipRect.rect().maxY() - rect.y().toFloat());
             FloatRoundedRect::Radii bottomCornerRadii;
-            bottomCornerRadii.setBottomRight(clipRect.radii().bottomRight());
+            bottomCornerRadii.setBottomRight(clipRect.getRadii().bottomRight());
             roundedRectClips.append(FloatRoundedRect(bottomCorner, bottomCornerRadii));
         }
 
-        if (!clipRect.radii().topRight().isEmpty() || !clipRect.radii().bottomLeft().isEmpty()) {
+        if (!clipRect.getRadii().topRight().isEmpty() || !clipRect.getRadii().bottomLeft().isEmpty()) {
             FloatRect topCorner(rect.x().toFloat(), clipRect.rect().y(), clipRect.rect().maxX() - rect.x().toFloat(), rect.maxY() - clipRect.rect().y());
             FloatRoundedRect::Radii topCornerRadii;
-            topCornerRadii.setTopRight(clipRect.radii().topRight());
+            topCornerRadii.setTopRight(clipRect.getRadii().topRight());
             roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii));
 
             FloatRect bottomCorner(clipRect.rect().x(), rect.y().toFloat(), rect.maxX() - clipRect.rect().x(), clipRect.rect().maxY() - rect.y().toFloat());
             FloatRoundedRect::Radii bottomCornerRadii;
-            bottomCornerRadii.setBottomLeft(clipRect.radii().bottomLeft());
+            bottomCornerRadii.setBottomLeft(clipRect.getRadii().bottomLeft());
             roundedRectClips.append(FloatRoundedRect(bottomCorner, bottomCornerRadii));
         }
     }
 
     if (m_usePaintController) {
-        m_paintInfo.context.paintController().createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips);
+        m_paintInfo.context.getPaintController().createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips);
     } else {
         ClipDisplayItem clipDisplayItem(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips);
         clipDisplayItem.replay(paintInfo.context);
@@ -59,7 +59,7 @@
 {
     DisplayItem::Type endType = DisplayItem::clipTypeToEndClipType(m_clipType);
     if (m_usePaintController) {
-        m_paintInfo.context.paintController().endItem<EndClipDisplayItem>(m_layoutObject, endType);
+        m_paintInfo.context.getPaintController().endItem<EndClipDisplayItem>(m_layoutObject, endType);
     } else {
         EndClipDisplayItem endClipDisplayItem(m_layoutObject, endType);
         endClipDisplayItem.replay(m_paintInfo.context);
diff --git a/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp b/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp
index 52d1bd9..2447198 100644
--- a/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGClipPainter.cpp
@@ -56,7 +56,7 @@
     Path clipPath;
     if (m_clip.asPath(animatedLocalTransform, targetBoundingBox, clipPath)) {
         clipperState = ClipperAppliedPath;
-        context.paintController().createAndAppend<BeginClipPathDisplayItem>(target, clipPath);
+        context.getPaintController().createAndAppend<BeginClipPathDisplayItem>(target, clipPath);
         return true;
     }
 
@@ -95,7 +95,7 @@
     switch (clipperState) {
     case ClipperAppliedPath:
         // Path-only clipping, no layers to restore but we need to emit an end to the clip path display item.
-        context.paintController().endItem<EndClipPathDisplayItem>(target);
+        context.getPaintController().endItem<EndClipPathDisplayItem>(target);
         break;
     case ClipperAppliedMask:
         // Transfer content -> clip mask (SrcIn)
diff --git a/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp b/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp
index 5e97460f..a07945e5 100644
--- a/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGFilterPainter.cpp
@@ -37,7 +37,7 @@
 {
     ASSERT(filterData->m_state == FilterData::RecordingContent);
 
-    SourceGraphic* sourceGraphic = filterData->filter->sourceGraphic();
+    SourceGraphic* sourceGraphic = filterData->filter->getSourceGraphic();
     ASSERT(sourceGraphic);
 
     GraphicsContext* context = &paintingContext();
@@ -62,7 +62,7 @@
 static void paintFilteredContent(const LayoutObject& object, GraphicsContext& context, FilterData* filterData)
 {
     ASSERT(filterData->m_state == FilterData::ReadyToPaint);
-    ASSERT(filterData->filter->sourceGraphic());
+    ASSERT(filterData->filter->getSourceGraphic());
 
     filterData->m_state = FilterData::PaintingFilter;
 
@@ -133,10 +133,10 @@
     filterData->nodeMap = SVGFilterGraphNodeMap::create();
 
     IntRect sourceRegion = enclosingIntRect(intersection(filterRegion, object.strokeBoundingBox()));
-    filterData->filter->sourceGraphic()->setSourceRect(sourceRegion);
+    filterData->filter->getSourceGraphic()->setSourceRect(sourceRegion);
 
     // Create all relevant filter primitives.
-    SVGFilterBuilder builder(filterData->filter->sourceGraphic(), filterData->nodeMap.get());
+    SVGFilterBuilder builder(filterData->filter->getSourceGraphic(), filterData->nodeMap.get());
     builder.buildGraph(filterData->filter.get(), *filterElement, referenceBox);
 
     FilterEffect* lastEffect = builder.lastEffect();
diff --git a/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp b/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
index 885451b2..51a5b41e 100644
--- a/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGImagePainter.cpp
@@ -91,10 +91,10 @@
     if (cachedImage->errorOccurred())
         return FloatSize();
 
-    if (cachedImage->image()->isSVGImage())
-        return toSVGImage(cachedImage->image())->concreteObjectSize(m_layoutSVGImage.objectBoundingBox().size());
+    if (cachedImage->getImage()->isSVGImage())
+        return toSVGImage(cachedImage->getImage())->concreteObjectSize(m_layoutSVGImage.objectBoundingBox().size());
 
-    return FloatSize(cachedImage->image()->size());
+    return FloatSize(cachedImage->getImage()->size());
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp
index c8cf48f..dbd05c8 100644
--- a/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGInlineTextBoxPainter.cpp
@@ -29,7 +29,7 @@
 {
     // Font::pixelSize(), returns FontDescription::computedPixelSize(), which returns "int(x + 0.5)".
     // If the absolute font size on screen is below x=0.5, don't render anything.
-    return textLayoutObject.scaledFont().fontDescription().computedPixelSize();
+    return textLayoutObject.scaledFont().getFontDescription().computedPixelSize();
 }
 
 bool SVGInlineTextBoxPainter::shouldPaintSelection(const PaintInfo& paintInfo) const
@@ -218,7 +218,7 @@
 {
     // FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
     // Compatible with Batik/Presto
-    return font.fontDescription().computedSize() / 20.0f;
+    return font.getFontDescription().computedSize() / 20.0f;
 }
 
 void SVGInlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, TextDecoration decoration, const SVGTextFragment& fragment)
@@ -245,7 +245,7 @@
     if (thickness <= 0)
         return;
 
-    float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.fontMetrics(), thickness);
+    float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.getFontMetrics(), thickness);
     FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scalingFactor);
 
     Path path;
@@ -261,7 +261,7 @@
                 if (!SVGPaintContext::paintForLayoutObject(paintInfo, decorationStyle, *decorationLayoutObject, ApplyToFillMode, fillPaint))
                     break;
                 fillPaint.setAntiAlias(true);
-                paintInfo.context.drawPath(path.skPath(), fillPaint);
+                paintInfo.context.drawPath(path.getSkPath(), fillPaint);
             }
             break;
         case PT_STROKE:
@@ -275,7 +275,7 @@
                 if (svgDecorationStyle.vectorEffect() == VE_NON_SCALING_STROKE)
                     strokeData.setThickness(strokeData.thickness() / scalingFactor);
                 strokeData.setupPaint(&strokePaint);
-                paintInfo.context.drawPath(path.skPath(), strokePaint);
+                paintInfo.context.drawPath(path.getSkPath(), strokePaint);
             }
             break;
         case PT_MARKERS:
@@ -352,7 +352,7 @@
     textRunPaintInfo.from = startPosition;
     textRunPaintInfo.to = endPosition;
 
-    float baseline = scaledFont.fontMetrics().floatAscent();
+    float baseline = scaledFont.getFontMetrics().floatAscent();
     textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - baseline,
         textSize.width(), textSize.height());
 
diff --git a/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp b/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp
index 743965c..4dcb0d2 100644
--- a/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGMaskPainter.cpp
@@ -26,7 +26,7 @@
     if (paintInvalidationRect.isEmpty() || !m_mask.element()->hasChildren())
         return false;
 
-    context.paintController().createAndAppend<BeginCompositingDisplayItem>(object, SkXfermode::kSrcOver_Mode, 1, &paintInvalidationRect);
+    context.getPaintController().createAndAppend<BeginCompositingDisplayItem>(object, SkXfermode::kSrcOver_Mode, 1, &paintInvalidationRect);
     return true;
 }
 
@@ -43,7 +43,7 @@
         drawMaskForLayoutObject(context, object, object.objectBoundingBox(), paintInvalidationRect);
     }
 
-    context.paintController().endItem<EndCompositingDisplayItem>(object);
+    context.getPaintController().endItem<EndCompositingDisplayItem>(object);
 }
 
 void SVGMaskPainter::drawMaskForLayoutObject(GraphicsContext& context, const LayoutObject& layoutObject, const FloatRect& targetBoundingBox, const FloatRect& targetPaintInvalidationRect)
diff --git a/third_party/WebKit/Source/core/paint/SVGRootPainter.cpp b/third_party/WebKit/Source/core/paint/SVGRootPainter.cpp
index 78fcd50..55218db 100644
--- a/third_party/WebKit/Source/core/paint/SVGRootPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGRootPainter.cpp
@@ -54,7 +54,7 @@
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && !m_layoutSVGRoot.hasLayer()) {
         const auto* objectProperties = m_layoutSVGRoot.objectPaintProperties();
         if (objectProperties && objectProperties->paintOffsetTranslation()) {
-            auto& paintController = paintInfoBeforeFiltering.context.paintController();
+            auto& paintController = paintInfoBeforeFiltering.context.getPaintController();
             PaintChunkProperties properties(paintController.currentPaintChunkProperties());
             properties.transform = objectProperties->paintOffsetTranslation();
             paintOffsetTranslationPropertyScope.emplace(paintController, properties);
diff --git a/third_party/WebKit/Source/core/paint/SVGShapePainter.cpp b/third_party/WebKit/Source/core/paint/SVGShapePainter.cpp
index 4a21952..4ef9f4c4 100644
--- a/third_party/WebKit/Source/core/paint/SVGShapePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/SVGShapePainter.cpp
@@ -120,7 +120,7 @@
 class PathWithTemporaryWindingRule {
 public:
     PathWithTemporaryWindingRule(Path& path, SkPath::FillType fillType)
-        : m_path(const_cast<SkPath&>(path.skPath()))
+        : m_path(const_cast<SkPath&>(path.getSkPath()))
     {
         m_savedFillType = m_path.getFillType();
         m_path.setFillType(fillType);
@@ -130,7 +130,7 @@
         m_path.setFillType(m_savedFillType);
     }
 
-    const SkPath& skPath() const { return m_path; }
+    const SkPath& getSkPath() const { return m_path; }
 
 private:
     SkPath& m_path;
@@ -148,7 +148,7 @@
         break;
     default: {
         PathWithTemporaryWindingRule pathWithWinding(m_layoutSVGShape.path(), fillType);
-        context.drawPath(pathWithWinding.skPath(), paint);
+        context.drawPath(pathWithWinding.getSkPath(), paint);
     }
     }
 }
@@ -170,7 +170,7 @@
         Path* usePath = &m_layoutSVGShape.path();
         if (m_layoutSVGShape.hasNonScalingStroke())
             usePath = m_layoutSVGShape.nonScalingStrokePath(usePath, m_layoutSVGShape.nonScalingStrokeTransform());
-        context.drawPath(usePath->skPath(), paint);
+        context.drawPath(usePath->getSkPath(), paint);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/paint/ScopeRecorder.cpp b/third_party/WebKit/Source/core/paint/ScopeRecorder.cpp
index c3697d09..f59c4130 100644
--- a/third_party/WebKit/Source/core/paint/ScopeRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/ScopeRecorder.cpp
@@ -11,7 +11,7 @@
 namespace blink {
 
 ScopeRecorder::ScopeRecorder(GraphicsContext& context)
-    : m_paintController(context.paintController())
+    : m_paintController(context.getPaintController())
 {
     m_paintController.beginScope();
 }
diff --git a/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp b/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp
index c1d32b385..4f2af9fc0 100644
--- a/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/ScrollRecorder.cpp
@@ -15,7 +15,7 @@
     , m_beginItemType(type)
     , m_context(context)
 {
-    m_context.paintController().createAndAppend<BeginScrollDisplayItem>(m_client, m_beginItemType, currentOffset);
+    m_context.getPaintController().createAndAppend<BeginScrollDisplayItem>(m_client, m_beginItemType, currentOffset);
 }
 
 ScrollRecorder::ScrollRecorder(GraphicsContext& context, const DisplayItemClient& client, PaintPhase phase, const IntSize& currentOffset)
@@ -25,7 +25,7 @@
 
 ScrollRecorder::~ScrollRecorder()
 {
-    m_context.paintController().endItem<EndScrollDisplayItem>(m_client, DisplayItem::scrollTypeToEndScrollType(m_beginItemType));
+    m_context.getPaintController().endItem<EndScrollDisplayItem>(m_client, DisplayItem::scrollTypeToEndScrollType(m_beginItemType));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
index 32702c1..3105d7407 100644
--- a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
@@ -19,31 +19,31 @@
 
 void ScrollableAreaPainter::paintResizer(GraphicsContext& context, const IntPoint& paintOffset, const CullRect& cullRect)
 {
-    if (scrollableArea().box().style()->resize() == RESIZE_NONE)
+    if (getScrollableArea().box().style()->resize() == RESIZE_NONE)
         return;
 
-    IntRect absRect = scrollableArea().resizerCornerRect(scrollableArea().box().pixelSnappedBorderBoxRect(), ResizerForPointer);
+    IntRect absRect = getScrollableArea().resizerCornerRect(getScrollableArea().box().pixelSnappedBorderBoxRect(), ResizerForPointer);
     if (absRect.isEmpty())
         return;
     absRect.moveBy(paintOffset);
 
-    if (scrollableArea().resizer()) {
+    if (getScrollableArea().resizer()) {
         if (!cullRect.intersectsCullRect(absRect))
             return;
-        ScrollbarPainter::paintIntoRect(*scrollableArea().resizer(), context, paintOffset, LayoutRect(absRect));
+        ScrollbarPainter::paintIntoRect(*getScrollableArea().resizer(), context, paintOffset, LayoutRect(absRect));
         return;
     }
 
-    if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, scrollableArea().box(), DisplayItem::Resizer))
+    if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, getScrollableArea().box(), DisplayItem::Resizer))
         return;
 
-    LayoutObjectDrawingRecorder recorder(context, scrollableArea().box(), DisplayItem::Resizer, absRect);
+    LayoutObjectDrawingRecorder recorder(context, getScrollableArea().box(), DisplayItem::Resizer, absRect);
 
     drawPlatformResizerImage(context, absRect);
 
     // Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
     // Clipping will exclude the right and bottom edges of this frame.
-    if (!scrollableArea().hasOverlayScrollbars() && scrollableArea().hasScrollbar()) {
+    if (!getScrollableArea().hasOverlayScrollbars() && getScrollableArea().hasScrollbar()) {
         GraphicsContextStateSaver stateSaver(context);
         context.clip(absRect);
         IntRect largerCorner = absRect;
@@ -57,7 +57,7 @@
 
 void ScrollableAreaPainter::drawPlatformResizerImage(GraphicsContext& context, IntRect resizerCornerRect)
 {
-    float deviceScaleFactor = blink::deviceScaleFactor(scrollableArea().box().frame());
+    float deviceScaleFactor = blink::deviceScaleFactor(getScrollableArea().box().frame());
 
     RefPtr<Image> resizeCornerImage;
     IntSize cornerResizerSize;
@@ -72,7 +72,7 @@
         cornerResizerSize = resizeCornerImage->size();
     }
 
-    if (scrollableArea().box().shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+    if (getScrollableArea().box().shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
         context.save();
         context.translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
         context.scale(-1.0, 1.0);
@@ -87,12 +87,12 @@
 void ScrollableAreaPainter::paintOverflowControls(GraphicsContext& context, const IntPoint& paintOffset, const CullRect& cullRect, bool paintingOverlayControls)
 {
     // Don't do anything if we have no overflow.
-    if (!scrollableArea().box().hasOverflowClip())
+    if (!getScrollableArea().box().hasOverflowClip())
         return;
 
     IntPoint adjustedPaintOffset = paintOffset;
     if (paintingOverlayControls)
-        adjustedPaintOffset = scrollableArea().cachedOverlayScrollbarOffset();
+        adjustedPaintOffset = getScrollableArea().cachedOverlayScrollbarOffset();
 
     CullRect adjustedCullRect(cullRect, -adjustedPaintOffset);
 
@@ -102,17 +102,17 @@
     // that need to be painted. That will cause the second pass through the layer tree to run,
     // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the
     // second pass doesn't need to re-enter the LayoutTree to get it right.
-    if (scrollableArea().hasOverlayScrollbars() && !paintingOverlayControls) {
-        scrollableArea().setCachedOverlayScrollbarOffset(paintOffset);
+    if (getScrollableArea().hasOverlayScrollbars() && !paintingOverlayControls) {
+        getScrollableArea().setCachedOverlayScrollbarOffset(paintOffset);
         // It's not necessary to do the second pass if the scrollbars paint into layers.
-        if ((scrollableArea().horizontalScrollbar() && scrollableArea().layerForHorizontalScrollbar()) || (scrollableArea().verticalScrollbar() && scrollableArea().layerForVerticalScrollbar()))
+        if ((getScrollableArea().horizontalScrollbar() && getScrollableArea().layerForHorizontalScrollbar()) || (getScrollableArea().verticalScrollbar() && getScrollableArea().layerForVerticalScrollbar()))
             return;
         if (!overflowControlsIntersectRect(adjustedCullRect))
             return;
 
-        LayoutView* layoutView = scrollableArea().box().view();
+        LayoutView* layoutView = getScrollableArea().box().view();
 
-        PaintLayer* paintingRoot = scrollableArea().layer()->enclosingLayerWithCompositedLayerMapping(IncludeSelf);
+        PaintLayer* paintingRoot = getScrollableArea().layer()->enclosingLayerWithCompositedLayerMapping(IncludeSelf);
         if (!paintingRoot)
             paintingRoot = layoutView->layer();
 
@@ -121,21 +121,21 @@
     }
 
     // This check is required to avoid painting custom CSS scrollbars twice.
-    if (paintingOverlayControls && !scrollableArea().hasOverlayScrollbars())
+    if (paintingOverlayControls && !getScrollableArea().hasOverlayScrollbars())
         return;
 
     {
-        if (scrollableArea().horizontalScrollbar() && !scrollableArea().layerForHorizontalScrollbar()) {
-            TransformRecorder translateRecorder(context, *scrollableArea().horizontalScrollbar(), AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()));
-            scrollableArea().horizontalScrollbar()->paint(context, adjustedCullRect);
+        if (getScrollableArea().horizontalScrollbar() && !getScrollableArea().layerForHorizontalScrollbar()) {
+            TransformRecorder translateRecorder(context, *getScrollableArea().horizontalScrollbar(), AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()));
+            getScrollableArea().horizontalScrollbar()->paint(context, adjustedCullRect);
         }
-        if (scrollableArea().verticalScrollbar() && !scrollableArea().layerForVerticalScrollbar()) {
-            TransformRecorder translateRecorder(context, *scrollableArea().verticalScrollbar(), AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()));
-            scrollableArea().verticalScrollbar()->paint(context, adjustedCullRect);
+        if (getScrollableArea().verticalScrollbar() && !getScrollableArea().layerForVerticalScrollbar()) {
+            TransformRecorder translateRecorder(context, *getScrollableArea().verticalScrollbar(), AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()));
+            getScrollableArea().verticalScrollbar()->paint(context, adjustedCullRect);
         }
     }
 
-    if (scrollableArea().layerForScrollCorner())
+    if (getScrollableArea().layerForScrollCorner())
         return;
 
     // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
@@ -148,18 +148,18 @@
 
 bool ScrollableAreaPainter::overflowControlsIntersectRect(const CullRect& cullRect) const
 {
-    const IntRect borderBox = scrollableArea().box().pixelSnappedBorderBoxRect();
+    const IntRect borderBox = getScrollableArea().box().pixelSnappedBorderBoxRect();
 
-    if (cullRect.intersectsCullRect(scrollableArea().rectForHorizontalScrollbar(borderBox)))
+    if (cullRect.intersectsCullRect(getScrollableArea().rectForHorizontalScrollbar(borderBox)))
         return true;
 
-    if (cullRect.intersectsCullRect(scrollableArea().rectForVerticalScrollbar(borderBox)))
+    if (cullRect.intersectsCullRect(getScrollableArea().rectForVerticalScrollbar(borderBox)))
         return true;
 
-    if (cullRect.intersectsCullRect(scrollableArea().scrollCornerRect()))
+    if (cullRect.intersectsCullRect(getScrollableArea().scrollCornerRect()))
         return true;
 
-    if (cullRect.intersectsCullRect(scrollableArea().resizerCornerRect(borderBox, ResizerForPointer)))
+    if (cullRect.intersectsCullRect(getScrollableArea().resizerCornerRect(borderBox, ResizerForPointer)))
         return true;
 
     return false;
@@ -167,31 +167,31 @@
 
 void ScrollableAreaPainter::paintScrollCorner(GraphicsContext& context, const IntPoint& paintOffset, const CullRect& adjustedCullRect)
 {
-    IntRect absRect = scrollableArea().scrollCornerRect();
+    IntRect absRect = getScrollableArea().scrollCornerRect();
     if (absRect.isEmpty())
         return;
     absRect.moveBy(paintOffset);
 
-    if (scrollableArea().scrollCorner()) {
+    if (getScrollableArea().scrollCorner()) {
         if (!adjustedCullRect.intersectsCullRect(absRect))
             return;
-        ScrollbarPainter::paintIntoRect(*scrollableArea().scrollCorner(), context, paintOffset, LayoutRect(absRect));
+        ScrollbarPainter::paintIntoRect(*getScrollableArea().scrollCorner(), context, paintOffset, LayoutRect(absRect));
         return;
     }
 
     // We don't want to paint white if we have overlay scrollbars, since we need
     // to see what is behind it.
-    if (scrollableArea().hasOverlayScrollbars())
+    if (getScrollableArea().hasOverlayScrollbars())
         return;
 
-    if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, scrollableArea().box(), DisplayItem::ScrollbarCorner))
+    if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, getScrollableArea().box(), DisplayItem::ScrollbarCorner))
         return;
 
-    LayoutObjectDrawingRecorder recorder(context, scrollableArea().box(), DisplayItem::ScrollbarCorner, absRect);
+    LayoutObjectDrawingRecorder recorder(context, getScrollableArea().box(), DisplayItem::ScrollbarCorner, absRect);
     context.fillRect(absRect, Color::white);
 }
 
-PaintLayerScrollableArea& ScrollableAreaPainter::scrollableArea() const
+PaintLayerScrollableArea& ScrollableAreaPainter::getScrollableArea() const
 {
     return *m_scrollableArea;
 }
diff --git a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.h b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.h
index 3004a6f..9d2a23b 100644
--- a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.h
+++ b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.h
@@ -29,7 +29,7 @@
     void drawPlatformResizerImage(GraphicsContext&, IntRect resizerCornerRect);
     bool overflowControlsIntersectRect(const CullRect&) const;
 
-    PaintLayerScrollableArea& scrollableArea() const;
+    PaintLayerScrollableArea& getScrollableArea() const;
 
     RawPtrWillBeMember<PaintLayerScrollableArea> m_scrollableArea;
 };
diff --git a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
index ebf0f76..e02f482 100644
--- a/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/TableCellPainterTest.cpp
@@ -31,7 +31,7 @@
     IntRect interestRect(0, 0, 200, 200);
     paint(&interestRect);
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
         TestDisplayItem(layoutView, DisplayItem::DocumentBackground),
         TestDisplayItem(cell1, DisplayItem::TableCellBackgroundFromRow));
 
@@ -39,7 +39,7 @@
     interestRect = IntRect(0, 300, 200, 1000);
     paint(&interestRect);
 
-    EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
         TestDisplayItem(layoutView, DisplayItem::DocumentBackground),
         TestDisplayItem(cell2, DisplayItem::TableCellBackgroundFromRow));
 }
diff --git a/third_party/WebKit/Source/core/paint/TextPainter.cpp b/third_party/WebKit/Source/core/paint/TextPainter.cpp
index ba057f65..4b0bd92e 100644
--- a/third_party/WebKit/Source/core/paint/TextPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/TextPainter.cpp
@@ -47,10 +47,10 @@
     if (emphasisMark.isNull()) {
         m_emphasisMarkOffset = 0;
     } else if (position == TextEmphasisPositionOver) {
-        m_emphasisMarkOffset = -m_font.fontMetrics().ascent() - m_font.emphasisMarkDescent(emphasisMark);
+        m_emphasisMarkOffset = -m_font.getFontMetrics().ascent() - m_font.emphasisMarkDescent(emphasisMark);
     } else {
         ASSERT(position == TextEmphasisPositionUnder);
-        m_emphasisMarkOffset = m_font.fontMetrics().descent() + m_font.emphasisMarkAscent(emphasisMark);
+        m_emphasisMarkOffset = m_font.getFontMetrics().descent() + m_font.emphasisMarkAscent(emphasisMark);
     }
 }
 
@@ -221,7 +221,7 @@
 {
     ASSERT(m_combinedText);
     TextRun placeholderTextRun(&ideographicFullStopCharacter, 1);
-    FloatPoint emphasisMarkTextOrigin(m_textBounds.x().toFloat(), m_textBounds.y().toFloat() + m_font.fontMetrics().ascent() + m_emphasisMarkOffset);
+    FloatPoint emphasisMarkTextOrigin(m_textBounds.x().toFloat(), m_textBounds.y().toFloat() + m_font.getFontMetrics().ascent() + m_emphasisMarkOffset);
     TextRunPaintInfo textRunPaintInfo(placeholderTextRun);
     textRunPaintInfo.bounds = FloatRect(m_textBounds);
     m_graphicsContext.concatCTM(rotation(m_textBounds, Clockwise));
diff --git a/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp b/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp
index c188e13..3501d36 100644
--- a/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/Transform3DRecorder.cpp
@@ -26,7 +26,7 @@
     if (m_skipRecordingForIdentityTransform)
         return;
 
-    m_context.paintController().createAndAppend<BeginTransform3DDisplayItem>(m_client, m_type, transform, transformOrigin);
+    m_context.getPaintController().createAndAppend<BeginTransform3DDisplayItem>(m_client, m_type, transform, transformOrigin);
 }
 
 Transform3DRecorder::~Transform3DRecorder()
@@ -34,7 +34,7 @@
     if (m_skipRecordingForIdentityTransform)
         return;
 
-    m_context.paintController().endItem<EndTransform3DDisplayItem>(m_client, DisplayItem::transform3DTypeToEndTransform3DType(m_type));
+    m_context.getPaintController().endItem<EndTransform3DDisplayItem>(m_client, DisplayItem::transform3DTypeToEndTransform3DType(m_type));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/TransformRecorder.cpp b/third_party/WebKit/Source/core/paint/TransformRecorder.cpp
index b1079f9..f649d13c 100644
--- a/third_party/WebKit/Source/core/paint/TransformRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/TransformRecorder.cpp
@@ -19,7 +19,7 @@
     if (m_skipRecordingForIdentityTransform)
         return;
 
-    m_context.paintController().createAndAppend<BeginTransformDisplayItem>(m_client, transform);
+    m_context.getPaintController().createAndAppend<BeginTransformDisplayItem>(m_client, transform);
 }
 
 TransformRecorder::~TransformRecorder()
@@ -27,7 +27,7 @@
     if (m_skipRecordingForIdentityTransform)
         return;
 
-    m_context.paintController().endItem<EndTransformDisplayItem>(m_client);
+    m_context.getPaintController().endItem<EndTransformDisplayItem>(m_client);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
index b2c67b1..af7b78e 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamReaderTest.cpp
@@ -179,7 +179,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("AbortError: the reader is already released", onRejected);
 
@@ -208,7 +208,7 @@
 
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(result.isSet);
     EXPECT_EQ("TypeError: the reader is already released", onRejected);
@@ -250,7 +250,7 @@
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_FALSE(result.isDone);
@@ -264,7 +264,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result2.isSet);
     EXPECT_FALSE(result2.isDone);
@@ -290,7 +290,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
@@ -298,7 +298,7 @@
     EXPECT_TRUE(onRejected2.isNull());
 
     m_stream->enqueue("hello");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_FALSE(result.isDone);
@@ -308,7 +308,7 @@
     EXPECT_TRUE(onRejected2.isNull());
 
     m_stream->enqueue("world");
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result2.isSet);
     EXPECT_FALSE(result2.isDone);
@@ -330,7 +330,7 @@
     String onClosedFulfilled, onClosedRejected;
     ReadResult result;
     String onReadRejected;
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     reader->closed(getScriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected));
     reader->read(getScriptState()).then(createResultCaptor(&result), createCaptor(&onReadRejected));
     EXPECT_TRUE(onClosedFulfilled.isNull());
@@ -338,7 +338,7 @@
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onReadRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onClosedFulfilled);
     EXPECT_TRUE(onClosedRejected.isNull());
     EXPECT_TRUE(result.isSet);
@@ -361,7 +361,7 @@
 
     String onClosedFulfilled, onClosedRejected;
     String onReadFulfilled, onReadRejected;
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     reader->closed(getScriptState()).then(createCaptor(&onClosedFulfilled), createCaptor(&onClosedRejected));
     reader->read(getScriptState()).then(createCaptor(&onReadFulfilled), createCaptor(&onReadRejected));
     EXPECT_TRUE(onClosedFulfilled.isNull());
@@ -369,7 +369,7 @@
     EXPECT_TRUE(onReadFulfilled.isNull());
     EXPECT_TRUE(onReadRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onClosedFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onClosedRejected);
     EXPECT_TRUE(onReadFulfilled.isNull());
@@ -389,7 +389,7 @@
     reader->read(getScriptState()).then(createResultCaptor(&result), createCaptor(&onRejected));
     reader->read(getScriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(result2.isSet);
@@ -401,7 +401,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_TRUE(result.isDone);
@@ -427,7 +427,7 @@
     reader->read(getScriptState()).then(createCaptor(&onFulfilled), createCaptor(&onRejected));
     reader->read(getScriptState()).then(createCaptor(&onFulfilled2), createCaptor(&onRejected2));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_TRUE(onFulfilled2.isNull());
@@ -439,7 +439,7 @@
     EXPECT_TRUE(onFulfilled2.isNull());
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ(onRejected, "SyntaxError: some error");
@@ -460,7 +460,7 @@
     reader->read(getScriptState()).then(createResultCaptor(&result), createCaptor(&onRejected));
     reader->read(getScriptState()).then(createResultCaptor(&result2), createCaptor(&onRejected2));
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_FALSE(result.isSet);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(result2.isSet);
@@ -473,7 +473,7 @@
     EXPECT_FALSE(result2.isSet);
     EXPECT_TRUE(onRejected2.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(result.isSet);
     EXPECT_TRUE(result.isDone);
@@ -502,7 +502,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("TypeError: the reader is already released", onRejected);
@@ -528,7 +528,7 @@
     EXPECT_TRUE(onCancelFulfilled.isNull());
     EXPECT_TRUE(onCancelRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onClosedFulfilled);
     EXPECT_TRUE(onClosedRejected.isNull());
     EXPECT_EQ("undefined", onCancelFulfilled);
@@ -552,7 +552,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
     EXPECT_FALSE(exceptionState.hadException());
@@ -574,7 +574,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onRejected);
     EXPECT_FALSE(exceptionState.hadException());
diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
index 63aa1a25..8ee42c8 100644
--- a/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
+++ b/third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp
@@ -304,7 +304,7 @@
 
     stream->read(getScriptState());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
     EXPECT_FALSE(stream->isPulling());
@@ -335,7 +335,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
 }
@@ -358,7 +358,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("NotFoundError: error", onRejected);
 }
@@ -392,7 +392,7 @@
     EXPECT_TRUE(onCancelFulfilled.isNull());
     EXPECT_TRUE(onCancelRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onCancelFulfilled);
     EXPECT_TRUE(onCancelRejected.isNull());
 }
@@ -416,7 +416,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
 
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("TypeError: this stream is locked to a ReadableStreamReader", onRejected);
@@ -563,7 +563,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_EQ("undefined", onFulfilled);
     EXPECT_TRUE(onRejected.isNull());
 }
@@ -586,7 +586,7 @@
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_TRUE(onRejected.isNull());
 
-    isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(isolate());
     EXPECT_TRUE(onFulfilled.isNull());
     EXPECT_EQ("SyntaxError: some error", onRejected);
 }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
index 30078b0..adb73a6 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -1137,7 +1137,7 @@
     FloatRoundedRect roundedRect(pixelSnappedIntRect(innerRect));
 
     if (hasBorderRadius()) {
-        FloatRoundedRect::Radii radii = getRoundedBorderFor(borderRect).radii();
+        FloatRoundedRect::Radii radii = getRoundedBorderFor(borderRect).getRadii();
         // Insets use negative values.
         radii.shrink(
             -insets.top().toFloat(),
@@ -1282,15 +1282,15 @@
 }
 
 const Font& ComputedStyle::font() const { return inherited->font; }
-const FontMetrics& ComputedStyle::fontMetrics() const { return inherited->font.fontMetrics(); }
-const FontDescription& ComputedStyle::fontDescription() const { return inherited->font.fontDescription(); }
-float ComputedStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); }
-float ComputedStyle::computedFontSize() const { return fontDescription().computedSize(); }
-int ComputedStyle::fontSize() const { return fontDescription().computedPixelSize(); }
-float ComputedStyle::fontSizeAdjust() const { return fontDescription().sizeAdjust(); }
-bool ComputedStyle::hasFontSizeAdjust() const { return fontDescription().hasSizeAdjust(); }
-FontWeight ComputedStyle::fontWeight() const { return fontDescription().weight(); }
-FontStretch ComputedStyle::fontStretch() const { return fontDescription().stretch(); }
+const FontMetrics& ComputedStyle::getFontMetrics() const { return inherited->font.getFontMetrics(); }
+const FontDescription& ComputedStyle::getFontDescription() const { return inherited->font.getFontDescription(); }
+float ComputedStyle::specifiedFontSize() const { return getFontDescription().specifiedSize(); }
+float ComputedStyle::computedFontSize() const { return getFontDescription().computedSize(); }
+int ComputedStyle::fontSize() const { return getFontDescription().computedPixelSize(); }
+float ComputedStyle::fontSizeAdjust() const { return getFontDescription().sizeAdjust(); }
+bool ComputedStyle::hasFontSizeAdjust() const { return getFontDescription().hasSizeAdjust(); }
+FontWeight ComputedStyle::fontWeight() const { return getFontDescription().weight(); }
+FontStretch ComputedStyle::fontStretch() const { return getFontDescription().stretch(); }
 
 TextDecoration ComputedStyle::textDecorationsInEffect() const
 {
@@ -1344,12 +1344,12 @@
     variables->removeVariable(name);
 }
 
-float ComputedStyle::wordSpacing() const { return fontDescription().wordSpacing(); }
-float ComputedStyle::letterSpacing() const { return fontDescription().letterSpacing(); }
+float ComputedStyle::wordSpacing() const { return getFontDescription().wordSpacing(); }
+float ComputedStyle::letterSpacing() const { return getFontDescription().letterSpacing(); }
 
 bool ComputedStyle::setFontDescription(const FontDescription& v)
 {
-    if (inherited->font.fontDescription() != v) {
+    if (inherited->font.getFontDescription() != v) {
         inherited.access()->font = Font(v);
         return true;
     }
@@ -1365,7 +1365,7 @@
 Length ComputedStyle::lineHeight() const
 {
     const Length& lh = inherited->line_height;
-    // Unlike fontDescription().computedSize() and hence fontSize(), this is
+    // Unlike getFontDescription().computedSize() and hence fontSize(), this is
     // recalculated on demand as we only store the specified line height.
     // FIXME: Should consider scaling the fixed part of any calc expressions
     // too, though this involves messily poking into CalcExpressionLength.
@@ -1385,7 +1385,7 @@
     // Negative value means the line height is not set. Use the font's built-in
     // spacing, if avalible.
     if (lh.isNegative() && font().primaryFont())
-        return fontMetrics().lineSpacing();
+        return getFontMetrics().lineSpacing();
 
     if (lh.hasPercent())
         return minimumValueForLength(lh, LayoutUnit(computedFontSize()));
@@ -1395,8 +1395,8 @@
 
 void ComputedStyle::setWordSpacing(float wordSpacing)
 {
-    FontSelector* currentFontSelector = font().fontSelector();
-    FontDescription desc(fontDescription());
+    FontSelector* currentFontSelector = font().getFontSelector();
+    FontDescription desc(getFontDescription());
     desc.setWordSpacing(wordSpacing);
     setFontDescription(desc);
     font().update(currentFontSelector);
@@ -1404,8 +1404,8 @@
 
 void ComputedStyle::setLetterSpacing(float letterSpacing)
 {
-    FontSelector* currentFontSelector = font().fontSelector();
-    FontDescription desc(fontDescription());
+    FontSelector* currentFontSelector = font().getFontSelector();
+    FontDescription desc(getFontDescription());
     desc.setLetterSpacing(letterSpacing);
     setFontDescription(desc);
     font().update(currentFontSelector);
@@ -1423,8 +1423,8 @@
     else
         size = std::min(maximumAllowedFontSize, size);
 
-    FontSelector* currentFontSelector = font().fontSelector();
-    FontDescription desc(fontDescription());
+    FontSelector* currentFontSelector = font().getFontSelector();
+    FontDescription desc(getFontDescription());
     desc.setSpecifiedSize(size);
     desc.setComputedSize(size);
 
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index a9ebb4a..36a0222 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -594,8 +594,8 @@
     bool isFixedTableLayout() const { return tableLayout() == TableLayoutFixed && !logicalWidth().isAuto(); }
 
     const Font& font() const;
-    const FontMetrics& fontMetrics() const;
-    const FontDescription& fontDescription() const;
+    const FontMetrics& getFontMetrics() const;
+    const FontDescription& getFontDescription() const;
     float specifiedFontSize() const;
     float computedFontSize() const;
     int fontSize() const;
@@ -816,10 +816,19 @@
 
     const Vector<GridTrackSize>& gridTemplateColumns() const { return rareNonInheritedData->m_grid->m_gridTemplateColumns; }
     const Vector<GridTrackSize>& gridTemplateRows() const { return rareNonInheritedData->m_grid->m_gridTemplateRows; }
+    const Vector<GridTrackSize>& gridAutoRepeatColumns() const { return rareNonInheritedData->m_grid->m_gridAutoRepeatColumns; }
+    const Vector<GridTrackSize>& gridAutoRepeatRows() const { return rareNonInheritedData->m_grid->m_gridAutoRepeatRows; }
+    size_t gridAutoRepeatColumnsInsertionPoint() const { return rareNonInheritedData->m_grid->m_autoRepeatColumnsInsertionPoint; }
+    size_t gridAutoRepeatRowsInsertionPoint() const { return rareNonInheritedData->m_grid->m_autoRepeatRowsInsertionPoint; }
+    AutoRepeatType gridAutoRepeatType() const  { return rareNonInheritedData->m_grid->m_autoRepeatType; }
     const NamedGridLinesMap& namedGridColumnLines() const { return rareNonInheritedData->m_grid->m_namedGridColumnLines; }
     const NamedGridLinesMap& namedGridRowLines() const { return rareNonInheritedData->m_grid->m_namedGridRowLines; }
     const OrderedNamedGridLines& orderedNamedGridColumnLines() const { return rareNonInheritedData->m_grid->m_orderedNamedGridColumnLines; }
     const OrderedNamedGridLines& orderedNamedGridRowLines() const { return rareNonInheritedData->m_grid->m_orderedNamedGridRowLines; }
+    const NamedGridLinesMap& autoRepeatNamedGridColumnLines() const { return rareNonInheritedData->m_grid->m_autoRepeatNamedGridColumnLines; }
+    const NamedGridLinesMap& autoRepeatNamedGridRowLines() const { return rareNonInheritedData->m_grid->m_autoRepeatNamedGridRowLines; }
+    const OrderedNamedGridLines& autoRepeatOrderedNamedGridColumnLines() const { return rareNonInheritedData->m_grid->m_autoRepeatOrderedNamedGridColumnLines; }
+    const OrderedNamedGridLines& autoRepeatOrderedNamedGridRowLines() const { return rareNonInheritedData->m_grid->m_autoRepeatOrderedNamedGridRowLines; }
     const NamedGridAreaMap& namedGridArea() const { return rareNonInheritedData->m_grid->m_namedGridArea; }
     size_t namedGridAreaRowCount() const { return rareNonInheritedData->m_grid->m_namedGridAreaRowCount; }
     size_t namedGridAreaColumnCount() const { return rareNonInheritedData->m_grid->m_namedGridAreaColumnCount; }
@@ -865,7 +874,7 @@
     LineBreak getLineBreak() const { return static_cast<LineBreak>(rareInheritedData->lineBreak); }
     const AtomicString& highlight() const { return rareInheritedData->highlight; }
     const AtomicString& hyphenationString() const { return rareInheritedData->hyphenationString; }
-    const AtomicString& locale() const { return fontDescription().locale(false); }
+    const AtomicString& locale() const { return getFontDescription().locale(false); }
     EResize resize() const { return static_cast<EResize>(rareNonInheritedData->m_resize); }
     bool hasInlinePaginationAxis() const
     {
@@ -1368,10 +1377,19 @@
     void setGridAutoRows(const GridTrackSize& length) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridAutoRows, length); }
     void setGridTemplateColumns(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridTemplateColumns, lengths); }
     void setGridTemplateRows(const Vector<GridTrackSize>& lengths) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridTemplateRows, lengths); }
+    void setGridAutoRepeatColumns(const Vector<GridTrackSize>& trackSizes) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridAutoRepeatColumns, trackSizes); }
+    void setGridAutoRepeatRows(const Vector<GridTrackSize>& trackSizes) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_gridAutoRepeatRows, trackSizes); }
+    void setGridAutoRepeatColumnsInsertionPoint(const size_t insertionPoint) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_autoRepeatColumnsInsertionPoint, insertionPoint); }
+    void setGridAutoRepeatRowsInsertionPoint(const size_t insertionPoint) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_autoRepeatRowsInsertionPoint, insertionPoint); }
+    void setGridAutoRepeatType(const AutoRepeatType autoRepeatType) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_autoRepeatType, autoRepeatType); }
     void setNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridColumnLines, namedGridColumnLines); }
     void setNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridRowLines, namedGridRowLines); }
     void setOrderedNamedGridColumnLines(const OrderedNamedGridLines& orderedNamedGridColumnLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_orderedNamedGridColumnLines, orderedNamedGridColumnLines); }
     void setOrderedNamedGridRowLines(const OrderedNamedGridLines& orderedNamedGridRowLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_orderedNamedGridRowLines, orderedNamedGridRowLines); }
+    void setAutoRepeatNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_autoRepeatNamedGridColumnLines, namedGridColumnLines); }
+    void setAutoRepeatNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_autoRepeatNamedGridRowLines, namedGridRowLines); }
+    void setAutoRepeatOrderedNamedGridColumnLines(const OrderedNamedGridLines& orderedNamedGridColumnLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_autoRepeatOrderedNamedGridColumnLines, orderedNamedGridColumnLines); }
+    void setAutoRepeatOrderedNamedGridRowLines(const OrderedNamedGridLines& orderedNamedGridRowLines) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_autoRepeatOrderedNamedGridRowLines, orderedNamedGridRowLines); }
     void setNamedGridArea(const NamedGridAreaMap& namedGridArea) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridArea, namedGridArea); }
     void setNamedGridAreaRowCount(size_t rowCount) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridAreaRowCount, rowCount); }
     void setNamedGridAreaColumnCount(size_t columnCount) { SET_NESTED_VAR(rareNonInheritedData, m_grid, m_namedGridAreaColumnCount, columnCount); }
@@ -1794,6 +1812,9 @@
     // The initial value is 'none' for grid tracks.
     static Vector<GridTrackSize> initialGridTemplateColumns() { return Vector<GridTrackSize>(); }
     static Vector<GridTrackSize> initialGridTemplateRows() { return Vector<GridTrackSize>(); }
+    static Vector<GridTrackSize> initialGridAutoRepeatTracks() { return Vector<GridTrackSize>(); }
+    static size_t initialGridAutoRepeatInsertionPoint() { return 0; }
+    static AutoRepeatType initialGridAutoRepeatType() { return NoAutoRepeat; }
 
     static GridAutoFlow initialGridAutoFlow() { return AutoFlowRow; }
 
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index 8e03c3d..6d9f77b 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -605,6 +605,12 @@
     ScrollSnapTypeProximity
 };
 
+enum AutoRepeatType {
+    NoAutoRepeat,
+    AutoFill,
+    AutoFit
+};
+
 } // namespace blink
 
 #endif // ComputedStyleConstants_h
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
index efd30cf..5b3f777 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImage.cpp
@@ -78,7 +78,7 @@
 
 bool StyleFetchedImage::canRender() const
 {
-    return !m_image->errorOccurred() && !m_image->image()->isNull();
+    return !m_image->errorOccurred() && !m_image->getImage()->isNull();
 }
 
 bool StyleFetchedImage::isLoaded() const
@@ -93,8 +93,8 @@
 
 LayoutSize StyleFetchedImage::imageSize(const LayoutObject* layoutObject, float multiplier, const LayoutSize& defaultObjectSize) const
 {
-    if (m_image->image() && m_image->image()->isSVGImage())
-        return imageSizeForSVGImage(toSVGImage(m_image->image()), multiplier, defaultObjectSize);
+    if (m_image->getImage() && m_image->getImage()->isSVGImage())
+        return imageSizeForSVGImage(toSVGImage(m_image->getImage()), multiplier, defaultObjectSize);
 
     // Image orientation should only be respected for content images,
     // not decorative images such as StyleImage (backgrounds,
@@ -126,24 +126,24 @@
 
 void StyleFetchedImage::notifyFinished(Resource* resource)
 {
-    if (m_document && m_image && m_image->image() && m_image->image()->isSVGImage())
-        toSVGImage(m_image->image())->updateUseCounters(*m_document);
+    if (m_document && m_image && m_image->getImage() && m_image->getImage()->isSVGImage())
+        toSVGImage(m_image->getImage())->updateUseCounters(*m_document);
     // Oilpan: do not prolong the Document's lifetime.
     m_document.clear();
 }
 
 PassRefPtr<Image> StyleFetchedImage::image(const LayoutObject*, const IntSize& containerSize, float zoom) const
 {
-    if (!m_image->image()->isSVGImage())
-        return m_image->image();
+    if (!m_image->getImage()->isSVGImage())
+        return m_image->getImage();
 
-    return SVGImageForContainer::create(toSVGImage(m_image->image()), containerSize, zoom, m_url);
+    return SVGImageForContainer::create(toSVGImage(m_image->getImage()), containerSize, zoom, m_url);
 }
 
 bool StyleFetchedImage::knownToBeOpaque(const LayoutObject* layoutObject) const
 {
     TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(layoutObject, *m_image.get()));
-    return m_image->image()->currentFrameKnownToBeOpaque(Image::PreCacheMetadata);
+    return m_image->getImage()->currentFrameKnownToBeOpaque(Image::PreCacheMetadata);
 }
 
 DEFINE_TRACE(StyleFetchedImage)
diff --git a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
index 3b11cf7..7f5a776ec 100644
--- a/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
+++ b/third_party/WebKit/Source/core/style/StyleFetchedImageSet.cpp
@@ -80,7 +80,7 @@
 
 bool StyleFetchedImageSet::canRender() const
 {
-    return !m_bestFitImage->errorOccurred() && !m_bestFitImage->image()->isNull();
+    return !m_bestFitImage->errorOccurred() && !m_bestFitImage->getImage()->isNull();
 }
 
 bool StyleFetchedImageSet::isLoaded() const
@@ -95,8 +95,8 @@
 
 LayoutSize StyleFetchedImageSet::imageSize(const LayoutObject*, float multiplier, const LayoutSize& defaultObjectSize) const
 {
-    if (m_bestFitImage->image() && m_bestFitImage->image()->isSVGImage())
-        return imageSizeForSVGImage(toSVGImage(m_bestFitImage->image()), multiplier, defaultObjectSize);
+    if (m_bestFitImage->getImage() && m_bestFitImage->getImage()->isSVGImage())
+        return imageSizeForSVGImage(toSVGImage(m_bestFitImage->getImage()), multiplier, defaultObjectSize);
 
     // Image orientation should only be respected for content images,
     // not decorative ones such as StyleImage (backgrounds,
@@ -130,16 +130,16 @@
 
 PassRefPtr<Image> StyleFetchedImageSet::image(const LayoutObject*, const IntSize& containerSize, float zoom) const
 {
-    if (!m_bestFitImage->image()->isSVGImage())
-        return m_bestFitImage->image();
+    if (!m_bestFitImage->getImage()->isSVGImage())
+        return m_bestFitImage->getImage();
 
-    return SVGImageForContainer::create(toSVGImage(m_bestFitImage->image()), containerSize, zoom, m_url);
+    return SVGImageForContainer::create(toSVGImage(m_bestFitImage->getImage()), containerSize, zoom, m_url);
 }
 
 bool StyleFetchedImageSet::knownToBeOpaque(const LayoutObject* layoutObject) const
 {
     TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(layoutObject, *m_bestFitImage.get()));
-    return m_bestFitImage->image()->currentFrameKnownToBeOpaque(Image::PreCacheMetadata);
+    return m_bestFitImage->getImage()->currentFrameKnownToBeOpaque(Image::PreCacheMetadata);
 }
 
 DEFINE_TRACE(StyleFetchedImageSet)
diff --git a/third_party/WebKit/Source/core/style/StyleGridData.cpp b/third_party/WebKit/Source/core/style/StyleGridData.cpp
index f780397..20f1588 100644
--- a/third_party/WebKit/Source/core/style/StyleGridData.cpp
+++ b/third_party/WebKit/Source/core/style/StyleGridData.cpp
@@ -36,6 +36,10 @@
     , m_namedGridRowLines(ComputedStyle::initialNamedGridRowLines())
     , m_orderedNamedGridColumnLines(ComputedStyle::initialOrderedNamedGridColumnLines())
     , m_orderedNamedGridRowLines(ComputedStyle::initialOrderedNamedGridRowLines())
+    , m_autoRepeatNamedGridColumnLines(ComputedStyle::initialNamedGridColumnLines())
+    , m_autoRepeatNamedGridRowLines(ComputedStyle::initialNamedGridRowLines())
+    , m_autoRepeatOrderedNamedGridColumnLines(ComputedStyle::initialOrderedNamedGridColumnLines())
+    , m_autoRepeatOrderedNamedGridRowLines(ComputedStyle::initialOrderedNamedGridRowLines())
     , m_gridAutoFlow(ComputedStyle::initialGridAutoFlow())
     , m_gridAutoRows(ComputedStyle::initialGridAutoRows())
     , m_gridAutoColumns(ComputedStyle::initialGridAutoColumns())
@@ -44,6 +48,11 @@
     , m_namedGridAreaColumnCount(ComputedStyle::initialNamedGridAreaCount())
     , m_gridColumnGap(ComputedStyle::initialGridColumnGap())
     , m_gridRowGap(ComputedStyle::initialGridRowGap())
+    , m_gridAutoRepeatColumns(ComputedStyle::initialGridAutoRepeatTracks())
+    , m_gridAutoRepeatRows(ComputedStyle::initialGridAutoRepeatTracks())
+    , m_autoRepeatColumnsInsertionPoint(ComputedStyle::initialGridAutoRepeatInsertionPoint())
+    , m_autoRepeatRowsInsertionPoint(ComputedStyle::initialGridAutoRepeatInsertionPoint())
+    , m_autoRepeatType(ComputedStyle::initialGridAutoRepeatType())
 {
 }
 
@@ -55,6 +64,10 @@
     , m_namedGridRowLines(o.m_namedGridRowLines)
     , m_orderedNamedGridColumnLines(o.m_orderedNamedGridColumnLines)
     , m_orderedNamedGridRowLines(o.m_orderedNamedGridRowLines)
+    , m_autoRepeatNamedGridColumnLines(o.m_namedGridColumnLines)
+    , m_autoRepeatNamedGridRowLines(o.m_namedGridRowLines)
+    , m_autoRepeatOrderedNamedGridColumnLines(o.m_orderedNamedGridColumnLines)
+    , m_autoRepeatOrderedNamedGridRowLines(o.m_orderedNamedGridRowLines)
     , m_gridAutoFlow(o.m_gridAutoFlow)
     , m_gridAutoRows(o.m_gridAutoRows)
     , m_gridAutoColumns(o.m_gridAutoColumns)
@@ -63,6 +76,11 @@
     , m_namedGridAreaColumnCount(o.m_namedGridAreaColumnCount)
     , m_gridColumnGap(o.m_gridColumnGap)
     , m_gridRowGap(o.m_gridRowGap)
+    , m_gridAutoRepeatColumns(o.m_gridAutoRepeatColumns)
+    , m_gridAutoRepeatRows(o.m_gridAutoRepeatRows)
+    , m_autoRepeatColumnsInsertionPoint(o.m_autoRepeatColumnsInsertionPoint)
+    , m_autoRepeatRowsInsertionPoint(o.m_autoRepeatRowsInsertionPoint)
+    , m_autoRepeatType(o.m_autoRepeatType)
 {
 }
 
diff --git a/third_party/WebKit/Source/core/style/StyleGridData.h b/third_party/WebKit/Source/core/style/StyleGridData.h
index fa5fae1..e47bddc 100644
--- a/third_party/WebKit/Source/core/style/StyleGridData.h
+++ b/third_party/WebKit/Source/core/style/StyleGridData.h
@@ -50,9 +50,14 @@
         && m_gridAutoFlow == o.m_gridAutoFlow && m_gridAutoRows == o.m_gridAutoRows && m_gridAutoColumns == o.m_gridAutoColumns
         && m_namedGridColumnLines == o.m_namedGridColumnLines && m_namedGridRowLines == o.m_namedGridRowLines
         && m_orderedNamedGridColumnLines == o.m_orderedNamedGridColumnLines && m_orderedNamedGridRowLines == o.m_orderedNamedGridRowLines
+        && m_autoRepeatNamedGridColumnLines == o.m_autoRepeatNamedGridColumnLines && m_autoRepeatNamedGridRowLines == o.m_autoRepeatNamedGridRowLines
+        && m_autoRepeatOrderedNamedGridColumnLines == o.m_autoRepeatOrderedNamedGridColumnLines && m_autoRepeatOrderedNamedGridRowLines == o.m_autoRepeatOrderedNamedGridRowLines
         && m_namedGridArea == o.m_namedGridArea && m_namedGridArea == o.m_namedGridArea
         && m_namedGridAreaRowCount == o.m_namedGridAreaRowCount && m_namedGridAreaColumnCount == o.m_namedGridAreaColumnCount
-        && m_gridColumnGap == o.m_gridColumnGap && m_gridRowGap == o.m_gridRowGap;
+        && m_gridColumnGap == o.m_gridColumnGap && m_gridRowGap == o.m_gridRowGap
+        && m_gridAutoRepeatColumns == o.m_gridAutoRepeatColumns && m_gridAutoRepeatRows == o.m_gridAutoRepeatRows
+        && m_autoRepeatColumnsInsertionPoint == o.m_autoRepeatColumnsInsertionPoint && m_autoRepeatRowsInsertionPoint == o.m_autoRepeatRowsInsertionPoint
+        && m_autoRepeatType == o.m_autoRepeatType;
     }
 
     bool operator!=(const StyleGridData& o) const
@@ -71,6 +76,11 @@
     OrderedNamedGridLines m_orderedNamedGridColumnLines;
     OrderedNamedGridLines m_orderedNamedGridRowLines;
 
+    NamedGridLinesMap m_autoRepeatNamedGridColumnLines;
+    NamedGridLinesMap m_autoRepeatNamedGridRowLines;
+    OrderedNamedGridLines m_autoRepeatOrderedNamedGridColumnLines;
+    OrderedNamedGridLines m_autoRepeatOrderedNamedGridRowLines;
+
     unsigned m_gridAutoFlow : GridAutoFlowBits;
 
     GridTrackSize m_gridAutoRows;
@@ -85,6 +95,13 @@
     Length m_gridColumnGap;
     Length m_gridRowGap;
 
+    Vector<GridTrackSize> m_gridAutoRepeatColumns;
+    Vector<GridTrackSize> m_gridAutoRepeatRows;
+
+    size_t m_autoRepeatColumnsInsertionPoint;
+    size_t m_autoRepeatRowsInsertionPoint;
+
+    AutoRepeatType m_autoRepeatType;
 private:
     StyleGridData();
     StyleGridData(const StyleGridData&);
diff --git a/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
index dbf42f3..a904821 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
@@ -71,16 +71,16 @@
     const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(*this);
     ASSERT(lightSource);
     ASSERT(lightElement);
-    ASSERT(effect->filter());
+    ASSERT(effect->getFilter());
 
     if (attrName == SVGNames::azimuthAttr)
         return lightSource->setAzimuth(lightElement->azimuth()->currentValue()->value());
     if (attrName == SVGNames::elevationAttr)
         return lightSource->setElevation(lightElement->elevation()->currentValue()->value());
     if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::zAttr)
-        return lightSource->setPosition(effect->filter()->resolve3dPoint(lightElement->position()));
+        return lightSource->setPosition(effect->getFilter()->resolve3dPoint(lightElement->position()));
     if (attrName == SVGNames::pointsAtXAttr || attrName == SVGNames::pointsAtYAttr || attrName == SVGNames::pointsAtZAttr)
-        return lightSource->setPointsAt(effect->filter()->resolve3dPoint(lightElement->pointsAt()));
+        return lightSource->setPointsAt(effect->getFilter()->resolve3dPoint(lightElement->pointsAt()));
     if (attrName == SVGNames::specularExponentAttr)
         return lightSource->setSpecularExponent(lightElement->specularExponent()->currentValue()->value());
     if (attrName == SVGNames::limitingConeAngleAttr)
diff --git a/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp b/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
index 8c33782..68f188b 100644
--- a/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
@@ -63,8 +63,8 @@
 
 bool SVGFEImageElement::currentFrameHasSingleSecurityOrigin() const
 {
-    if (m_cachedImage && m_cachedImage->image())
-        return m_cachedImage->image()->currentFrameHasSingleSecurityOrigin();
+    if (m_cachedImage && m_cachedImage->getImage())
+        return m_cachedImage->getImage()->currentFrameHasSingleSecurityOrigin();
 
     return true;
 }
@@ -161,7 +161,7 @@
     if (m_cachedImage) {
         // Don't use the broken image icon on image loading errors.
         RefPtr<Image> image = m_cachedImage->errorOccurred() ?
-            nullptr : m_cachedImage->image();
+            nullptr : m_cachedImage->getImage();
         return FEImage::createWithImage(filter, image, m_preserveAspectRatio->currentValue());
     }
 
diff --git a/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp b/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
index f9fe68e..e468a189 100644
--- a/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
@@ -77,16 +77,16 @@
     SVGFELightElement* lightElement = SVGFELightElement::findLightElement(*this);
     ASSERT(lightSource);
     ASSERT(lightElement);
-    ASSERT(effect->filter());
+    ASSERT(effect->getFilter());
 
     if (attrName == SVGNames::azimuthAttr)
         return lightSource->setAzimuth(lightElement->azimuth()->currentValue()->value());
     if (attrName == SVGNames::elevationAttr)
         return lightSource->setElevation(lightElement->elevation()->currentValue()->value());
     if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::zAttr)
-        return lightSource->setPosition(effect->filter()->resolve3dPoint(lightElement->position()));
+        return lightSource->setPosition(effect->getFilter()->resolve3dPoint(lightElement->position()));
     if (attrName == SVGNames::pointsAtXAttr || attrName == SVGNames::pointsAtYAttr || attrName == SVGNames::pointsAtZAttr)
-        return lightSource->setPointsAt(effect->filter()->resolve3dPoint(lightElement->pointsAt()));
+        return lightSource->setPointsAt(effect->getFilter()->resolve3dPoint(lightElement->pointsAt()));
     if (attrName == SVGNames::specularExponentAttr)
         return lightSource->setSpecularExponent(lightElement->specularExponent()->currentValue()->value());
     if (attrName == SVGNames::limitingConeAngleAttr)
diff --git a/third_party/WebKit/Source/core/svg/SVGImageElement.cpp b/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
index 71a25509..15976d9 100644
--- a/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
@@ -64,7 +64,7 @@
 {
     if (LayoutSVGImage* layoutSVGImage = toLayoutSVGImage(layoutObject())) {
         if (layoutSVGImage->imageResource()->hasImage()) {
-            if (Image* image = layoutSVGImage->imageResource()->cachedImage()->image())
+            if (Image* image = layoutSVGImage->imageResource()->cachedImage()->getImage())
                 return image->currentFrameHasSingleSecurityOrigin();
         }
     }
diff --git a/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp b/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
index 0b6d073..fcb6425 100644
--- a/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
@@ -349,7 +349,7 @@
     if (!style)
         return 0;
 
-    float zeroWidth = style->fontMetrics().zeroWidth() / style->effectiveZoom();
+    float zeroWidth = style->getFontMetrics().zeroWidth() / style->effectiveZoom();
     if (!zeroWidth)
         return 0;
 
@@ -362,7 +362,7 @@
     if (!style)
         return 0;
 
-    return value * style->fontMetrics().zeroWidth() / style->effectiveZoom();
+    return value * style->getFontMetrics().zeroWidth() / style->effectiveZoom();
 }
 
 float SVGLengthContext::convertValueFromUserUnitsToEXS(float value) const
@@ -373,7 +373,7 @@
 
     // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg
     // if this causes problems in real world cases maybe it would be best to remove this
-    float xHeight = ceilf(style->fontMetrics().xHeight() / style->effectiveZoom());
+    float xHeight = ceilf(style->getFontMetrics().xHeight() / style->effectiveZoom());
     if (!xHeight)
         return 0;
 
@@ -388,7 +388,7 @@
 
     // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg
     // if this causes problems in real world cases maybe it would be best to remove this
-    return value * ceilf(style->fontMetrics().xHeight() / style->effectiveZoom());
+    return value * ceilf(style->getFontMetrics().xHeight() / style->effectiveZoom());
 }
 
 bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index 1bd519d..fb401607 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -376,8 +376,8 @@
         canvas->drawPicture(recording.get());
     }
 
-    if (imageObserver())
-        imageObserver()->didDraw(this);
+    if (getImageObserver())
+        getImageObserver()->didDraw(this);
 
     // Start any (SMIL) animations if needed. This will restart or continue
     // animations if preceded by calls to resetAnimation or stopAnimation
@@ -445,7 +445,7 @@
         // TODO(pdr): Actually advance the document timeline so CSS animations
         // can be properly tested.
         rootElement->document().page()->animator().serviceScriptedAnimations(rootElement->getCurrentTime());
-        imageObserver()->animationAdvanced(this);
+        getImageObserver()->animationAdvanced(this);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
index f6c234f3..5adc7a4 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
@@ -134,7 +134,7 @@
     ImageObserverDisabler(Image* image)
         : m_image(image)
     {
-        m_observer = m_image->imageObserver();
+        m_observer = m_image->getImageObserver();
         m_image->setImageObserver(0);
     }
 
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
index eea5b03..a2556b1b 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
@@ -62,8 +62,8 @@
 void SVGImageChromeClient::invalidateRect(const IntRect& r)
 {
     // If m_image->m_page is null, we're being destructed, don't fire changedInRect() in that case.
-    if (m_image && m_image->imageObserver() && m_image->m_page)
-        m_image->imageObserver()->changedInRect(m_image, r);
+    if (m_image && m_image->getImageObserver() && m_image->m_page)
+        m_image->getImageObserver()->changedInRect(m_image, r);
 }
 
 void SVGImageChromeClient::scheduleAnimation(Widget*)
@@ -95,7 +95,7 @@
     //
     // TODO(Oilpan): move (SVG)Image to the Oilpan heap, and avoid
     // this explicit lifetime check.
-    if (Heap::willObjectBeLazilySwept(m_image->imageObserver()))
+    if (Heap::willObjectBeLazilySwept(m_image->getImageObserver()))
         return;
 #endif
 
@@ -106,7 +106,7 @@
     // The calls below may trigger GCs, so set up the required persistent
     // reference on the ImageResource which owns this SVGImage. By transitivity,
     // that will keep this SVGImageChromeClient object alive.
-    RawPtrWillBePersistent<ImageObserver> protect(m_image->imageObserver());
+    RawPtrWillBePersistent<ImageObserver> protect(m_image->getImageObserver());
     m_image->frameView()->page()->animator().serviceScriptedAnimations(monotonicallyIncreasingTime());
     m_image->frameView()->updateAllLifecyclePhases();
 }
diff --git a/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp b/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp
index d551f17..b27fe83 100644
--- a/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp
@@ -100,7 +100,7 @@
     if (clipsToBounds())
         requestedRect.intersect(maxEffectRect());
 
-    FloatRect destRect = filter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion());
+    FloatRect destRect = getFilter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion());
     FloatRect srcRect;
     if (layoutObject) {
         srcRect = getLayoutObjectRepaintRect(layoutObject);
@@ -114,7 +114,7 @@
                 srcRect = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect).mapRect(srcRect);
             }
         } else {
-            srcRect = filter()->mapLocalRectToAbsoluteRect(srcRect);
+            srcRect = getFilter()->mapLocalRectToAbsoluteRect(srcRect);
             srcRect.move(destRect.x(), destRect.y());
         }
         destRect.intersect(srcRect);
diff --git a/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp b/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
index a58d52f..d077944a 100644
--- a/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
@@ -37,7 +37,7 @@
 
 class FilterInputKeywords {
 public:
-    static const AtomicString& sourceGraphic()
+    static const AtomicString& getSourceGraphic()
     {
         DEFINE_STATIC_LOCAL(const AtomicString, s_sourceGraphicName, ("SourceGraphic", AtomicString::ConstructFromLiteral));
         return s_sourceGraphicName;
@@ -121,12 +121,12 @@
     : m_nodeMap(nodeMap)
 {
     RefPtrWillBeRawPtr<FilterEffect> sourceGraphicRef = sourceGraphic;
-    m_builtinEffects.add(FilterInputKeywords::sourceGraphic(), sourceGraphicRef);
+    m_builtinEffects.add(FilterInputKeywords::getSourceGraphic(), sourceGraphicRef);
     m_builtinEffects.add(FilterInputKeywords::sourceAlpha(), SourceAlpha::create(sourceGraphicRef.get()));
     if (fillPaint)
-        m_builtinEffects.add(FilterInputKeywords::fillPaint(), PaintFilterEffect::create(sourceGraphicRef->filter(), *fillPaint));
+        m_builtinEffects.add(FilterInputKeywords::fillPaint(), PaintFilterEffect::create(sourceGraphicRef->getFilter(), *fillPaint));
     if (strokePaint)
-        m_builtinEffects.add(FilterInputKeywords::strokePaint(), PaintFilterEffect::create(sourceGraphicRef->filter(), *strokePaint));
+        m_builtinEffects.add(FilterInputKeywords::strokePaint(), PaintFilterEffect::create(sourceGraphicRef->getFilter(), *strokePaint));
     addBuiltinEffects();
 }
 
@@ -210,7 +210,7 @@
     if (m_lastEffect)
         return m_lastEffect.get();
 
-    return m_builtinEffects.get(FilterInputKeywords::sourceGraphic());
+    return m_builtinEffects.get(FilterInputKeywords::getSourceGraphic());
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index be3f7e0..895adc8 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -204,7 +204,7 @@
     if (!layoutObject || !layoutObject->isBox())
         return nullptr;
 
-    return toLayoutBox(layoutObject)->scrollableArea();
+    return toLayoutBox(layoutObject)->getScrollableArea();
 }
 
 const char* Internals::internalsId = "internals";
@@ -531,7 +531,7 @@
         return;
     }
 
-    Image* imageData = resource->image();
+    Image* imageData = resource->getImage();
     if (!imageData->isBitmapImage()) {
         exceptionState.throwDOMException(InvalidAccessError, "The image resource is not a BitmapImage type.");
         return;
@@ -559,7 +559,7 @@
         return;
     }
 
-    Image* imageData = resource->image();
+    Image* imageData = resource->getImage();
     imageData->advanceAnimationForTesting();
 }
 
@@ -1308,7 +1308,7 @@
 
     // If the |graphicsLayer| is a scroller's scrollingContent layer,
     // consider this is a scrolling layer.
-    GraphicsLayer* layerForScrolling = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForScrolling() : 0;
+    GraphicsLayer* layerForScrolling = searchRoot->getScrollableArea() ? searchRoot->getScrollableArea()->layerForScrolling() : 0;
     if (graphicsLayer == layerForScrolling) {
         *layerType = "scrolling";
         return searchRoot;
@@ -1325,19 +1325,19 @@
         }
     }
 
-    GraphicsLayer* layerForHorizontalScrollbar = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForHorizontalScrollbar() : 0;
+    GraphicsLayer* layerForHorizontalScrollbar = searchRoot->getScrollableArea() ? searchRoot->getScrollableArea()->layerForHorizontalScrollbar() : 0;
     if (graphicsLayer == layerForHorizontalScrollbar) {
         *layerType = "horizontalScrollbar";
         return searchRoot;
     }
 
-    GraphicsLayer* layerForVerticalScrollbar = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForVerticalScrollbar() : 0;
+    GraphicsLayer* layerForVerticalScrollbar = searchRoot->getScrollableArea() ? searchRoot->getScrollableArea()->layerForVerticalScrollbar() : 0;
     if (graphicsLayer == layerForVerticalScrollbar) {
         *layerType = "verticalScrollbar";
         return searchRoot;
     }
 
-    GraphicsLayer* layerForScrollCorner = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForScrollCorner() : 0;
+    GraphicsLayer* layerForScrollCorner = searchRoot->getScrollableArea() ? searchRoot->getScrollableArea()->layerForScrollCorner() : 0;
     if (graphicsLayer == layerForScrollCorner) {
         *layerType = "scrollCorner";
         return searchRoot;
@@ -1995,7 +1995,7 @@
     ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
     GraphicsLayer* graphicsLayer = toLocalFrame(frame()->page()->mainFrame())->view()->layoutView()->layer()->graphicsLayerBacking();
     if (graphicsLayer->drawsContent())
-        graphicsLayer->paintController().startTrackingPaintInvalidationObjects();
+        graphicsLayer->getPaintController().startTrackingPaintInvalidationObjects();
 }
 
 void Internals::stopTrackingPaintInvalidationObjects()
@@ -2003,7 +2003,7 @@
     ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
     GraphicsLayer* graphicsLayer = toLocalFrame(frame()->page()->mainFrame())->view()->layoutView()->layer()->graphicsLayerBacking();
     if (graphicsLayer->drawsContent())
-        graphicsLayer->paintController().stopTrackingPaintInvalidationObjects();
+        graphicsLayer->getPaintController().stopTrackingPaintInvalidationObjects();
 }
 
 Vector<String> Internals::trackedPaintInvalidationObjects()
@@ -2012,7 +2012,7 @@
     GraphicsLayer* graphicsLayer = toLocalFrame(frame()->page()->mainFrame())->view()->layoutView()->layer()->graphicsLayerBacking();
     if (!graphicsLayer->drawsContent())
         return Vector<String>();
-    return graphicsLayer->paintController().trackedPaintInvalidationObjects();
+    return graphicsLayer->getPaintController().trackedPaintInvalidationObjects();
 }
 
 ClientRectList* Internals::draggableRegions(Document* document, ExceptionState& exceptionState)
@@ -2109,8 +2109,8 @@
     result.appendNumber(cursor.hotSpot().x());
     result.append(',');
     result.appendNumber(cursor.hotSpot().y());
-    if (cursor.image()) {
-        IntSize size = cursor.image()->size();
+    if (cursor.getImage()) {
+        IntSize size = cursor.getImage()->size();
         result.appendLiteral(" image=");
         result.appendNumber(size.width());
         result.append('x');
@@ -2212,7 +2212,7 @@
     if (itemIndex < 0 || static_cast<size_t>(itemIndex) >= select.listItems().size())
         return false;
     const ComputedStyle* itemStyle = select.itemComputedStyle(*select.listItems()[itemIndex]);
-    return itemStyle ? itemStyle->font().fontMetrics().height() : 0;
+    return itemStyle ? itemStyle->font().getFontMetrics().height() : 0;
 }
 
 void Internals::resetTypeAheadSession(HTMLSelectElement* select)
@@ -2471,12 +2471,12 @@
 
 double Internals::visualViewportScrollX()
 {
-    return frame()->view()->scrollableArea()->scrollPositionDouble().x();
+    return frame()->view()->getScrollableArea()->scrollPositionDouble().x();
 }
 
 double Internals::visualViewportScrollY()
 {
-    return frame()->view()->scrollableArea()->scrollPositionDouble().y();
+    return frame()->view()->getScrollableArea()->scrollPositionDouble().y();
 }
 
 ValueIterable<int>::IterationSource* Internals::startIteration(ScriptState*, ExceptionState&)
diff --git a/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.cpp
index abfa3692..8e768bd 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.cpp
@@ -31,6 +31,7 @@
 
 #include "core/timing/PerformanceCompositeTiming.h"
 
+#include "bindings/core/v8/V8ObjectBuilder.h"
 #include "core/dom/Document.h"
 #include "core/loader/DocumentLoader.h"
 
@@ -58,6 +59,12 @@
     return m_sourceFrame;
 }
 
+void PerformanceCompositeTiming::buildJSONValue(V8ObjectBuilder& builder) const
+{
+    PerformanceEntry::buildJSONValue(builder);
+    builder.addNumber("sourceFrame", sourceFrame());
+}
+
 DEFINE_TRACE(PerformanceCompositeTiming)
 {
     visitor->trace(m_requestingDocument);
diff --git a/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.h b/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.h
index e2466a5..908cb30 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.h
+++ b/third_party/WebKit/Source/core/timing/PerformanceCompositeTiming.h
@@ -53,6 +53,9 @@
 
     DECLARE_VIRTUAL_TRACE();
 
+protected:
+    void buildJSONValue(V8ObjectBuilder&) const override;
+
 private:
     PerformanceCompositeTiming(Document* requestingDocument, unsigned sourceFrame, double startTime);
     ~PerformanceCompositeTiming() override;
diff --git a/third_party/WebKit/Source/core/timing/PerformanceEntry.cpp b/third_party/WebKit/Source/core/timing/PerformanceEntry.cpp
index 52a6387..0812ee5 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceEntry.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceEntry.cpp
@@ -86,11 +86,16 @@
 ScriptValue PerformanceEntry::toJSONForBinding(ScriptState* scriptState) const
 {
     V8ObjectBuilder result(scriptState);
-    result.addString("name", name());
-    result.addString("entryType", entryType());
-    result.addNumber("startTime", startTime());
-    result.addNumber("duration", duration());
+    buildJSONValue(result);
     return result.scriptValue();
 }
 
+void PerformanceEntry::buildJSONValue(V8ObjectBuilder& builder) const
+{
+    builder.addString("name", name());
+    builder.addString("entryType", entryType());
+    builder.addNumber("startTime", startTime());
+    builder.addNumber("duration", duration());
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/timing/PerformanceEntry.h b/third_party/WebKit/Source/core/timing/PerformanceEntry.h
index 0bc7107..8f0e542a 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceEntry.h
+++ b/third_party/WebKit/Source/core/timing/PerformanceEntry.h
@@ -41,6 +41,7 @@
 
 class ScriptState;
 class ScriptValue;
+class V8ObjectBuilder;
 
 using PerformanceEntryType = unsigned char;
 using PerformanceEntryTypeMask = unsigned char;
@@ -85,6 +86,7 @@
 
 protected:
     PerformanceEntry(const String& name, const String& entryType, double startTime, double finishTime);
+    virtual void buildJSONValue(V8ObjectBuilder&) const;
 
 private:
     const String m_name;
diff --git a/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.cpp
index 6e1ae535..997748b5 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.cpp
@@ -31,6 +31,7 @@
 
 #include "core/timing/PerformanceRenderTiming.h"
 
+#include "bindings/core/v8/V8ObjectBuilder.h"
 #include "core/dom/Document.h"
 #include "core/loader/DocumentLoader.h"
 
@@ -58,6 +59,12 @@
     return m_sourceFrame;
 }
 
+void PerformanceRenderTiming::buildJSONValue(V8ObjectBuilder& builder) const
+{
+    PerformanceEntry::buildJSONValue(builder);
+    builder.addNumber("sourceFrame", sourceFrame());
+}
+
 DEFINE_TRACE(PerformanceRenderTiming)
 {
     visitor->trace(m_requestingDocument);
diff --git a/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.h b/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.h
index 4f8df46f..9aea801 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.h
+++ b/third_party/WebKit/Source/core/timing/PerformanceRenderTiming.h
@@ -53,6 +53,9 @@
 
     DECLARE_VIRTUAL_TRACE();
 
+protected:
+    void buildJSONValue(V8ObjectBuilder&) const override;
+
 private:
     PerformanceRenderTiming(Document* requestingDocument, unsigned sourceFrame, double startTime, double finishTime);
     ~PerformanceRenderTiming() override;
diff --git a/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp
index 0fda8c47..18ccf42 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp
@@ -31,6 +31,7 @@
 
 #include "core/timing/PerformanceResourceTiming.h"
 
+#include "bindings/core/v8/V8ObjectBuilder.h"
 #include "core/timing/PerformanceBase.h"
 #include "platform/network/ResourceRequest.h"
 #include "platform/network/ResourceResponse.h"
@@ -212,4 +213,22 @@
     return monotonicTimeToDOMHighResTimeStamp(m_timeOrigin, m_finishTime);
 }
 
+void PerformanceResourceTiming::buildJSONValue(V8ObjectBuilder& builder) const
+{
+    PerformanceEntry::buildJSONValue(builder);
+    builder.addString("initiatorType", initiatorType());
+    builder.addNumber("workerStart", workerStart());
+    builder.addNumber("redirectStart", redirectStart());
+    builder.addNumber("redirectEnd", redirectEnd());
+    builder.addNumber("fetchStart", fetchStart());
+    builder.addNumber("domainLookupStart", domainLookupStart());
+    builder.addNumber("domainLookupEnd", domainLookupEnd());
+    builder.addNumber("connectStart", connectStart());
+    builder.addNumber("connectEnd", connectEnd());
+    builder.addNumber("secureConnectionStart", secureConnectionStart());
+    builder.addNumber("requestStart", requestStart());
+    builder.addNumber("responseStart", responseStart());
+    builder.addNumber("responseEnd", responseEnd());
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h b/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h
index 0ec1909..98858fe 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h
+++ b/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h
@@ -69,6 +69,9 @@
     double responseStart() const;
     double responseEnd() const;
 
+protected:
+    void buildJSONValue(V8ObjectBuilder&) const override;
+
 private:
     PerformanceResourceTiming(const ResourceTimingInfo&, double timeOrigin, double startTime, double lastRedirectEndTime, bool m_allowTimingDetails, bool m_allowRedirectDetails);
     ~PerformanceResourceTiming() override;
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
index 13ee21cf..7efe531 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
@@ -559,10 +559,7 @@
     {
         if (!this._irModel)
             return;
-        var segments = this._irModel.interactionRecords();
-        if (!segments || !segments.length)
-            return;
-        segments.forEach(this._appendSegment, this);
+        this._irModel.interactionRecords().forEach(this._appendSegment, this);
         this._entryTypeByLevel[this._currentLevel++] = WebInspector.TimelineFlameChartEntryType.InteractionRecord;
     },
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js b/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js
index f699c73a..20b7e3db 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/FlameChart.js
@@ -1114,7 +1114,7 @@
         var groups = this._rawTimelineData.groups || [];
         var group = this._groupOffsets.upperBound(y) - 1;
 
-        if (group >= 0 && y - this._groupOffsets[group] < groups[group].style.height)
+        if (group >= 0 && group < groups.length && y - this._groupOffsets[group] < groups[group].style.height)
             return group;
         return -1;
     },
@@ -1333,9 +1333,11 @@
         var barHeight = this._barHeight;
         var textBaseHeight = barHeight - this._dataProvider.textBaseline();
         var groups = this._rawTimelineData.groups || [];
+        if (!groups.length)
+            return;
+
         var groupOffsets = this._groupOffsets;
         var lastGroupOffset = Array.prototype.peekLast.call(groupOffsets);
-
         var firstVisibleGroup = Math.max(groupOffsets.upperBound(top) - 1, 0);
 
         context.save();
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
index 8654688..579c3a7 100644
--- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
+++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -247,7 +247,7 @@
     if (!box->canBeScrolledAndHasScrollableArea())
         return 0;
 
-    return box->scrollableArea();
+    return box->getScrollableArea();
 }
 
 static bool isImageOrAltText(LayoutBoxModelObject* box, Node* node)
@@ -952,7 +952,7 @@
     unsigned textStyle = TextStyleNone;
     if (style->fontWeight() == FontWeightBold)
         textStyle |= TextStyleBold;
-    if (style->fontDescription().style() == FontStyleItalic)
+    if (style->getFontDescription().style() == FontStyleItalic)
         textStyle |= TextStyleItalic;
     if (style->getTextDecoration() == TextDecorationUnderline)
         textStyle |= TextStyleUnderline;
@@ -1393,7 +1393,7 @@
         dirty = true;
 
     if (box->canBeScrolledAndHasScrollableArea()) {
-        ScrollableArea* scrollableArea = box->scrollableArea();
+        ScrollableArea* scrollableArea = box->getScrollableArea();
         if (scrollableArea && scrollableArea->scrollPosition() != m_cachedScrollPosition)
             dirty = true;
     }
@@ -1417,7 +1417,7 @@
     m_cachedFrameRect = box->frameRect();
 
     if (box->canBeScrolledAndHasScrollableArea()) {
-        ScrollableArea* scrollableArea = box->scrollableArea();
+        ScrollableArea* scrollableArea = box->getScrollableArea();
         if (scrollableArea)
             m_cachedScrollPosition = scrollableArea->scrollPosition();
     }
diff --git a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
index df86cda..fcd57501 100644
--- a/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
+++ b/third_party/WebKit/Source/modules/cachestorage/CacheTest.cpp
@@ -249,7 +249,7 @@
     {
         ScriptValue onReject;
         promise.then(UnreachableFunction::create(getScriptState()), TestFunction::create(getScriptState(), &onReject));
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         return onReject;
     }
 
@@ -263,7 +263,7 @@
     {
         ScriptValue onResolve;
         promise.then(TestFunction::create(getScriptState(), &onResolve), UnreachableFunction::create(getScriptState()));
-        isolate()->RunMicrotasks();
+        v8::MicrotasksScope::PerformCheckpoint(isolate());
         return onResolve;
     }
 
diff --git a/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.cpp b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.cpp
new file mode 100644
index 0000000..09f992f2
--- /dev/null
+++ b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.cpp
@@ -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.
+
+#include "modules/canvas/HTMLCanvasElementModule.h"
+
+#include "core/html/canvas/CanvasContextCreationAttributes.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+
+namespace blink {
+
+void HTMLCanvasElementModule::getContext(HTMLCanvasElement& canvas, const String& type, const CanvasContextCreationAttributes& attributes, RenderingContext& result)
+{
+    CanvasRenderingContext* context = canvas.getCanvasRenderingContext(type, attributes);
+    if (context) {
+        context->setCanvasGetContextResult(result);
+    }
+}
+
+}
diff --git a/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.h b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.h
new file mode 100644
index 0000000..bacb33cc
--- /dev/null
+++ b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.h
@@ -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.
+
+#ifndef HTMLCanvasElementModule_h
+#define HTMLCanvasElementModule_h
+
+#include "core/html/HTMLCanvasElement.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+class CanvasContextCreationAttributes;
+class HTMLCanvasElement;
+class ScriptState;
+
+class HTMLCanvasElementModule {
+    STATIC_ONLY(HTMLCanvasElementModule);
+public:
+    static void getContext(HTMLCanvasElement&, const String&, const CanvasContextCreationAttributes&, RenderingContext&);
+};
+
+}
+
+#endif
diff --git a/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.idl b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.idl
new file mode 100644
index 0000000..3b0219fc
--- /dev/null
+++ b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModule.idl
@@ -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.
+
+// https://html.spec.whatwg.org/#the-canvas-element
+
+typedef (CanvasRenderingContext2D or
+         WebGLRenderingContext or
+         WebGL2RenderingContext or
+         ImageBitmapRenderingContext) RenderingContext;
+
+partial interface HTMLCanvasElement
+{
+    // The PermissiveDictionaryConversion extended attribute is needed to allow the
+    // autogenerated code to match the behavior of the custom binding. Web IDL
+    // requires throwing TypeError if the incoming argument is not an object type
+    // (and is not undefined or null). The binding must ignore this.
+    // Related spec issue: https://github.com/whatwg/html/issues/595
+    RenderingContext? getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributes attributes);
+};
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
index 65da616..1429cb55 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -557,7 +557,7 @@
 
 static bool isPathExpensive(const Path& path)
 {
-    const SkPath& skPath = path.skPath();
+    const SkPath& skPath = path.getSkPath();
     if (ExpensiveCanvasHeuristicParameters::ConcavePathsAreExpensive && !skPath.isConvex())
         return true;
 
@@ -572,7 +572,7 @@
     if (path.isEmpty())
         return;
 
-    SkPath skPath = path.skPath();
+    SkPath skPath = path.getSkPath();
     FloatRect bounds = path.boundingRect();
     skPath.setFillType(fillType);
 
@@ -697,7 +697,7 @@
         return;
     }
 
-    SkPath skPath = path.skPath();
+    SkPath skPath = path.getSkPath();
     skPath.setFillType(parseWinding(windingRuleString));
     modifiableState().clipPath(skPath, m_clipAntialiasing);
     c->clipPath(skPath, SkRegion::kIntersect_Op, m_clipAntialiasing == AntiAliased);
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
index ff96cb5..5724bc4 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -35,6 +35,7 @@
 #include "bindings/core/v8/ExceptionMessages.h"
 #include "bindings/core/v8/ExceptionState.h"
 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
+#include "bindings/modules/v8/UnionTypesModules.h"
 #include "core/CSSPropertyNames.h"
 #include "core/css/StylePropertySet.h"
 #include "core/css/resolver/StyleResolver.h"
@@ -127,6 +128,11 @@
 #endif
 }
 
+void CanvasRenderingContext2D::setCanvasGetContextResult(RenderingContext& result)
+{
+    result.setCanvasRenderingContext2D(PassRefPtrWillBeRawPtr<CanvasRenderingContext2D>(this));
+}
+
 void CanvasRenderingContext2D::unwindStateStack()
 {
     if (size_t stackSize = m_stateStack.size()) {
@@ -409,7 +415,7 @@
 
     canvas()->document().canvasFontCache()->willUseCurrentFont();
     StringBuilder serializedFont;
-    const FontDescription& fontDescription = state().font().fontDescription();
+    const FontDescription& fontDescription = state().font().getFontDescription();
 
     if (fontDescription.style() == FontStyleItalic)
         serializedFont.appendLiteral("italic ");
@@ -473,11 +479,11 @@
             if (!parsedStyle)
                 return;
             fontStyle = ComputedStyle::create();
-            FontDescription elementFontDescription(computedStyle->fontDescription());
+            FontDescription elementFontDescription(computedStyle->getFontDescription());
             // Reset the computed size to avoid inheriting the zoom factor from the <canvas> element.
             elementFontDescription.setComputedSize(elementFontDescription.specifiedSize());
             fontStyle->setFontDescription(elementFontDescription);
-            fontStyle->font().update(fontStyle->font().fontSelector());
+            fontStyle->font().update(fontStyle->font().getFontSelector());
             canvas()->document().ensureStyleResolver().computeFont(fontStyle.get(), *parsedStyle);
             m_fontsResolvedUsingCurrentStyle.add(newFont, fontStyle->font());
             ASSERT(!m_fontLRUList.contains(newFont));
@@ -688,7 +694,7 @@
         direction = toTextDirection(state().getDirection(), canvas());
     TextRun textRun(text, 0, 0, TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, direction, false);
     textRun.setNormalizeSpace(true);
-    FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font.fontDescription().computedSize(), 0, -1, true);
+    FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font.getFontDescription().computedSize(), 0, -1, true);
 
     // x direction
     metrics->setWidth(font.width(textRun));
@@ -696,7 +702,7 @@
     metrics->setActualBoundingBoxRight(textBounds.maxX());
 
     // y direction
-    const FontMetrics& fontMetrics = font.fontMetrics();
+    const FontMetrics& fontMetrics = font.getFontMetrics();
     const float ascent = fontMetrics.floatAscent();
     const float descent = fontMetrics.floatDescent();
     const float baselineY = getFontBaseline(fontMetrics);
@@ -748,7 +754,7 @@
     if (!font.primaryFont())
         return;
 
-    const FontMetrics& fontMetrics = font.fontMetrics();
+    const FontMetrics& fontMetrics = font.getFontMetrics();
 
     // FIXME: Need to turn off font smoothing.
 
@@ -915,7 +921,7 @@
     SkColor color = LayoutTheme::theme().focusRingColor().rgb();
     const int focusRingWidth = 5;
 
-    drawPlatformFocusRing(path.skPath(), drawingCanvas(), color, focusRingWidth);
+    drawPlatformFocusRing(path.getSkPath(), drawingCanvas(), color, focusRingWidth);
 
     // We need to add focusRingWidth to dirtyRect.
     StrokeData strokeData;
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
index 05ab7972..7ffc69b2 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
@@ -83,6 +83,8 @@
 
     ~CanvasRenderingContext2D() override;
 
+    void setCanvasGetContextResult(RenderingContext&) final;
+
     bool isContextLost() const override;
 
     void setShouldAntialias(bool) override;
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp
index 438a159f..8ccb1c9 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DState.cpp
@@ -107,20 +107,20 @@
         m_clipList = other.m_clipList;
     }
     if (m_realizedFont)
-        static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalidationCallbacks(this);
+        static_cast<CSSFontSelector*>(m_font.getFontSelector())->registerForInvalidationCallbacks(this);
 }
 
 CanvasRenderingContext2DState::~CanvasRenderingContext2DState()
 {
 #if !ENABLE(OILPAN)
     if (m_realizedFont)
-        static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInvalidationCallbacks(this);
+        static_cast<CSSFontSelector*>(m_font.getFontSelector())->unregisterForInvalidationCallbacks(this);
 #endif
 }
 
 void CanvasRenderingContext2DState::fontsNeedUpdate(CSSFontSelector* fontSelector)
 {
-    ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
+    ASSERT_ARG(fontSelector, fontSelector == m_font.getFontSelector());
     ASSERT(m_realizedFont);
 
     m_font.update(fontSelector);
@@ -264,7 +264,7 @@
 {
 #if !ENABLE(OILPAN)
     if (m_realizedFont)
-        static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInvalidationCallbacks(this);
+        static_cast<CSSFontSelector*>(m_font.getFontSelector())->unregisterForInvalidationCallbacks(this);
 #endif
     m_font = font;
     m_font.update(selector);
diff --git a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
index 4d19f76..00c3fa65 100644
--- a/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
+++ b/third_party/WebKit/Source/modules/fetch/ReadableStreamDataConsumerHandleTest.cpp
@@ -8,6 +8,7 @@
 #include "bindings/core/v8/ScriptState.h"
 #include "bindings/core/v8/V8BindingMacros.h"
 #include "bindings/core/v8/V8GCController.h"
+#include "bindings/core/v8/V8RecursionScope.h"
 #include "core/dom/Document.h"
 #include "core/testing/DummyPageHolder.h"
 #include "modules/fetch/DataConsumerHandleTestUtil.h"
@@ -59,6 +60,7 @@
     {
         v8::Local<v8::String> source;
         v8::Local<v8::Script> script;
+        V8RecursionScope::MicrotaskSuppression microtasks(isolate());
         if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) {
             ADD_FAILURE();
             return v8::MaybeLocal<v8::Value>();
diff --git a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
index bc56126..7acc629 100644
--- a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
@@ -4,6 +4,7 @@
 
 #include "modules/imagebitmap/ImageBitmapRenderingContext.h"
 
+#include "bindings/modules/v8/UnionTypesModules.h"
 #include "core/frame/ImageBitmap.h"
 #include "platform/graphics/GraphicsContext.h"
 #include "platform/graphics/StaticBitmapImage.h"
@@ -19,6 +20,11 @@
 
 ImageBitmapRenderingContext::~ImageBitmapRenderingContext() { }
 
+void ImageBitmapRenderingContext::setCanvasGetContextResult(RenderingContext& result)
+{
+    result.setImageBitmapRenderingContext(PassRefPtrWillBeRawPtr<ImageBitmapRenderingContext>(this));
+}
+
 void ImageBitmapRenderingContext::transferImageBitmap(ImageBitmap* imageBitmap)
 {
     m_image = imageBitmap->bitmapImage();
diff --git a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h
index 38148256..897ab83 100644
--- a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h
+++ b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h
@@ -37,6 +37,7 @@
     void setIsHidden(bool) override { }
     bool isContextLost() const override { return false; }
     bool paint(GraphicsContext&, const IntRect&) override;
+    void setCanvasGetContextResult(RenderingContext&) final;
 
     // TODO(junov): Implement GPU accelerated rendering using a layer bridge
     WebLayer* platformLayer() const override { return nullptr; }
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi
index 93b86db4..9765e64 100644
--- a/third_party/WebKit/Source/modules/modules.gypi
+++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -337,6 +337,7 @@
       'bluetooth/NavigatorBluetooth.idl',
       'cachestorage/WindowCacheStorage.idl',
       'cachestorage/WorkerCacheStorage.idl',
+      'canvas/HTMLCanvasElementModule.idl',
       'canvas2d/CanvasPathMethods.idl',
       'canvas2d/MouseEventHitRegion.idl',
       'canvas2d/TouchHitRegion.idl',
@@ -856,6 +857,8 @@
       'cachestorage/GlobalCacheStorage.h',
       'cachestorage/InspectorCacheStorageAgent.cpp',
       'cachestorage/InspectorCacheStorageAgent.h',
+      'canvas/HTMLCanvasElementModule.cpp',
+      'canvas/HTMLCanvasElementModule.h',
       'canvas2d/BaseRenderingContext2D.cpp',
       'canvas2d/BaseRenderingContext2D.h',
       'canvas2d/CanvasGradient.cpp',
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.cpp b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.cpp
index a73f7c6..44207895 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.cpp
@@ -26,6 +26,20 @@
     return adoptRefWillBeNoop(new ExtendableMessageEvent(data, origin, ports, observer));
 }
 
+PassRefPtrWillBeRawPtr<ExtendableMessageEvent> ExtendableMessageEvent::create(PassRefPtr<SerializedScriptValue> data, const String& origin, MessagePortArray* ports, ServiceWorkerClient* source, WaitUntilObserver* observer)
+{
+    RefPtrWillBeRawPtr<ExtendableMessageEvent> event = adoptRefWillBeNoop(new ExtendableMessageEvent(data, origin, ports, observer));
+    event->m_sourceAsClient = source;
+    return event.release();
+}
+
+PassRefPtrWillBeRawPtr<ExtendableMessageEvent> ExtendableMessageEvent::create(PassRefPtr<SerializedScriptValue> data, const String& origin, MessagePortArray* ports, ServiceWorker* source, WaitUntilObserver* observer)
+{
+    RefPtrWillBeRawPtr<ExtendableMessageEvent> event = adoptRefWillBeNoop(new ExtendableMessageEvent(data, origin, ports, observer));
+    event->m_sourceAsServiceWorker = source;
+    return event.release();
+}
+
 MessagePortArray ExtendableMessageEvent::ports(bool& isNull) const
 {
     // TODO(bashi): Currently we return a copied array because the binding
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.h b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.h
index 48d0281..b2b5ad9 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.h
+++ b/third_party/WebKit/Source/modules/serviceworkers/ExtendableMessageEvent.h
@@ -20,6 +20,8 @@
     static PassRefPtrWillBeRawPtr<ExtendableMessageEvent> create(const AtomicString& type, const ExtendableMessageEventInit& initializer);
     static PassRefPtrWillBeRawPtr<ExtendableMessageEvent> create(const AtomicString& type, const ExtendableMessageEventInit& initializer, WaitUntilObserver*);
     static PassRefPtrWillBeRawPtr<ExtendableMessageEvent> create(PassRefPtr<SerializedScriptValue> data, const String& origin, MessagePortArray* ports, WaitUntilObserver*);
+    static PassRefPtrWillBeRawPtr<ExtendableMessageEvent> create(PassRefPtr<SerializedScriptValue> data, const String& origin, MessagePortArray* ports, ServiceWorkerClient* source, WaitUntilObserver*);
+    static PassRefPtrWillBeRawPtr<ExtendableMessageEvent> create(PassRefPtr<SerializedScriptValue> data, const String& origin, MessagePortArray* ports, ServiceWorker* source, WaitUntilObserver*);
 
     SerializedScriptValue* serializedData() const { return m_serializedData.get(); }
     void setSerializedData(PassRefPtr<SerializedScriptValue> serializedData) { m_serializedData = serializedData; }
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.cpp
index 85047432..d5f53676 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorker.cpp
@@ -36,7 +36,9 @@
 #include "core/events/Event.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "modules/EventTargetModules.h"
+#include "modules/serviceworkers/ServiceWorkerContainerClient.h"
 #include "public/platform/WebMessagePortChannel.h"
+#include "public/platform/WebSecurityOrigin.h"
 #include "public/platform/WebString.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerState.h"
 
@@ -49,6 +51,12 @@
 
 void ServiceWorker::postMessage(ExecutionContext* context, PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionState& exceptionState)
 {
+    ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::from(getExecutionContext());
+    if (!client || !client->provider()) {
+        exceptionState.throwDOMException(InvalidStateError, "Failed to post a message: No associated provider is available.");
+        return;
+    }
+
     // Disentangle the port in preparation for sending it to the remote context.
     OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(context, ports, exceptionState);
     if (exceptionState.hadException())
@@ -63,7 +71,7 @@
 
     WebString messageString = message->toWireString();
     OwnPtr<WebMessagePortChannelArray> webChannels = MessagePort::toWebMessagePortChannelArray(channels.release());
-    m_handle->serviceWorker()->postMessage(messageString, webChannels.leakPtr());
+    m_handle->serviceWorker()->postMessage(client->provider(), messageString, WebSecurityOrigin(getExecutionContext()->getSecurityOrigin()), webChannels.leakPtr());
 }
 
 void ServiceWorker::internalsTerminate()
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
index 37d0f14..a2409dd2 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerContainerTest.cpp
@@ -92,7 +92,7 @@
 {
     StubScriptFunction resolved, rejected;
     promise.then(resolved.function(scriptState), rejected.function(scriptState));
-    promise.isolate()->RunMicrotasks();
+    v8::MicrotasksScope::PerformCheckpoint(promise.isolate());
     EXPECT_EQ(0ul, resolved.callCount());
     EXPECT_EQ(1ul, rejected.callCount());
     if (rejected.callCount())
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
index a0cecf2..8bb957d8 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.cpp
@@ -57,7 +57,6 @@
 #include "modules/serviceworkers/WaitUntilObserver.h"
 #include "platform/Histogram.h"
 #include "platform/network/ResourceRequest.h"
-#include "platform/weborigin/DatabaseIdentifier.h"
 #include "platform/weborigin/KURL.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebURL.h"
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
index 4f009b1..05bc1bd7 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.cpp
@@ -4,6 +4,7 @@
 
 #include "modules/webgl/WebGL2RenderingContext.h"
 
+#include "bindings/modules/v8/UnionTypesModules.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/loader/FrameLoader.h"
@@ -75,6 +76,11 @@
 
 }
 
+void WebGL2RenderingContext::setCanvasGetContextResult(RenderingContext& result)
+{
+    result.setWebGL2RenderingContext(PassRefPtrWillBeRawPtr<WebGL2RenderingContext>(this));
+}
+
 void WebGL2RenderingContext::registerContextExtensions()
 {
     // Register extensions.
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h
index 773bfe4..5a27233e 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContext.h
@@ -33,6 +33,7 @@
     unsigned version() const override { return 2; }
     String contextName() const override { return "WebGL2RenderingContext"; }
     void registerContextExtensions() override;
+    void setCanvasGetContextResult(RenderingContext&) final;
 
     DECLARE_VIRTUAL_TRACE();
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index 786cdf5..f2e7257 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -1105,7 +1105,7 @@
     if (!validateTexture3DBinding("texSubImage3D", target))
         return;
 
-    RefPtr<Image> imageForRender = image->cachedImage()->image();
+    RefPtr<Image> imageForRender = image->cachedImage()->getImage();
     if (imageForRender->isSVGImage())
         imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), "texSubImage3D");
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
index b657410..56e28c6 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.cpp
@@ -25,6 +25,7 @@
 
 #include "modules/webgl/WebGLRenderingContext.h"
 
+#include "bindings/modules/v8/UnionTypesModules.h"
 #include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/layout/LayoutBox.h"
@@ -104,6 +105,11 @@
 {
 }
 
+void WebGLRenderingContext::setCanvasGetContextResult(RenderingContext& result)
+{
+    result.setWebGLRenderingContext(PassRefPtrWillBeRawPtr<WebGLRenderingContext>(this));
+}
+
 void WebGLRenderingContext::registerContextExtensions()
 {
     // Register extensions.
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h
index 1cc9191c..0f823b25 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContext.h
@@ -53,6 +53,7 @@
     unsigned version() const override { return 1; }
     String contextName() const override { return "WebGLRenderingContext"; }
     void registerContextExtensions() override;
+    void setCanvasGetContextResult(RenderingContext&) final;
 
     EAGERLY_FINALIZE();
     DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index a0b60b8..2c9e99d 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -4020,7 +4020,7 @@
     if (!validateTexture2DBinding("texImage2D", target))
         return;
 
-    RefPtr<Image> imageForRender = image->cachedImage()->image();
+    RefPtr<Image> imageForRender = image->cachedImage()->getImage();
     if (imageForRender && imageForRender->isSVGImage())
         imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), "texImage2D");
 
@@ -4394,7 +4394,7 @@
     if (!validateTexture2DBinding("texSubImage2D", target))
         return;
 
-    RefPtr<Image> imageForRender = image->cachedImage()->image();
+    RefPtr<Image> imageForRender = image->cachedImage()->getImage();
     if (imageForRender && imageForRender->isSVGImage())
         imageForRender = drawImageIntoBuffer(imageForRender.release(), image->width(), image->height(), "texSubImage2D");
 
diff --git a/third_party/WebKit/Source/platform/Cursor.h b/third_party/WebKit/Source/platform/Cursor.h
index f37fe6e81..00ef3d7 100644
--- a/third_party/WebKit/Source/platform/Cursor.h
+++ b/third_party/WebKit/Source/platform/Cursor.h
@@ -105,7 +105,7 @@
         ASSERT(m_type >= 0 && m_type <= Custom);
         return m_type;
     }
-    Image* image() const { return m_image.get(); }
+    Image* getImage() const { return m_image.get(); }
     const IntPoint& hotSpot() const { return m_hotSpot; }
     // Image scale in image pixels per logical (UI) pixel.
     float imageScaleFactor() const { return m_imageScaleFactor; }
diff --git a/third_party/WebKit/Source/platform/DragImage.cpp b/third_party/WebKit/Source/platform/DragImage.cpp
index f96ea2a..de3a48e 100644
--- a/third_party/WebKit/Source/platform/DragImage.cpp
+++ b/third_party/WebKit/Source/platform/DragImage.cpp
@@ -188,7 +188,7 @@
     // First step is drawing the link drag image width.
     TextRun labelRun(label.impl());
     TextRun urlRun(urlString.impl());
-    IntSize labelSize(labelFont.width(labelRun), labelFont.fontMetrics().ascent() + labelFont.fontMetrics().descent());
+    IntSize labelSize(labelFont.width(labelRun), labelFont.getFontMetrics().ascent() + labelFont.getFontMetrics().descent());
 
     if (labelSize.width() > maxDragLabelStringWidthDIP) {
         labelSize.setWidth(maxDragLabelStringWidthDIP);
@@ -200,7 +200,7 @@
 
     if (drawURLString) {
         urlStringSize.setWidth(urlFont.width(urlRun));
-        urlStringSize.setHeight(urlFont.fontMetrics().ascent() + urlFont.fontMetrics().descent());
+        urlStringSize.setHeight(urlFont.getFontMetrics().ascent() + urlFont.getFontMetrics().descent());
         imageSize.setHeight(imageSize.height() + urlStringSize.height());
         if (urlStringSize.width() > maxDragLabelStringWidthDIP) {
             imageSize.setWidth(maxDragLabelStringWidthDIP);
@@ -233,7 +233,7 @@
     if (drawURLString) {
         if (clipURLString)
             urlString = StringTruncator::centerTruncate(urlString, imageSize.width() - (kDragLabelBorderX * 2.0f), urlFont);
-        IntPoint textPos(kDragLabelBorderX, imageSize.height() - (kLabelBorderYOffset + urlFont.fontMetrics().descent()));
+        IntPoint textPos(kDragLabelBorderX, imageSize.height() - (kLabelBorderYOffset + urlFont.getFontMetrics().descent()));
         TextRun textRun(urlString);
         urlFont.drawText(buffer->canvas(), TextRunPaintInfo(textRun), textPos, deviceScaleFactor, textPaint);
     }
@@ -243,7 +243,7 @@
 
     bool hasStrongDirectionality;
     TextRun textRun = textRunWithDirectionality(label, &hasStrongDirectionality);
-    IntPoint textPos(kDragLabelBorderX, kDragLabelBorderY + labelFont.fontDescription().computedPixelSize());
+    IntPoint textPos(kDragLabelBorderX, kDragLabelBorderY + labelFont.getFontDescription().computedPixelSize());
     if (hasStrongDirectionality && textRun.direction() == RTL) {
         float textWidth = labelFont.width(textRun);
         int availableWidth = imageSize.width() - kDragLabelBorderX * 2;
diff --git a/third_party/WebKit/Source/platform/Prerender.h b/third_party/WebKit/Source/platform/Prerender.h
index f2106406..6943c76 100644
--- a/third_party/WebKit/Source/platform/Prerender.h
+++ b/third_party/WebKit/Source/platform/Prerender.h
@@ -69,7 +69,7 @@
     ReferrerPolicy getReferrerPolicy() const { return m_referrer.referrerPolicy; }
 
     void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; }
-    ExtraData* extraData() { return m_extraData.get(); }
+    ExtraData* getExtraData() { return m_extraData.get(); }
 
     void didStartPrerender();
     void didStopPrerender();
diff --git a/third_party/WebKit/Source/platform/UserGestureIndicator.cpp b/third_party/WebKit/Source/platform/UserGestureIndicator.cpp
index 62e614d..be074e3 100644
--- a/third_party/WebKit/Source/platform/UserGestureIndicator.cpp
+++ b/third_party/WebKit/Source/platform/UserGestureIndicator.cpp
@@ -39,15 +39,17 @@
 // For out of process tokens we allow a 10 second delay.
 const double userGestureOutOfProcessTimeout = 10.0;
 
-class GestureToken : public UserGestureToken {
+class GestureToken final : public UserGestureToken {
+    WTF_MAKE_NONCOPYABLE(GestureToken);
 public:
     static PassRefPtr<UserGestureToken> create() { return adoptRef(new GestureToken); }
 
-    ~GestureToken() override {}
+    ~GestureToken() final {}
+
     bool hasGestures() const override
     {
         // Do not enforce timeouts for gestures which spawned javascript prompts or debugger pause.
-        if (m_consumableGestures < 1 || (WTF::currentTime() - m_timestamp > (m_outOfProcess ? userGestureOutOfProcessTimeout : userGestureTimeout) && !m_javascriptPrompt && !m_pauseInDebugger))
+        if (m_consumableGestures < 1 || (!m_javascriptPrompt && !m_pauseInDebugger && hasTimedOut(m_outOfProcess ? userGestureOutOfProcessTimeout : userGestureTimeout)))
             return false;
         return true;
     }
@@ -71,27 +73,21 @@
         return true;
     }
 
-    void setOutOfProcess() override
+    void setOutOfProcess() final
     {
-        if (WTF::currentTime() - m_timestamp > userGestureTimeout)
-            return;
-        if (hasGestures())
+        if (!hasTimedOut(userGestureTimeout) && hasGestures())
             m_outOfProcess = true;
     }
 
-    void setJavascriptPrompt() override
+    void setJavascriptPrompt() final
     {
-        if (WTF::currentTime() - m_timestamp > userGestureTimeout)
-            return;
-        if (hasGestures())
+        if (!hasTimedOut(userGestureTimeout) && hasGestures())
             m_javascriptPrompt = true;
     }
 
-    void setPauseInDebugger() override
+    void setPauseInDebugger() final
     {
-        if (WTF::currentTime() - m_timestamp > userGestureTimeout)
-            return;
-        if (hasGestures())
+        if (!hasTimedOut(userGestureTimeout) && hasGestures())
             m_pauseInDebugger = true;
     }
 
@@ -105,6 +101,11 @@
     {
     }
 
+    bool hasTimedOut(double timeout) const
+    {
+        return WTF::currentTime() - m_timestamp > timeout;
+    }
+
     size_t m_consumableGestures;
     double m_timestamp;
     bool m_outOfProcess;
@@ -112,13 +113,18 @@
     bool m_pauseInDebugger;
 };
 
-} // namespace
-
-static bool isDefinite(ProcessingUserGestureState state)
+bool isDefinite(ProcessingUserGestureState state)
 {
     return state == DefinitelyProcessingNewUserGesture || state == DefinitelyProcessingUserGesture || state == DefinitelyNotProcessingUserGesture;
 }
 
+bool isDefiniteUserGesture(ProcessingUserGestureState state)
+{
+    return state == DefinitelyProcessingNewUserGesture || state == DefinitelyProcessingUserGesture;
+}
+
+} // namespace
+
 ProcessingUserGestureState UserGestureIndicator::s_state = DefinitelyNotProcessingUserGesture;
 UserGestureIndicator* UserGestureIndicator::s_topmostIndicator = 0;
 bool UserGestureIndicator::s_processedUserGestureSinceLoad = false;
@@ -138,7 +144,7 @@
             s_topmostIndicator = this;
             m_token = GestureToken::create();
         } else {
-            m_token = s_topmostIndicator->currentToken();
+            m_token = currentToken();
         }
         s_state = state;
     }
@@ -168,7 +174,7 @@
             s_topmostIndicator = this;
             m_token = token;
         } else {
-            m_token = s_topmostIndicator->currentToken();
+            m_token = currentToken();
             if (static_cast<GestureToken*>(token.get())->hasGestures()) {
                 static_cast<GestureToken*>(m_token.get())->addGesture();
                 static_cast<GestureToken*>(token.get())->consumeGesture();
@@ -186,37 +192,48 @@
         return;
     s_state = m_previousState;
     if (s_topmostIndicator == this)
-        s_topmostIndicator = 0;
+        s_topmostIndicator = nullptr;
     ASSERT(isDefinite(s_state));
 }
 
+// static
 bool UserGestureIndicator::processingUserGesture()
 {
-    if (!isMainThread())
-        return false;
-    return s_topmostIndicator && static_cast<GestureToken*>(s_topmostIndicator->currentToken())->hasGestures() && (s_state == DefinitelyProcessingNewUserGesture || s_state == DefinitelyProcessingUserGesture);
+    if (auto* token = currentToken()) {
+        ASSERT(isMainThread());
+        return isDefiniteUserGesture(s_state) && static_cast<GestureToken*>(token)->hasGestures();
+    }
+
+    return false;
 }
 
+// static
 bool UserGestureIndicator::consumeUserGesture()
 {
-    if (!isMainThread() || !s_topmostIndicator)
-        return false;
-    return static_cast<GestureToken*>(s_topmostIndicator->currentToken())->consumeGesture();
+    if (auto* token = currentToken()) {
+        ASSERT(isMainThread());
+        return static_cast<GestureToken*>(token)->consumeGesture();
+    }
+
+    return false;
 }
 
+// static
 UserGestureToken* UserGestureIndicator::currentToken()
 {
     if (!isMainThread() || !s_topmostIndicator)
-        return 0;
+        return nullptr;
     return s_topmostIndicator->m_token.get();
 }
 
+// static
 void UserGestureIndicator::clearProcessedUserGestureSinceLoad()
 {
     if (isMainThread())
         s_processedUserGestureSinceLoad = false;
 }
 
+// static
 bool UserGestureIndicator::processedUserGestureSinceLoad()
 {
     if (!isMainThread())
diff --git a/third_party/WebKit/Source/platform/UserGestureIndicator.h b/third_party/WebKit/Source/platform/UserGestureIndicator.h
index ccadaf44..aa94520 100644
--- a/third_party/WebKit/Source/platform/UserGestureIndicator.h
+++ b/third_party/WebKit/Source/platform/UserGestureIndicator.h
@@ -33,8 +33,6 @@
 
 namespace blink {
 
-class UserGestureIndicator;
-
 enum ProcessingUserGestureState {
     DefinitelyProcessingNewUserGesture,
     DefinitelyProcessingUserGesture,
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp
index ff4f19ed..ce2ee9d 100644
--- a/third_party/WebKit/Source/platform/exported/Platform.cpp
+++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -30,18 +30,24 @@
 
 #include "base/thread_task_runner_handle.h"
 #include "base/trace_event/memory_dump_manager.h"
+#include "platform/Histogram.h"
 #include "platform/PartitionAllocMemoryDumpProvider.h"
+#include "platform/fonts/FontCacheMemoryDumpProvider.h"
 #include "platform/graphics/CompositorFactory.h"
+#include "platform/heap/GCTaskRunner.h"
 #include "platform/web_memory_dump_provider_adapter.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebPrerenderingSupport.h"
 #include "wtf/HashMap.h"
 #include "wtf/OwnPtr.h"
 
 namespace blink {
 
-static Platform* s_platform = 0;
+static Platform* s_platform = nullptr;
 using ProviderToAdapterMap = HashMap<WebMemoryDumpProvider*, OwnPtr<WebMemoryDumpProviderAdapter>>;
 
+static GCTaskRunner* s_gcTaskRunner = nullptr;
+
 namespace {
 
 ProviderToAdapterMap& memoryDumpProviders()
@@ -57,25 +63,71 @@
 {
 }
 
+static void maxObservedSizeFunction(size_t sizeInMB)
+{
+    const size_t supportedMaxSizeInMB = 4 * 1024;
+    if (sizeInMB >= supportedMaxSizeInMB)
+        sizeInMB = supportedMaxSizeInMB - 1;
+
+    // Send a UseCounter only when we see the highest memory usage
+    // we've ever seen.
+    DEFINE_STATIC_LOCAL(EnumerationHistogram, committedSizeHistogram, ("PartitionAlloc.CommittedSize", supportedMaxSizeInMB));
+    committedSizeHistogram.count(sizeInMB);
+}
+
+static void callOnMainThreadFunction(WTF::MainThreadFunction function, void* context)
+{
+    Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(function, AllowCrossThreadAccess(context)));
+}
+
 void Platform::initialize(Platform* platform)
 {
+    ASSERT(!s_platform);
     ASSERT(platform);
     s_platform = platform;
     s_platform->m_mainThread = platform->currentThread();
 
+    WTF::Partitions::initialize(maxObservedSizeFunction);
+    WTF::initialize();
+    WTF::initializeMainThread(callOnMainThreadFunction);
+
+    Heap::init();
+
+    ThreadState::attachMainThread();
+
     // TODO(ssid): remove this check after fixing crbug.com/486782.
-    if (s_platform->m_mainThread)
+    if (s_platform->m_mainThread) {
+        ASSERT(!s_gcTaskRunner);
+        s_gcTaskRunner = new GCTaskRunner(s_platform->m_mainThread);
         s_platform->registerMemoryDumpProvider(PartitionAllocMemoryDumpProvider::instance(), "PartitionAlloc");
+        s_platform->registerMemoryDumpProvider(FontCacheMemoryDumpProvider::instance(), "FontCaches");
+    }
 
     CompositorFactory::initializeDefault();
 }
 
 void Platform::shutdown()
 {
+    ASSERT(isMainThread());
     CompositorFactory::shutdown();
 
-    if (s_platform->m_mainThread)
+    if (s_platform->m_mainThread) {
+        s_platform->unregisterMemoryDumpProvider(FontCacheMemoryDumpProvider::instance());
         s_platform->unregisterMemoryDumpProvider(PartitionAllocMemoryDumpProvider::instance());
+        ASSERT(s_gcTaskRunner);
+        delete s_gcTaskRunner;
+        s_gcTaskRunner = nullptr;
+    }
+
+    // Detach the main thread before starting the shutdown sequence
+    // so that the main thread won't get involved in a GC during the shutdown.
+    ThreadState::detachMainThread();
+
+    Heap::shutdown();
+
+    WTF::shutdown();
+    WebPrerenderingSupport::shutdown();
+    WTF::Partitions::shutdown();
 
     s_platform->m_mainThread = nullptr;
     s_platform = nullptr;
@@ -100,6 +152,10 @@
 
 void Platform::registerMemoryDumpProvider(WebMemoryDumpProvider* provider, const char* name)
 {
+    // MemoryDumpProvider needs a message loop.
+    if (!Platform::current()->currentThread())
+        return;
+
     WebMemoryDumpProviderAdapter* adapter = new WebMemoryDumpProviderAdapter(provider);
     ProviderToAdapterMap::AddResult result = memoryDumpProviders().add(provider, adoptPtr(adapter));
     if (!result.isNewEntry)
@@ -110,6 +166,10 @@
 
 void Platform::unregisterMemoryDumpProvider(WebMemoryDumpProvider* provider)
 {
+    // MemoryDumpProvider needs a message loop.
+    if (!Platform::current()->currentThread())
+        return;
+
     ProviderToAdapterMap::iterator it = memoryDumpProviders().find(provider);
     if (it == memoryDumpProviders().end())
         return;
diff --git a/third_party/WebKit/Source/platform/exported/WebCursorInfo.cpp b/third_party/WebKit/Source/platform/exported/WebCursorInfo.cpp
index 09108c9..ded60d9 100644
--- a/third_party/WebKit/Source/platform/exported/WebCursorInfo.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebCursorInfo.cpp
@@ -38,7 +38,7 @@
     : type(static_cast<Type>(cursor.getType()))
     , hotSpot(cursor.hotSpot())
     , imageScaleFactor(cursor.imageScaleFactor())
-    , customImage(cursor.image())
+    , customImage(cursor.getImage())
 #ifdef WIN32
     , externalHandle(0)
 #endif
diff --git a/third_party/WebKit/Source/platform/exported/WebFont.cpp b/third_party/WebKit/Source/platform/exported/WebFont.cpp
index f499328..2c8c9b18 100644
--- a/third_party/WebKit/Source/platform/exported/WebFont.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebFont.cpp
@@ -33,7 +33,7 @@
         m_font.update(nullptr);
     }
 
-    const Font& font() const { return m_font; }
+    const Font& getFont() const { return m_font; }
     String debugName() const final { return "WebFont::Impl"; }
     LayoutRect visualRect() const final
     {
@@ -55,34 +55,34 @@
     m_private.reset(0);
 }
 
-WebFontDescription WebFont::fontDescription() const
+WebFontDescription WebFont::getFontDescription() const
 {
-    return WebFontDescription(m_private->font().fontDescription());
+    return WebFontDescription(m_private->getFont().getFontDescription());
 }
 
 int WebFont::ascent() const
 {
-    return m_private->font().fontMetrics().ascent();
+    return m_private->getFont().getFontMetrics().ascent();
 }
 
 int WebFont::descent() const
 {
-    return m_private->font().fontMetrics().descent();
+    return m_private->getFont().getFontMetrics().descent();
 }
 
 int WebFont::height() const
 {
-    return m_private->font().fontMetrics().height();
+    return m_private->getFont().getFontMetrics().height();
 }
 
 int WebFont::lineSpacing() const
 {
-    return m_private->font().fontMetrics().lineSpacing();
+    return m_private->getFont().getFontMetrics().lineSpacing();
 }
 
 float WebFont::xHeight() const
 {
-    return m_private->font().fontMetrics().xHeight();
+    return m_private->getFont().getFontMetrics().xHeight();
 }
 
 void WebFont::drawText(WebCanvas* canvas, const WebTextRun& run,
@@ -104,7 +104,7 @@
         context.save();
         context.setFillColor(color);
         context.clip(textClipRect);
-        context.drawText(m_private->font(), runInfo, leftBaseline);
+        context.drawText(m_private->getFont(), runInfo, leftBaseline);
         context.restore();
     }
 
@@ -113,17 +113,17 @@
 
 int WebFont::calculateWidth(const WebTextRun& run) const
 {
-    return m_private->font().width(run, 0);
+    return m_private->getFont().width(run, 0);
 }
 
 int WebFont::offsetForPosition(const WebTextRun& run, float position) const
 {
-    return m_private->font().offsetForPosition(run, position, true);
+    return m_private->getFont().offsetForPosition(run, position, true);
 }
 
 WebFloatRect WebFont::selectionRectForText(const WebTextRun& run, const WebFloatPoint& leftBaseline, int height, int from, int to) const
 {
-    return m_private->font().selectionRectForText(run, leftBaseline, height, from, to);
+    return m_private->getFont().selectionRectForText(run, leftBaseline, height, from, to);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/exported/WebMediaStream.cpp b/third_party/WebKit/Source/platform/exported/WebMediaStream.cpp
index 076ae23..468f919 100644
--- a/third_party/WebKit/Source/platform/exported/WebMediaStream.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebMediaStream.cpp
@@ -43,7 +43,7 @@
 public:
     ExtraDataContainer(PassOwnPtr<WebMediaStream::ExtraData> extraData) : m_extraData(std::move(extraData)) { }
 
-    WebMediaStream::ExtraData* extraData() { return m_extraData.get(); }
+    WebMediaStream::ExtraData* getExtraData() { return m_extraData.get(); }
 
 private:
     OwnPtr<WebMediaStream::ExtraData> m_extraData;
@@ -66,12 +66,12 @@
     return m_private->id();
 }
 
-WebMediaStream::ExtraData* WebMediaStream::extraData() const
+WebMediaStream::ExtraData* WebMediaStream::getExtraData() const
 {
-    MediaStreamDescriptor::ExtraData* data = m_private->extraData();
+    MediaStreamDescriptor::ExtraData* data = m_private->getExtraData();
     if (!data)
         return 0;
-    return static_cast<ExtraDataContainer*>(data)->extraData();
+    return static_cast<ExtraDataContainer*>(data)->getExtraData();
 }
 
 void WebMediaStream::setExtraData(ExtraData* extraData)
diff --git a/third_party/WebKit/Source/platform/exported/WebMediaStreamSource.cpp b/third_party/WebKit/Source/platform/exported/WebMediaStreamSource.cpp
index fc2474fa..d8001a8 100644
--- a/third_party/WebKit/Source/platform/exported/WebMediaStreamSource.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebMediaStreamSource.cpp
@@ -47,7 +47,7 @@
 public:
     ExtraDataContainer(PassOwnPtr<WebMediaStreamSource::ExtraData> extraData) : m_extraData(std::move(extraData)) { }
 
-    WebMediaStreamSource::ExtraData* extraData() { return m_extraData.get(); }
+    WebMediaStreamSource::ExtraData* getExtraData() { return m_extraData.get(); }
 
 private:
     OwnPtr<WebMediaStreamSource::ExtraData> m_extraData;
@@ -142,10 +142,10 @@
 WebMediaStreamSource::ExtraData* WebMediaStreamSource::getExtraData() const
 {
     ASSERT(!m_private.isNull());
-    MediaStreamSource::ExtraData* data = m_private->extraData();
+    MediaStreamSource::ExtraData* data = m_private->getExtraData();
     if (!data)
         return 0;
-    return static_cast<ExtraDataContainer*>(data)->extraData();
+    return static_cast<ExtraDataContainer*>(data)->getExtraData();
 }
 
 void WebMediaStreamSource::setExtraData(ExtraData* extraData)
diff --git a/third_party/WebKit/Source/platform/exported/WebMediaStreamTrack.cpp b/third_party/WebKit/Source/platform/exported/WebMediaStreamTrack.cpp
index 2fec9660..5e9a00f 100644
--- a/third_party/WebKit/Source/platform/exported/WebMediaStreamTrack.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebMediaStreamTrack.cpp
@@ -39,7 +39,7 @@
 public:
     explicit ExtraDataContainer(PassOwnPtr<WebMediaStreamTrack::ExtraData> extraData) : m_extraData(std::move(extraData)) { }
 
-    WebMediaStreamTrack::ExtraData* extraData() { return m_extraData.get(); }
+    WebMediaStreamTrack::ExtraData* getExtraData() { return m_extraData.get(); }
 
 private:
     OwnPtr<WebMediaStreamTrack::ExtraData> m_extraData;
@@ -102,12 +102,12 @@
     return WebMediaStreamSource(m_private->source());
 }
 
-WebMediaStreamTrack::ExtraData* WebMediaStreamTrack::extraData() const
+WebMediaStreamTrack::ExtraData* WebMediaStreamTrack::getExtraData() const
 {
-    MediaStreamComponent::ExtraData* data = m_private->extraData();
+    MediaStreamComponent::ExtraData* data = m_private->getExtraData();
     if (!data)
         return 0;
-    return static_cast<ExtraDataContainer*>(data)->extraData();
+    return static_cast<ExtraDataContainer*>(data)->getExtraData();
 }
 
 void WebMediaStreamTrack::setExtraData(ExtraData* extraData)
diff --git a/third_party/WebKit/Source/platform/exported/WebPrerender.cpp b/third_party/WebKit/Source/platform/exported/WebPrerender.cpp
index 426ef683..a97cc61 100644
--- a/third_party/WebKit/Source/platform/exported/WebPrerender.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebPrerender.cpp
@@ -43,7 +43,7 @@
 
     ~ExtraDataContainer() override {}
 
-    WebPrerender::ExtraData* extraData() const { return m_extraData.get(); }
+    WebPrerender::ExtraData* getExtraData() const { return m_extraData.get(); }
 
 private:
     explicit ExtraDataContainer(WebPrerender::ExtraData* extraData)
@@ -106,12 +106,12 @@
     m_private->setExtraData(ExtraDataContainer::create(extraData));
 }
 
-const WebPrerender::ExtraData* WebPrerender::extraData() const
+const WebPrerender::ExtraData* WebPrerender::getExtraData() const
 {
-    RefPtr<Prerender::ExtraData> webcoreExtraData = m_private->extraData();
+    RefPtr<Prerender::ExtraData> webcoreExtraData = m_private->getExtraData();
     if (!webcoreExtraData)
         return 0;
-    return static_cast<ExtraDataContainer*>(webcoreExtraData.get())->extraData();
+    return static_cast<ExtraDataContainer*>(webcoreExtraData.get())->getExtraData();
 }
 
 void WebPrerender::didStartPrerender()
diff --git a/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp b/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp
index 99e6a59..a4f1614 100644
--- a/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp
@@ -49,7 +49,7 @@
 
     ~ExtraDataContainer() override {}
 
-    WebURLRequest::ExtraData* extraData() const { return m_extraData.get(); }
+    WebURLRequest::ExtraData* getExtraData() const { return m_extraData.get(); }
 
 private:
     explicit ExtraDataContainer(WebURLRequest::ExtraData* extraData)
@@ -386,12 +386,12 @@
     return m_private->m_resourceRequest->setLoFiState(loFiState);
 }
 
-WebURLRequest::ExtraData* WebURLRequest::extraData() const
+WebURLRequest::ExtraData* WebURLRequest::getExtraData() const
 {
-    RefPtr<ResourceRequest::ExtraData> data = m_private->m_resourceRequest->extraData();
+    RefPtr<ResourceRequest::ExtraData> data = m_private->m_resourceRequest->getExtraData();
     if (!data)
         return 0;
-    return static_cast<ExtraDataContainer*>(data.get())->extraData();
+    return static_cast<ExtraDataContainer*>(data.get())->getExtraData();
 }
 
 void WebURLRequest::setExtraData(WebURLRequest::ExtraData* extraData)
diff --git a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
index 946b8e5..9aab10f5 100644
--- a/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebURLResponse.cpp
@@ -51,7 +51,7 @@
 
     ~ExtraDataContainer() override {}
 
-    WebURLResponse::ExtraData* extraData() const { return m_extraData.get(); }
+    WebURLResponse::ExtraData* getExtraData() const { return m_extraData.get(); }
 
 private:
     explicit ExtraDataContainer(WebURLResponse::ExtraData* extraData)
@@ -440,14 +440,9 @@
     m_private->m_resourceResponse->setOriginalURLViaServiceWorker(url);
 }
 
-bool WebURLResponse::isMultipartPayload() const
+void WebURLResponse::setMultipartBoundary(const char* bytes, size_t size)
 {
-    return m_private->m_resourceResponse->isMultipartPayload();
-}
-
-void WebURLResponse::setIsMultipartPayload(bool value)
-{
-    m_private->m_resourceResponse->setIsMultipartPayload(value);
+    m_private->m_resourceResponse->setMultipartBoundary(bytes, size);
 }
 
 WebString WebURLResponse::downloadFilePath() const
@@ -480,12 +475,12 @@
     m_private->m_resourceResponse->setRemotePort(remotePort);
 }
 
-WebURLResponse::ExtraData* WebURLResponse::extraData() const
+WebURLResponse::ExtraData* WebURLResponse::getExtraData() const
 {
-    RefPtr<ResourceResponse::ExtraData> data = m_private->m_resourceResponse->extraData();
+    RefPtr<ResourceResponse::ExtraData> data = m_private->m_resourceResponse->getExtraData();
     if (!data)
         return 0;
-    return static_cast<ExtraDataContainer*>(data.get())->extraData();
+    return static_cast<ExtraDataContainer*>(data.get())->getExtraData();
 }
 
 void WebURLResponse::setExtraData(WebURLResponse::ExtraData* extraData)
diff --git a/third_party/WebKit/Source/platform/fonts/Font.cpp b/third_party/WebKit/Source/platform/fonts/Font.cpp
index 8329e502..5dd61a5 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.cpp
+++ b/third_party/WebKit/Source/platform/fonts/Font.cpp
@@ -87,8 +87,8 @@
 
 bool Font::operator==(const Font& other) const
 {
-    FontSelector* first = m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0;
-    FontSelector* second = other.m_fontFallbackList ? other.m_fontFallbackList->fontSelector() : 0;
+    FontSelector* first = m_fontFallbackList ? m_fontFallbackList->getFontSelector() : 0;
+    FontSelector* second = other.m_fontFallbackList ? other.m_fontFallbackList->getFontSelector() : 0;
 
     return first == second
         && m_fontDescription == other.m_fontDescription
@@ -318,8 +318,8 @@
         } else {
             ASSERT(m_hasVerticalOffsets);
 
-            const float verticalBaselineXOffset = fontData->fontMetrics().floatAscent()
-                - fontData->fontMetrics().floatAscent(IdeographicBaseline);
+            const float verticalBaselineXOffset = fontData->getFontMetrics().floatAscent()
+                - fontData->getFontMetrics().floatAscent(IdeographicBaseline);
 
             // TODO(fmalita): why don't we apply this adjustment when building the glyph buffer?
             for (unsigned i = 0; i < 2 * count; i += 2) {
@@ -402,7 +402,7 @@
 {
     FontCachePurgePreventer purgePreventer;
 
-    if (codePath(TextRunPaintInfo(run)) != ComplexPath && !fontDescription().getTypesettingFeatures())
+    if (codePath(TextRunPaintInfo(run)) != ComplexPath && !getFontDescription().getTypesettingFeatures())
         return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
 
     return offsetForPositionForComplexText(run, x, includePartialGlyphs);
@@ -421,7 +421,7 @@
 
     const TextRun& run = runInfo.run;
 
-    if (fontDescription().getTypesettingFeatures() && (runInfo.from || runInfo.to != run.length()))
+    if (getFontDescription().getTypesettingFeatures() && (runInfo.from || runInfo.to != run.length()))
         return ComplexPath;
 
     if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0)
@@ -433,13 +433,13 @@
     if (m_fontDescription.widthVariant() != RegularWidth)
         return ComplexPath;
 
-    if (run.length() > 1 && fontDescription().getTypesettingFeatures())
+    if (run.length() > 1 && getFontDescription().getTypesettingFeatures())
         return ComplexPath;
 
     // FIXME: This really shouldn't be needed but for some reason the
     // TextRendering setting doesn't propagate to typesettingFeatures in time
     // for the prefs width calculation.
-    if (fontDescription().textRendering() == OptimizeLegibility || fontDescription().textRendering() == GeometricPrecision)
+    if (getFontDescription().textRendering() == OptimizeLegibility || getFontDescription().textRendering() == GeometricPrecision)
         return ComplexPath;
 
     if (run.is8Bit())
@@ -460,19 +460,19 @@
 
 bool Font::computeCanShapeWordByWord() const
 {
-    if (!fontDescription().getTypesettingFeatures())
+    if (!getFontDescription().getTypesettingFeatures())
         return true;
 
     const FontPlatformData& platformData = primaryFont()->platformData();
-    TypesettingFeatures features = fontDescription().getTypesettingFeatures();
+    TypesettingFeatures features = getFontDescription().getTypesettingFeatures();
     return !platformData.hasSpaceInLigaturesOrKerning(features);
 };
 
 void Font::willUseFontData(UChar32 character) const
 {
-    const FontFamily& family = fontDescription().family();
-    if (m_fontFallbackList && m_fontFallbackList->fontSelector() && !family.familyIsEmpty())
-        m_fontFallbackList->fontSelector()->willUseFontData(fontDescription(), family.family(), character);
+    const FontFamily& family = getFontDescription().family();
+    if (m_fontFallbackList && m_fontFallbackList->getFontSelector() && !family.familyIsEmpty())
+        m_fontFallbackList->getFontSelector()->willUseFontData(getFontDescription(), family.family(), character);
 }
 
 static inline GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(UChar32 character, bool isUpright, GlyphData& data, unsigned pageNumber)
@@ -693,7 +693,7 @@
     if (!markFontData)
         return 0;
 
-    return markFontData->fontMetrics().ascent();
+    return markFontData->getFontMetrics().ascent();
 }
 
 int Font::emphasisMarkDescent(const AtomicString& mark) const
@@ -709,7 +709,7 @@
     if (!markFontData)
         return 0;
 
-    return markFontData->fontMetrics().descent();
+    return markFontData->getFontMetrics().descent();
 }
 
 int Font::emphasisMarkHeight(const AtomicString& mark) const
@@ -725,7 +725,7 @@
     if (!markFontData)
         return 0;
 
-    return markFontData->fontMetrics().height();
+    return markFontData->getFontMetrics().height();
 }
 
 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, FloatRect* glyphBounds) const
@@ -752,6 +752,19 @@
     return FloatRect(point.x() + range.start, point.y(), range.width(), height);
 }
 
+Vector<CharacterRange> Font::individualCharacterRanges(const TextRun& run,
+    int from, int to) const
+{
+    // TODO(pdr): Android is temporarily (crbug.com/577306) using the old simple
+    // shaper and using the complex shaper here can show differences between
+    // the two shapers. This function is currently only called through SVG
+    // which now exclusively uses the complex shaper, so the primary difference
+    // will be improved shaping in SVG when compared to HTML.
+    FontCachePurgePreventer purgePreventer;
+    CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
+    return shaper.individualCharacterRanges(this, run, from, to);
+}
+
 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, FloatRect* glyphBounds) const
 {
     SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds);
diff --git a/third_party/WebKit/Source/platform/fonts/Font.h b/third_party/WebKit/Source/platform/fonts/Font.h
index 6254fff..c7794a1 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.h
+++ b/third_party/WebKit/Source/platform/fonts/Font.h
@@ -46,6 +46,7 @@
 
 namespace blink {
 
+struct CharacterRange;
 class FloatPoint;
 class FloatRect;
 class FontFallbackIterator;
@@ -71,7 +72,7 @@
     bool operator==(const Font& other) const;
     bool operator!=(const Font& other) const { return !(*this == other); }
 
-    const FontDescription& fontDescription() const { return m_fontDescription; }
+    const FontDescription& getFontDescription() const { return m_fontDescription; }
 
     void update(PassRefPtrWillBeRawPtr<FontSelector>) const;
 
@@ -86,14 +87,15 @@
 
     int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
     FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1, bool accountForGlyphBounds = false) const;
+    Vector<CharacterRange> individualCharacterRanges(const TextRun&, int from, int to) const;
 
     // Metrics that we query the FontFallbackList for.
-    const FontMetrics& fontMetrics() const
+    const FontMetrics& getFontMetrics() const
     {
         RELEASE_ASSERT(primaryFont());
-        return primaryFont()->fontMetrics();
+        return primaryFont()->getFontMetrics();
     }
-    float spaceWidth() const { return primaryFont()->spaceWidth() + fontDescription().letterSpacing(); }
+    float spaceWidth() const { return primaryFont()->spaceWidth() + getFontDescription().letterSpacing(); }
     float tabWidth(const SimpleFontData&, const TabSize&, float position) const;
     float tabWidth(const TabSize& tabSize, float position) const { return tabWidth(*primaryFont(), tabSize, position); }
 
@@ -139,7 +141,7 @@
     friend struct SimpleShaper;
 
 public:
-    FontSelector* fontSelector() const;
+    FontSelector* getFontSelector() const;
     PassRefPtr<FontFallbackIterator> createFontFallbackIterator(
         FontFallbackPriority) const;
 
@@ -179,21 +181,21 @@
     return m_fontFallbackList->fontDataAt(m_fontDescription, index);
 }
 
-inline FontSelector* Font::fontSelector() const
+inline FontSelector* Font::getFontSelector() const
 {
-    return m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0;
+    return m_fontFallbackList ? m_fontFallbackList->getFontSelector() : 0;
 }
 
 inline float Font::tabWidth(const SimpleFontData& fontData, const TabSize& tabSize, float position) const
 {
     float baseTabWidth = tabSize.getPixelSize(fontData.spaceWidth());
     if (!baseTabWidth)
-        return fontDescription().letterSpacing();
+        return getFontDescription().letterSpacing();
     float distanceToTabStop = baseTabWidth - fmodf(position, baseTabWidth);
 
     // The smallest allowable tab space is letterSpacing() (but must be at least one layout unit).
     // if the distance to the next tab stop is less than that, advance an additional tab stop.
-    if (distanceToTabStop < std::max(fontDescription().letterSpacing(), LayoutUnit::epsilon()))
+    if (distanceToTabStop < std::max(getFontDescription().letterSpacing(), LayoutUnit::epsilon()))
         distanceToTabStop += baseTabWidth;
 
     return distanceToTabStop;
diff --git a/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp b/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp
index 0b73e27..a80122f 100644
--- a/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp
+++ b/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp
@@ -66,7 +66,7 @@
 
 void FontFallbackIterator::willUseRange(const AtomicString& family, const FontDataRange& range)
 {
-    FontSelector* selector = m_fontFallbackList->fontSelector();
+    FontSelector* selector = m_fontFallbackList->getFontSelector();
     if (!selector)
         return;
 
diff --git a/third_party/WebKit/Source/platform/fonts/FontFallbackList.h b/third_party/WebKit/Source/platform/fonts/FontFallbackList.h
index 7eac4f8f..66c66ab 100644
--- a/third_party/WebKit/Source/platform/fonts/FontFallbackList.h
+++ b/third_party/WebKit/Source/platform/fonts/FontFallbackList.h
@@ -74,7 +74,7 @@
     bool loadingCustomFonts() const;
     bool shouldSkipDrawing() const;
 
-    FontSelector* fontSelector() const { return m_fontSelector.get(); }
+    FontSelector* getFontSelector() const { return m_fontSelector.get(); }
     // FIXME: It should be possible to combine fontSelectorVersion and generation.
     unsigned fontSelectorVersion() const { return m_fontSelectorVersion; }
     unsigned generation() const { return m_generation; }
@@ -86,8 +86,8 @@
             m_shapeCache = FontCache::fontCache()->getShapeCache(key)->weakPtr();
         }
         ASSERT(m_shapeCache);
-        if (fontSelector())
-            m_shapeCache->clearIfVersionChanged(fontSelector()->version());
+        if (getFontSelector())
+            m_shapeCache->clearIfVersionChanged(getFontSelector()->version());
         return m_shapeCache.get();
     }
 
diff --git a/third_party/WebKit/Source/platform/fonts/FontPlatformData.h b/third_party/WebKit/Source/platform/fonts/FontPlatformData.h
index 2a1c78df..0ad9c86 100644
--- a/third_party/WebKit/Source/platform/fonts/FontPlatformData.h
+++ b/third_party/WebKit/Source/platform/fonts/FontPlatformData.h
@@ -128,7 +128,7 @@
 
 #if !OS(MACOSX)
     // The returned styles are all actual styles without FontRenderStyle::NoPreference.
-    const FontRenderStyle& fontRenderStyle() const { return m_style; }
+    const FontRenderStyle& getFontRenderStyle() const { return m_style; }
 #endif
     void setupPaint(SkPaint*, float deviceScaleFactor = 1, const Font* = 0) const;
 
diff --git a/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp
index c9522e8a..d4c4bd9 100644
--- a/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/ScriptRunIteratorTest.cpp
@@ -325,7 +325,6 @@
             ASSERT_EQ(expect[runCount].code, code);
             ++runCount;
         }
-        WTF_LOG_ERROR("Expected %zu runs, got %lu ", expect.size(), runCount);
         ASSERT_EQ(expect.size(), runCount);
     }
 };
diff --git a/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp b/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp
index 12c1287..b3eae92 100644
--- a/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp
+++ b/third_party/WebKit/Source/platform/fonts/SimpleFontData.cpp
@@ -141,7 +141,7 @@
         // of the glyph may be truncated when displayed in a 'overflow: hidden' container.
         // To avoid that, borrow 1 unit from the ascent when possible.
         // FIXME: This can be removed if sub-pixel ascent/descent is supported.
-        if (platformData().fontRenderStyle().useSubpixelPositioning && descent < SkScalarToFloat(metrics.fDescent) && ascent >= 1) {
+        if (platformData().getFontRenderStyle().useSubpixelPositioning && descent < SkScalarToFloat(metrics.fDescent) && ascent >= 1) {
             ++descent;
             --ascent;
         }
diff --git a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
index 94d75be..eed56b4 100644
--- a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
+++ b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
@@ -83,10 +83,10 @@
     bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
     bool isTextOrientationFallbackOf(const SimpleFontData*) const;
 
-    FontMetrics& fontMetrics() { return m_fontMetrics; }
-    const FontMetrics& fontMetrics() const { return m_fontMetrics; }
-    float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); }
-    float internalLeading() const { return fontMetrics().floatHeight() - platformData().size(); }
+    FontMetrics& getFontMetrics() { return m_fontMetrics; }
+    const FontMetrics& getFontMetrics() const { return m_fontMetrics; }
+    float sizePerUnit() const { return platformData().size() / (getFontMetrics().unitsPerEm() ? getFontMetrics().unitsPerEm() : 1); }
+    float internalLeading() const { return getFontMetrics().floatHeight() - platformData().size(); }
 
     float maxCharWidth() const { return m_maxCharWidth; }
     void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
diff --git a/third_party/WebKit/Source/platform/fonts/mac/FontPlatformDataMac.mm b/third_party/WebKit/Source/platform/fonts/mac/FontPlatformDataMac.mm
index bfb4147..2c7346a 100644
--- a/third_party/WebKit/Source/platform/fonts/mac/FontPlatformDataMac.mm
+++ b/third_party/WebKit/Source/platform/fonts/mac/FontPlatformDataMac.mm
@@ -107,7 +107,7 @@
     bool shouldAntialias = true;
 
     if (font) {
-        switch (font->fontDescription().fontSmoothing()) {
+        switch (font->getFontDescription().fontSmoothing()) {
         case Antialiased:
             shouldSmoothFonts = false;
             break;
@@ -141,7 +141,7 @@
     // When rendering using CoreGraphics, disable hinting when webkit-font-smoothing:antialiased or
     // text-rendering:geometricPrecision is used.
     // See crbug.com/152304
-    if (font && (font->fontDescription().fontSmoothing() == Antialiased || font->fontDescription().textRendering() == GeometricPrecision))
+    if (font && (font->getFontDescription().fontSmoothing() == Antialiased || font->getFontDescription().textRendering() == GeometricPrecision))
         paint->setHinting(SkPaint::kNo_Hinting);
 }
 
diff --git a/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeVerticalData.cpp b/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeVerticalData.cpp
index 556e52f..62a2a15 100644
--- a/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeVerticalData.cpp
+++ b/third_party/WebKit/Source/platform/fonts/opentype/OpenTypeVerticalData.cpp
@@ -216,14 +216,14 @@
     }
 
     // No vertical info in the font file; use height as advance.
-    return font->fontMetrics().height();
+    return font->getFontMetrics().height();
 }
 
 void OpenTypeVerticalData::getVerticalTranslationsForGlyphs(const SimpleFontData* font, const Glyph* glyphs, size_t count, float* outXYArray) const
 {
     size_t countWidths = m_advanceWidths.size();
     ASSERT(countWidths > 0);
-    const FontMetrics& metrics = font->fontMetrics();
+    const FontMetrics& metrics = font->getFontMetrics();
     float sizePerUnit = font->sizePerUnit();
     float ascent = metrics.ascent();
     bool useVORG = hasVORG();
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
index 75cc46e..8717679e 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
@@ -46,7 +46,7 @@
         , m_widthSoFar(0), m_startIndex(0)
     {
         ASSERT(font);
-        const FontDescription& fontDescription = font->fontDescription();
+        const FontDescription& fontDescription = font->getFontDescription();
 
         // Word and letter spacing can change the width of a word, as can tabs
         // as we segment solely based on on space characters.
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
index 92023e3..09455027 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
@@ -116,4 +116,20 @@
     return buffer.getCharacterRange(run.direction(), totalWidth, from, to);
 }
 
+Vector<CharacterRange> CachingWordShaper::individualCharacterRanges(
+    const Font* font, const TextRun& run, unsigned from, unsigned to)
+{
+    ShapeResultBuffer buffer;
+    float totalWidth = shapeResultsForRun(m_shapeCache, font, run, nullptr,
+        &buffer);
+
+    Vector<CharacterRange> allExtents;
+    for (unsigned position = from; position <= to; position++) {
+        allExtents.append(buffer.getCharacterRange(run.direction(), totalWidth,
+            position, position + 1));
+    }
+
+    return allExtents;
+}
+
 }; // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
index 5907c46..5fda353 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
@@ -61,6 +61,8 @@
         unsigned from, unsigned to);
     CharacterRange getCharacterRange(const Font*, const TextRun&,
         unsigned from, unsigned to);
+    Vector<CharacterRange> individualCharacterRanges(const Font*,
+        const TextRun&, unsigned from, unsigned to);
 
 private:
     ShapeCache* m_shapeCache;
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
index 39c0c02..ac756ab 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
@@ -253,7 +253,7 @@
     HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
     const OpenTypeVerticalData* verticalData = hbFontData->m_simpleFontData->verticalData();
     if (!verticalData)
-        return SkiaScalarToHarfBuzzPosition(hbFontData->m_simpleFontData->fontMetrics().height());
+        return SkiaScalarToHarfBuzzPosition(hbFontData->m_simpleFontData->getFontMetrics().height());
 
     Glyph theGlyph = glyph;
     float advanceHeight = -verticalData->advanceHeight(hbFontData->m_simpleFontData.get(), theGlyph);
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
index b946a26..44d12de1 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -116,8 +116,8 @@
 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run)
     : Shaper(font, run)
     , m_normalizedBufferLength(0)
-    , m_wordSpacingAdjustment(font->fontDescription().wordSpacing())
-    , m_letterSpacing(font->fontDescription().letterSpacing())
+    , m_wordSpacingAdjustment(font->getFontDescription().wordSpacing())
+    , m_letterSpacing(font->getFontDescription().letterSpacing())
     , m_expansionOpportunityCount(0)
 {
     m_normalizedBuffer = adoptArrayPtr(new UChar[m_textRun.length() + 1]);
@@ -171,7 +171,7 @@
 
 void HarfBuzzShaper::setFontFeatures()
 {
-    const FontDescription& description = m_font->fontDescription();
+    const FontDescription& description = m_font->getFontDescription();
 
     static hb_feature_t noKern = createFeature('k', 'e', 'r', 'n');
     static hb_feature_t noVkrn = createFeature('v', 'k', 'r', 'n');
@@ -332,10 +332,10 @@
     hb_buffer_set_language(harfBuzzBuffer, language);
     hb_buffer_set_script(harfBuzzBuffer, ICUScriptToHBScript(currentRunScript));
     hb_buffer_set_direction(harfBuzzBuffer, TextDirectionToHBDirection(m_textRun.direction(),
-        m_font->fontDescription().orientation(), currentFont));
+        m_font->getFontDescription().orientation(), currentFont));
 
     addToHarfBuzzBufferInternal(harfBuzzBuffer,
-        m_font->fontDescription(), m_normalizedBuffer.get(), m_normalizedBufferLength,
+        m_font->getFontDescription(), m_normalizedBuffer.get(), m_normalizedBufferLength,
         startIndex, numCharacters);
 
     HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(currentFontRangeFrom, currentFontRangeTo), hb_font_destroy);
@@ -459,7 +459,7 @@
             // Here we need to specify glyph positions.
             OwnPtr<ShapeResult::RunInfo> run = adoptPtr(new ShapeResult::RunInfo(currentFont,
                 TextDirectionToHBDirection(m_textRun.direction(),
-                m_font->fontDescription().orientation(), currentFont),
+                m_font->getFontDescription().orientation(), currentFont),
                 ICUScriptToHBScript(currentRunScript),
                 startIndex,
                 numGlyphsToInsert, numCharacters));
@@ -523,7 +523,7 @@
         m_normalizedBufferLength, m_textRun.direction());
     HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_destroy);
 
-    const FontDescription& fontDescription = m_font->fontDescription();
+    const FontDescription& fontDescription = m_font->getFontDescription();
     const String& localeString = fontDescription.locale();
     CString locale = localeString.latin1();
     const hb_language_t language = hb_language_from_string(locale.data(), locale.length());
@@ -538,7 +538,7 @@
     RunSegmenter runSegmenter(
         m_normalizedBuffer.get(),
         m_normalizedBufferLength,
-        m_font->fontDescription().orientation(),
+        m_font->getFontDescription().orientation(),
         fontDescription.variant());
 
     Vector<UChar32> fallbackCharsHint;
@@ -599,7 +599,7 @@
             // TODO: crbug.com/506224 This should go away in favor of storing that information elsewhere, for example in
             // ShapeResult.
             const SimpleFontData* directionAndSmallCapsAdjustedFont = fontDataAdjustedForOrientation(smallcapsAdjustedFont,
-                m_font->fontDescription().orientation(),
+                m_font->getFontDescription().orientation(),
                 segmentRange.renderOrientation);
 
             if (!shapeRange(harfBuzzBuffer.get(),
@@ -645,7 +645,7 @@
     float totalAdvance = 0.0f;
     FloatPoint glyphOrigin;
     float offsetX, offsetY;
-    float* directionOffset = m_font->fontDescription().isVerticalAnyUpright() ? &offsetY : &offsetX;
+    float* directionOffset = m_font->getFontDescription().isVerticalAnyUpright() ? &offsetY : &offsetX;
     bool hasVerticalOffsets = !HB_DIRECTION_IS_HORIZONTAL(run->m_direction);
 
     // HarfBuzz returns result in visual order, no need to flip for RTL.
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.cpp
index f8d0ef57..f1bc7a1c 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.cpp
@@ -87,7 +87,7 @@
 {
     // Account for letter-spacing.
     if (width)
-        width += m_font->fontDescription().letterSpacing();
+        width += m_font->getFontDescription().letterSpacing();
 
     bool isExpansionOpportunity = Character::treatAsSpace(charData.character) || (m_textRun.getTextJustify() == TextJustifyDistribute);
     if (isExpansionOpportunity || (m_textRun.getTextJustify() == TextJustifyAuto && Character::isCJKIdeographOrSymbol(charData.character))) {
@@ -113,8 +113,8 @@
         // We apply additional space between "words" by adding width to the space character.
         if (isExpansionOpportunity && (charData.character != tabulationCharacter || !m_textRun.allowTabs())
             && (charData.characterOffset || charData.character == noBreakSpaceCharacter)
-            && m_font->fontDescription().wordSpacing()) {
-            width += m_font->fontDescription().wordSpacing();
+            && m_font->getFontDescription().wordSpacing()) {
+            width += m_font->getFontDescription().wordSpacing();
         }
     } else {
         m_isAfterExpansion = false;
@@ -126,7 +126,7 @@
 template <typename TextIterator>
 unsigned SimpleShaper::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer)
 {
-    bool hasExtraSpacing = (m_font->fontDescription().letterSpacing() || m_font->fontDescription().wordSpacing() || m_expansion)
+    bool hasExtraSpacing = (m_font->getFontDescription().letterSpacing() || m_font->getFontDescription().wordSpacing() || m_expansion)
         && !m_textRun.spacingDisabled();
 
     const SimpleFontData* lastFontData = m_font->primaryFont();
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.h b/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.h
index 6b49cb4..fb4d138 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/SimpleShaper.h
@@ -40,9 +40,6 @@
 struct GlyphData;
 
 struct PLATFORM_EXPORT SimpleShaper : public Shaper {
-    // SVGTextMetricsCalculator wants to allocate SimpleShaper by using
-    // operator new.
-    USING_FAST_MALLOC(SimpleShaper);
 public:
     SimpleShaper(const Font*, const TextRun&, const GlyphData* emphasisData = nullptr,
         HashSet<const SimpleFontData*>* fallbackFonts = nullptr, FloatRect* = nullptr);
diff --git a/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.cpp b/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.cpp
index 0b2ce34..245a96b2 100644
--- a/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.cpp
+++ b/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.cpp
@@ -318,7 +318,7 @@
 
 void FloatRoundedRect::constrainRadii()
 {
-    m_radii.scaleAndFloor(calcBorderRadiiConstraintScaleFor(rect(), radii()));
+    m_radii.scaleAndFloor(calcBorderRadiiConstraintScaleFor(rect(), getRadii()));
 }
 
 void FloatRoundedRect::includeLogicalEdges(const Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
diff --git a/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.h b/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.h
index f189a61..f3ccbbf 100644
--- a/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.h
+++ b/third_party/WebKit/Source/platform/geometry/FloatRoundedRect.h
@@ -104,7 +104,7 @@
     FloatRoundedRect(const FloatRect&, const FloatSize& topLeft, const FloatSize& topRight, const FloatSize& bottomLeft, const FloatSize& bottomRight);
 
     const FloatRect& rect() const { return m_rect; }
-    const Radii& radii() const { return m_radii; }
+    const Radii& getRadii() const { return m_radii; }
     bool isRounded() const { return !m_radii.isZero(); }
     bool isEmpty() const { return m_rect.isEmpty(); }
 
@@ -204,7 +204,7 @@
 
 inline bool operator==(const FloatRoundedRect& a, const FloatRoundedRect& b)
 {
-    return a.rect() == b.rect() && a.radii() == b.radii();
+    return a.rect() == b.rect() && a.getRadii() == b.getRadii();
 }
 
 // Redeclared here to avoid ODR issues.
diff --git a/third_party/WebKit/Source/platform/geometry/FloatRoundedRectTest.cpp b/third_party/WebKit/Source/platform/geometry/FloatRoundedRectTest.cpp
index 35a457f8..272417a 100644
--- a/third_party/WebKit/Source/platform/geometry/FloatRoundedRectTest.cpp
+++ b/third_party/WebKit/Source/platform/geometry/FloatRoundedRectTest.cpp
@@ -47,11 +47,11 @@
     FloatRoundedRect r = FloatRoundedRect(1, 2, 3, 4);
 
     EXPECT_EQ(FloatRect(1, 2, 3, 4), r.rect());
-    EXPECT_EQ(FloatSize(), r.radii().topLeft());
-    EXPECT_EQ(FloatSize(), r.radii().topRight());
-    EXPECT_EQ(FloatSize(), r.radii().bottomLeft());
-    EXPECT_EQ(FloatSize(), r.radii().bottomRight());
-    EXPECT_TRUE(r.radii().isZero());
+    EXPECT_EQ(FloatSize(), r.getRadii().topLeft());
+    EXPECT_EQ(FloatSize(), r.getRadii().topRight());
+    EXPECT_EQ(FloatSize(), r.getRadii().bottomLeft());
+    EXPECT_EQ(FloatSize(), r.getRadii().bottomRight());
+    EXPECT_TRUE(r.getRadii().isZero());
     EXPECT_FALSE(r.isRounded());
     EXPECT_FALSE(r.isEmpty());
 
@@ -74,7 +74,7 @@
     // are <= zero. Same as RoundedRect::expandRadii().
     r.expandRadii(20);
     r.shrinkRadii(10);
-    EXPECT_TRUE(r.radii().isZero());
+    EXPECT_TRUE(r.getRadii().isZero());
 }
 
 TEST(FloatRoundedRectTest, circle)
@@ -83,11 +83,11 @@
     FloatRoundedRect r(FloatRect(0, 0, 100, 100), cornerRadii, cornerRadii, cornerRadii, cornerRadii);
 
     EXPECT_EQ(FloatRect(0, 0, 100, 100), r.rect());
-    EXPECT_EQ(cornerRadii, r.radii().topLeft());
-    EXPECT_EQ(cornerRadii, r.radii().topRight());
-    EXPECT_EQ(cornerRadii, r.radii().bottomLeft());
-    EXPECT_EQ(cornerRadii, r.radii().bottomRight());
-    EXPECT_FALSE(r.radii().isZero());
+    EXPECT_EQ(cornerRadii, r.getRadii().topLeft());
+    EXPECT_EQ(cornerRadii, r.getRadii().topRight());
+    EXPECT_EQ(cornerRadii, r.getRadii().bottomLeft());
+    EXPECT_EQ(cornerRadii, r.getRadii().bottomRight());
+    EXPECT_FALSE(r.getRadii().isZero());
     EXPECT_TRUE(r.isRounded());
     EXPECT_FALSE(r.isEmpty());
 
@@ -133,7 +133,7 @@
 
     FloatRoundedRect r(FloatRect(0, 0, 100, 100), cornerRadii);
 
-    EXPECT_EQ(r.radii(), FloatRoundedRect::Radii(FloatSize(10, 15), FloatSize(10, 20), FloatSize(25, 15), FloatSize(20, 30)));
+    EXPECT_EQ(r.getRadii(), FloatRoundedRect::Radii(FloatSize(10, 15), FloatSize(10, 20), FloatSize(25, 15), FloatSize(20, 30)));
     EXPECT_EQ(r, FloatRoundedRect(FloatRect(0, 0, 100, 100), cornerRadii));
 
     EXPECT_EQ(FloatRect(0, 0, 10, 15), r.topLeftCorner());
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
index 34894c61..fad71475 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -136,8 +136,8 @@
 
 void BitmapImage::notifyMemoryChanged(int delta)
 {
-    if (delta && imageObserver())
-        imageObserver()->decodedSizeChanged(this, delta);
+    if (delta && getImageObserver())
+        getImageObserver()->decodedSizeChanged(this, delta);
 }
 
 int BitmapImage::totalFrameBytes()
@@ -300,7 +300,7 @@
     if (currentFrameIsLazyDecoded())
         PlatformInstrumentation::didDrawLazyPixelRef(image->uniqueID());
 
-    if (ImageObserver* observer = imageObserver())
+    if (ImageObserver* observer = getImageObserver())
         observer->didDraw(this);
 
     startAnimation();
@@ -453,7 +453,7 @@
 
 bool BitmapImage::shouldAnimate()
 {
-    bool animated = repetitionCount(false) != cAnimationNone && !m_animationFinished && imageObserver();
+    bool animated = repetitionCount(false) != cAnimationNone && !m_animationFinished && getImageObserver();
     if (animated && m_animationPolicy == ImageAnimationPolicyNoAnimation)
         animated = false;
     return animated;
@@ -609,7 +609,7 @@
 
     // See if anyone is still paying attention to this animation.  If not, we don't
     // advance and will remain suspended at the current frame until the animation is resumed.
-    if (!skippingFrames && imageObserver()->shouldPauseAnimation(this))
+    if (!skippingFrames && getImageObserver()->shouldPauseAnimation(this))
         return false;
 
     ++m_currentFrame;
@@ -636,7 +636,7 @@
     // We need to draw this frame if we advanced to it while not skipping, or if
     // while trying to skip frames we hit the last frame and thus had to stop.
     if (skippingFrames != advancedAnimation)
-        imageObserver()->animationAdvanced(this);
+        getImageObserver()->animationAdvanced(this);
     return advancedAnimation;
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp
index 040e0280..da8a4ae 100644
--- a/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ContentLayerDelegate.cpp
@@ -75,7 +75,7 @@
 {
     TRACE_EVENT0("blink,benchmark", "ContentLayerDelegate::paintContents");
 
-    PaintController& paintController = m_graphicsLayer->paintController();
+    PaintController& paintController = m_graphicsLayer->getPaintController();
     paintController.setDisplayItemConstructionIsDisabled(
         paintingControl == WebContentLayerClient::DisplayListConstructionDisabled);
     paintController.setSubsequenceCachingIsDisabled(
@@ -107,7 +107,7 @@
 
 size_t ContentLayerDelegate::approximateUnsharedMemoryUsage() const
 {
-    return m_graphicsLayer->paintController().approximateUnsharedMemoryUsage();
+    return m_graphicsLayer->getPaintController().approximateUnsharedMemoryUsage();
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
index c5ccd4ba..55a6b12e 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -378,7 +378,7 @@
     if (contextDisabled())
         return;
 
-    drawFocusRingPath(focusRingPath.skPath(), color, width);
+    drawFocusRingPath(focusRingPath.getSkPath(), color, width);
 }
 
 void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
@@ -457,7 +457,7 @@
     Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
 
     FloatRect outerRect = areaCastingShadowInHole(rect.rect(), shadowBlur, shadowSpread, shadowOffset);
-    FloatRoundedRect roundedHole(holeRect, rect.radii());
+    FloatRoundedRect roundedHole(holeRect, rect.getRadii());
 
     GraphicsContextStateSaver stateSaver(*this);
     if (rect.isRounded()) {
@@ -707,7 +707,7 @@
     if (fillcolorNotTransparent)
         drawRect(skRect, immutableState()->fillPaint());
 
-    if (immutableState()->strokeData().style() != NoStroke
+    if (immutableState()->getStrokeData().style() != NoStroke
         && immutableState()->strokeColor().alpha()) {
         // Stroke a width: 1 inset border
         SkPaint paint(immutableState()->fillPaint());
@@ -901,7 +901,7 @@
     if (contextDisabled() || pathToFill.isEmpty())
         return;
 
-    drawPath(pathToFill.skPath(), immutableState()->fillPaint());
+    drawPath(pathToFill.getSkPath(), immutableState()->fillPaint());
 }
 
 void GraphicsContext::fillRect(const FloatRect& rect)
@@ -959,8 +959,8 @@
 
     // and
     //   2) the inner radii are not constrained
-    const FloatRoundedRect::Radii& oRadii = outer.radii();
-    const FloatRoundedRect::Radii& iRadii = inner.radii();
+    const FloatRoundedRect::Radii& oRadii = outer.getRadii();
+    const FloatRoundedRect::Radii& iRadii = inner.getRadii();
     if (!WebCoreFloatNearlyEqual(oRadii.topLeft().width() - strokeSize.width(), iRadii.topLeft().width())
         || !WebCoreFloatNearlyEqual(oRadii.topLeft().height() - strokeSize.height(), iRadii.topLeft().height())
         || !WebCoreFloatNearlyEqual(oRadii.topRight().width() - strokeSize.width(), iRadii.topRight().width())
@@ -1029,7 +1029,7 @@
     if (contextDisabled() || pathToStroke.isEmpty())
         return;
 
-    drawPath(pathToStroke.skPath(), immutableState()->strokePaint());
+    drawPath(pathToStroke.getSkPath(), immutableState()->strokePaint());
 }
 
 void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
@@ -1040,7 +1040,7 @@
     SkPaint paint(immutableState()->strokePaint());
     paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth));
     // Reset the dash effect to account for the width
-    immutableState()->strokeData().setupPaintDashPathEffect(&paint, 0);
+    immutableState()->getStrokeData().setupPaintDashPathEffect(&paint, 0);
     // strokerect has special rules for CSS when the rect is degenerate:
     // if width==0 && height==0, do nothing
     // if width==0 || height==0, then just draw line for the other dimension
@@ -1087,7 +1087,7 @@
         return;
 
     // Use const_cast and temporarily toggle the inverse fill type instead of copying the path.
-    SkPath& path = const_cast<SkPath&>(pathToClip.skPath());
+    SkPath& path = const_cast<SkPath&>(pathToClip.getSkPath());
     path.toggleInverseFillType();
     clipPath(path, AntiAliased);
     path.toggleInverseFillType();
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
index c819176..713e9ee 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
@@ -77,7 +77,7 @@
     SkCanvas* canvas() { return m_canvas; }
     const SkCanvas* canvas() const { return m_canvas; }
 
-    PaintController& paintController() { return m_paintController; }
+    PaintController& getPaintController() { return m_paintController; }
 
     bool contextDisabled() const { return m_disabledState; }
 
@@ -89,10 +89,10 @@
     unsigned saveCount() const;
 #endif
 
-    float strokeThickness() const { return immutableState()->strokeData().thickness(); }
+    float strokeThickness() const { return immutableState()->getStrokeData().thickness(); }
     void setStrokeThickness(float thickness) { mutableState()->setStrokeThickness(thickness); }
 
-    StrokeStyle getStrokeStyle() const { return immutableState()->strokeData().style(); }
+    StrokeStyle getStrokeStyle() const { return immutableState()->getStrokeData().style(); }
     void setStrokeStyle(StrokeStyle style) { mutableState()->setStrokeStyle(style); }
 
     Color strokeColor() const { return immutableState()->strokeColor(); }
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContextState.h b/third_party/WebKit/Source/platform/graphics/GraphicsContextState.h
index d4c9418..ec2ce9e2 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContextState.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContextState.h
@@ -75,7 +75,7 @@
     Gradient* strokeGradient() const { return m_strokeGradient.get(); }
     void setStrokeGradient(const PassRefPtr<Gradient>, float);
 
-    const StrokeData& strokeData() const { return m_strokeData; }
+    const StrokeData& getStrokeData() const { return m_strokeData; }
     void setStrokeStyle(StrokeStyle);
     void setStrokeThickness(float);
     void setLineCap(LineCap);
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
index d4471a7..46da10f 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
@@ -135,7 +135,7 @@
     SkPaint paint;
     paint.setColor(alpha.rgb());
     paint.setXfermodeMode(SkXfermode::kSrcOut_Mode);
-    context.drawPath(path.skPath(), paint);
+    context.drawPath(path.getSkPath(), paint);
 
     picture = context.endRecording();
     canvas.drawPicture(picture.get());
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index 45b6fac..193492b 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -314,7 +314,7 @@
 void GraphicsLayer::paint(const IntRect* interestRect, GraphicsContext::DisabledMode disabledMode)
 {
     if (paintWithoutCommit(interestRect, disabledMode))
-        paintController().commitNewDisplayItems(offsetFromLayoutObjectWithSubpixelAccumulation());
+        getPaintController().commitNewDisplayItems(offsetFromLayoutObjectWithSubpixelAccumulation());
 }
 
 bool GraphicsLayer::paintWithoutCommit(const IntRect* interestRect, GraphicsContext::DisabledMode disabledMode)
@@ -333,15 +333,15 @@
         interestRect = &newInterestRect;
     }
 
-    if (!paintController().subsequenceCachingIsDisabled()
+    if (!getPaintController().subsequenceCachingIsDisabled()
         && !m_client->needsRepaint()
-        && !paintController().cacheIsEmpty()
+        && !getPaintController().cacheIsEmpty()
         && m_previousInterestRect == *interestRect) {
-        ASSERT(!paintController().hasInvalidations());
+        ASSERT(!getPaintController().hasInvalidations());
         return false;
     }
 
-    GraphicsContext context(paintController(), disabledMode);
+    GraphicsContext context(getPaintController(), disabledMode);
 
 #ifndef NDEBUG
     if (contentsOpaque() && s_drawDebugRedFill) {
@@ -1054,7 +1054,7 @@
     for (size_t i = 0; i < m_linkHighlights.size(); ++i)
         m_linkHighlights[i]->invalidate();
 
-    paintController().invalidateAll();
+    getPaintController().invalidateAll();
     if (isTrackingPaintInvalidations())
         trackPaintInvalidationObject("##ALL##");
 }
@@ -1078,7 +1078,7 @@
     if (!drawsContent())
         return;
 
-    paintController().invalidate(displayItemClient);
+    getPaintController().invalidate(displayItemClient);
     if (isTrackingPaintInvalidations())
         trackPaintInvalidationObject(displayItemClient.debugName());
 }
@@ -1203,7 +1203,7 @@
     return std::move(tracedValue);
 }
 
-PaintController& GraphicsLayer::paintController()
+PaintController& GraphicsLayer::getPaintController()
 {
     RELEASE_ASSERT(drawsContent());
     if (!m_paintController)
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
index 88e1335d..489d010 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -219,10 +219,10 @@
     void removeLinkHighlight(LinkHighlight*);
     // Exposed for tests
     unsigned numLinkHighlights() { return m_linkHighlights.size(); }
-    LinkHighlight* linkHighlight(int i) { return m_linkHighlights[i]; }
+    LinkHighlight* getLinkHighlight(int i) { return m_linkHighlights[i]; }
 
     void setScrollableArea(ScrollableArea*, bool isViewport);
-    ScrollableArea* scrollableArea() const { return m_scrollableArea; }
+    ScrollableArea* getScrollableArea() const { return m_scrollableArea; }
 
     WebContentLayer* contentLayer() const { return m_layer.get(); }
 
@@ -238,7 +238,7 @@
     // cc::LayerClient implementation.
     scoped_ptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo(cc::Layer*) override;
 
-    PaintController& paintController();
+    PaintController& getPaintController();
 
     // Exposed for tests.
     WebLayer* contentsLayer() const { return m_contentsLayer; }
diff --git a/third_party/WebKit/Source/platform/graphics/Image.h b/third_party/WebKit/Source/platform/graphics/Image.h
index 4d31e1d..0f89990 100644
--- a/third_party/WebKit/Source/platform/graphics/Image.h
+++ b/third_party/WebKit/Source/platform/graphics/Image.h
@@ -129,7 +129,7 @@
     virtual void advanceAnimationForTesting() { }
 
     // Typically the ImageResource that owns us.
-    ImageObserver* imageObserver() const { return m_imageObserver; }
+    ImageObserver* getImageObserver() const { return m_imageObserver; }
     void setImageObserver(ImageObserver* observer) { m_imageObserver = observer; }
 
     enum TileRule { StretchTile, RoundTile, SpaceTile, RepeatTile };
diff --git a/third_party/WebKit/Source/platform/graphics/Path.cpp b/third_party/WebKit/Source/platform/graphics/Path.cpp
index 7f36cbc..2fd75f8 100644
--- a/third_party/WebKit/Source/platform/graphics/Path.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Path.cpp
@@ -242,8 +242,8 @@
 }
 
 Path::PositionCalculator::PositionCalculator(const Path& path)
-    : m_path(path.skPath())
-    , m_pathMeasure(path.skPath(), false)
+    : m_path(path.getSkPath())
+    , m_pathMeasure(path.getSkPath(), false)
     , m_accumulatedLength(0)
 {
 }
@@ -433,7 +433,7 @@
 
 void Path::addRoundedRect(const FloatRoundedRect& r)
 {
-    addRoundedRect(r.rect(), r.radii().topLeft(), r.radii().topRight(), r.radii().bottomLeft(), r.radii().bottomRight());
+    addRoundedRect(r.rect(), r.getRadii().topLeft(), r.getRadii().topRight(), r.getRadii().bottomLeft(), r.getRadii().bottomRight());
 }
 
 void Path::addRoundedRect(const FloatRect& rect, const FloatSize& roundingRadii)
@@ -495,7 +495,7 @@
 
 void Path::addPath(const Path& src, const AffineTransform& transform)
 {
-    m_path.addPath(src.skPath(), affineTransformToSkMatrix(transform));
+    m_path.addPath(src.getSkPath(), affineTransformToSkMatrix(transform));
 }
 
 void Path::translate(const FloatSize& size)
diff --git a/third_party/WebKit/Source/platform/graphics/Path.h b/third_party/WebKit/Source/platform/graphics/Path.h
index 681fa9b65..5497706 100644
--- a/third_party/WebKit/Source/platform/graphics/Path.h
+++ b/third_party/WebKit/Source/platform/graphics/Path.h
@@ -140,7 +140,7 @@
 
     void translate(const FloatSize&);
 
-    const SkPath& skPath() const { return m_path; }
+    const SkPath& getSkPath() const { return m_path; }
 
     void apply(void* info, PathApplierFunction) const;
     void transform(const AffineTransform&);
diff --git a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp
index 2e73786..8094837 100644
--- a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp
@@ -55,7 +55,7 @@
     canvas->drawImageRect(m_image.get(), srcSkRect, dstRect, &paint,
         WebCoreClampingModeToSkiaRectConstraint(clampMode));
 
-    if (ImageObserver* observer = imageObserver())
+    if (ImageObserver* observer = getImageObserver())
         observer->didDraw(this);
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
index 67b1e5f8..290818d 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -100,7 +100,7 @@
     // TODO(jbroman, wkorman): What visual rectangle is wanted here?
     list->CreateAndAppendItem<cc::TransformDisplayItem>(gfx::Rect(), translation);
 
-    const DisplayItemList& displayItems = artifact.displayItemList();
+    const DisplayItemList& displayItems = artifact.getDisplayItemList();
     for (const auto& displayItem : displayItems.itemsInPaintChunk(chunk))
         appendDisplayItemToCcDisplayItemList(displayItem, list.get());
 
@@ -177,11 +177,13 @@
     // necessarily true, and this should be fixed.
     gfx::Transform transform = transformToTransformSpace(localTransformSpace(node), localTransformSpace(node->parent()));
     gfx::Vector2dF offset = clipRect.OffsetFromOrigin();
+    transform.Translate(offset.x(), offset.y());
     if (node->parent()) {
         FloatPoint offsetDueToParentClipOffset = node->parent()->clipRect().rect().location();
-        offset -= gfx::Vector2dF(offsetDueToParentClipOffset.x(), offsetDueToParentClipOffset.y());
+        gfx::Transform undoClipOffset;
+        undoClipOffset.Translate(-offsetDueToParentClipOffset.x(), -offsetDueToParentClipOffset.y());
+        transform.PreconcatTransform(undoClipOffset);
     }
-    transform.Translate(offset.x(), offset.y());
 
     scoped_refptr<cc::Layer> layer = cc::Layer::Create(cc::LayerSettings());
     layer->SetIsDrawable(false);
@@ -243,7 +245,7 @@
     if (paintChunk.size() != 1)
         return nullptr;
 
-    const auto& displayItem = paintArtifact.displayItemList()[paintChunk.beginIndex];
+    const auto& displayItem = paintArtifact.getDisplayItemList()[paintChunk.beginIndex];
     if (!displayItem.isForeignLayer())
         return nullptr;
 
@@ -293,14 +295,17 @@
     // this layer's transform space (whereas layer position applies in its
     // parent's transform space).
     gfx::Vector2dF offset = gfx::PointF(combinedBounds.origin()).OffsetFromOrigin();
-    if (const auto* clip = paintChunk.properties.clip.get()) {
-        // If a clip was applied, its origin needs to be cancelled out in
-        // this transform.
-        FloatPoint offsetDueToClipOffset = clip->clipRect().rect().location();
-        offset -= gfx::Vector2dF(offsetDueToClipOffset.x(), offsetDueToClipOffset.y());
-    }
     transform.Translate(offset.x(), offset.y());
 
+    // If a clip was applied, its origin needs to be cancelled out in
+    // this transform.
+    if (const auto* clip = paintChunk.properties.clip.get()) {
+        FloatPoint offsetDueToClipOffset = clip->clipRect().rect().location();
+        gfx::Transform undoClipOffset;
+        undoClipOffset.Translate(-offsetDueToClipOffset.x(), -offsetDueToClipOffset.y());
+        transform.PreconcatTransform(undoClipOffset);
+    }
+
     scoped_refptr<cc::PictureLayer> layer = cc::PictureLayer::Create(cc::LayerSettings(), contentLayerClient.get());
     layer->SetBounds(combinedBounds.size());
     layer->SetTransform(transform);
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
index 78727854..12968c67 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
@@ -47,7 +47,7 @@
 
     // Wraps rootLayer(), so that it can be attached as a child of another
     // WebLayer.
-    WebLayer* webLayer() const { return m_webLayer.get(); }
+    WebLayer* getWebLayer() const { return m_webLayer.get(); }
 
 private:
     class ContentLayerClientImpl;
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
index 0ca76e96..0a0e033 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -40,7 +40,7 @@
         m_featuresBackup.restore();
     }
 
-    PaintArtifactCompositor& paintArtifactCompositor() { return *m_paintArtifactCompositor; }
+    PaintArtifactCompositor& getPaintArtifactCompositor() { return *m_paintArtifactCompositor; }
     cc::Layer* rootLayer() { return m_paintArtifactCompositor->rootLayer(); }
     void update(const PaintArtifact& artifact) { m_paintArtifactCompositor->update(artifact); }
 
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FEDisplacementMap.cpp b/third_party/WebKit/Source/platform/graphics/filters/FEDisplacementMap.cpp
index 616fe64..900e2b3 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FEDisplacementMap.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FEDisplacementMap.cpp
@@ -48,8 +48,8 @@
 FloatRect FEDisplacementMap::mapPaintRect(const FloatRect& rect, bool)
 {
     FloatRect result = rect;
-    result.inflateX(filter()->applyHorizontalScale(m_scale / 2));
-    result.inflateY(filter()->applyVerticalScale(m_scale / 2));
+    result.inflateX(getFilter()->applyHorizontalScale(m_scale / 2));
+    result.inflateY(getFilter()->applyVerticalScale(m_scale / 2));
     return result;
 }
 
@@ -118,7 +118,7 @@
     SkImageFilter::CropRect cropRect = getCropRect();
     // FIXME : Only applyHorizontalScale is used and applyVerticalScale is ignored
     // This can be fixed by adding a 2nd scale parameter to SkDisplacementMapEffect
-    return adoptRef(SkDisplacementMapEffect::Create(typeX, typeY, SkFloatToScalar(filter()->applyHorizontalScale(m_scale)), displ.get(), color.get(), &cropRect));
+    return adoptRef(SkDisplacementMapEffect::Create(typeX, typeY, SkFloatToScalar(getFilter()->applyHorizontalScale(m_scale)), displ.get(), color.get(), &cropRect));
 }
 
 static TextStream& operator<<(TextStream& ts, const ChannelSelectorType& type)
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FEDropShadow.cpp b/third_party/WebKit/Source/platform/graphics/filters/FEDropShadow.cpp
index 75ddeb7..366e457 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FEDropShadow.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FEDropShadow.cpp
@@ -47,7 +47,7 @@
 FloatRect FEDropShadow::mapRect(const FloatRect& rect, bool forward)
 {
     FloatRect result = rect;
-    Filter* filter = this->filter();
+    Filter* filter = this->getFilter();
     ASSERT(filter);
 
     FloatRect offsetRect = rect;
@@ -68,10 +68,10 @@
 PassRefPtr<SkImageFilter> FEDropShadow::createImageFilter(SkiaImageFilterBuilder& builder)
 {
     RefPtr<SkImageFilter> input(builder.build(inputEffect(0), operatingColorSpace()));
-    float dx = filter()->applyHorizontalScale(m_dx);
-    float dy = filter()->applyVerticalScale(m_dy);
-    float stdX = filter()->applyHorizontalScale(m_stdX);
-    float stdY = filter()->applyVerticalScale(m_stdY);
+    float dx = getFilter()->applyHorizontalScale(m_dx);
+    float dy = getFilter()->applyVerticalScale(m_dy);
+    float stdX = getFilter()->applyHorizontalScale(m_stdX);
+    float stdY = getFilter()->applyVerticalScale(m_stdY);
     Color color = adaptColorToOperatingColorSpace(m_shadowColor.combineWithAlpha(m_shadowOpacity));
     SkImageFilter::CropRect cropRect = getCropRect();
     return adoptRef(SkDropShadowImageFilter::Create(SkFloatToScalar(dx), SkFloatToScalar(dy), SkFloatToScalar(stdX), SkFloatToScalar(stdY), color.rgb(), SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, input.get(), &cropRect));
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FEGaussianBlur.cpp b/third_party/WebKit/Source/platform/graphics/filters/FEGaussianBlur.cpp
index 9a6ad05..fd0a3a1 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FEGaussianBlur.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FEGaussianBlur.cpp
@@ -80,7 +80,7 @@
 FloatRect FEGaussianBlur::mapRect(const FloatRect& rect, bool)
 {
     FloatRect result = rect;
-    IntSize kernelSize = calculateKernelSize(filter(), FloatPoint(m_stdX, m_stdY));
+    IntSize kernelSize = calculateKernelSize(getFilter(), FloatPoint(m_stdX, m_stdY));
 
     // We take the half kernel size and multiply it with three, because we run box blur three times.
     result.inflateX(3 * kernelSize.width() * 0.5f);
@@ -111,8 +111,8 @@
 PassRefPtr<SkImageFilter> FEGaussianBlur::createImageFilter(SkiaImageFilterBuilder& builder)
 {
     RefPtr<SkImageFilter> input(builder.build(inputEffect(0), operatingColorSpace()));
-    float stdX = filter()->applyHorizontalScale(m_stdX);
-    float stdY = filter()->applyVerticalScale(m_stdY);
+    float stdX = getFilter()->applyHorizontalScale(m_stdX);
+    float stdY = getFilter()->applyVerticalScale(m_stdY);
     SkImageFilter::CropRect rect = getCropRect();
     return adoptRef(SkBlurImageFilter::Create(SkFloatToScalar(stdX), SkFloatToScalar(stdY), input.get(), &rect));
 }
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FEMorphology.cpp b/third_party/WebKit/Source/platform/graphics/filters/FEMorphology.cpp
index bd0dec6..d10cbe7 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FEMorphology.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FEMorphology.cpp
@@ -88,16 +88,16 @@
 FloatRect FEMorphology::mapRect(const FloatRect& rect, bool)
 {
     FloatRect result = rect;
-    result.inflateX(filter()->applyHorizontalScale(m_radiusX));
-    result.inflateY(filter()->applyVerticalScale(m_radiusY));
+    result.inflateX(getFilter()->applyHorizontalScale(m_radiusX));
+    result.inflateY(getFilter()->applyVerticalScale(m_radiusY));
     return result;
 }
 
 PassRefPtr<SkImageFilter> FEMorphology::createImageFilter(SkiaImageFilterBuilder& builder)
 {
     RefPtr<SkImageFilter> input(builder.build(inputEffect(0), operatingColorSpace()));
-    SkScalar radiusX = SkFloatToScalar(filter()->applyHorizontalScale(m_radiusX));
-    SkScalar radiusY = SkFloatToScalar(filter()->applyVerticalScale(m_radiusY));
+    SkScalar radiusX = SkFloatToScalar(getFilter()->applyHorizontalScale(m_radiusX));
+    SkScalar radiusY = SkFloatToScalar(getFilter()->applyVerticalScale(m_radiusY));
     SkImageFilter::CropRect rect = getCropRect();
     if (m_type == FEMORPHOLOGY_OPERATOR_DILATE)
         return adoptRef(SkDilateImageFilter::Create(radiusX, radiusY, input.get(), &rect));
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FEOffset.cpp b/third_party/WebKit/Source/platform/graphics/filters/FEOffset.cpp
index fa8cc091..b43da65 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FEOffset.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FEOffset.cpp
@@ -67,16 +67,16 @@
 {
     FloatRect result = rect;
     if (forward)
-        result.move(filter()->applyHorizontalScale(m_dx), filter()->applyVerticalScale(m_dy));
+        result.move(getFilter()->applyHorizontalScale(m_dx), getFilter()->applyVerticalScale(m_dy));
     else
-        result.move(-filter()->applyHorizontalScale(m_dx), -filter()->applyVerticalScale(m_dy));
+        result.move(-getFilter()->applyHorizontalScale(m_dx), -getFilter()->applyVerticalScale(m_dy));
     return result;
 }
 
 PassRefPtr<SkImageFilter> FEOffset::createImageFilter(SkiaImageFilterBuilder& builder)
 {
     RefPtr<SkImageFilter> input(builder.build(inputEffect(0), operatingColorSpace()));
-    Filter* filter = this->filter();
+    Filter* filter = this->getFilter();
     SkImageFilter::CropRect cropRect = getCropRect();
     return adoptRef(SkOffsetImageFilter::Create(SkFloatToScalar(filter->applyHorizontalScale(m_dx)), SkFloatToScalar(filter->applyVerticalScale(m_dy)), input.get(), &cropRect));
 }
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp b/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp
index f42ffe9..8981017 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FETile.cpp
@@ -47,7 +47,7 @@
 {
     RefPtr<SkImageFilter> input(builder.build(inputEffect(0), operatingColorSpace()));
     FloatRect srcRect = inputEffect(0)->filterPrimitiveSubregion();
-    FloatRect dstRect = applyEffectBoundaries(filter()->filterRegion());
+    FloatRect dstRect = applyEffectBoundaries(getFilter()->filterRegion());
     return adoptRef(SkTileImageFilter::Create(srcRect, dstRect, input.get()));
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FETurbulence.cpp b/third_party/WebKit/Source/platform/graphics/filters/FETurbulence.cpp
index 091c340d..4f0de74 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FETurbulence.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FETurbulence.cpp
@@ -135,8 +135,8 @@
     // and not the target bounding box scale (as SVGFilter::apply*Scale()
     // would do). Note also that we divide by the scale since this is
     // a frequency, not a period.
-    float baseFrequencyX = m_baseFrequencyX / filter()->scale();
-    float baseFrequencyY = m_baseFrequencyY / filter()->scale();
+    float baseFrequencyX = m_baseFrequencyX / getFilter()->scale();
+    float baseFrequencyY = m_baseFrequencyY / getFilter()->scale();
     return (type() == FETURBULENCE_TYPE_FRACTALNOISE) ?
         SkPerlinNoiseShader::CreateFractalNoise(SkFloatToScalar(baseFrequencyX),
             SkFloatToScalar(baseFrequencyY), numOctaves(), SkFloatToScalar(seed()),
diff --git a/third_party/WebKit/Source/platform/graphics/filters/Filter.h b/third_party/WebKit/Source/platform/graphics/filters/Filter.h
index a009dd2..530b070 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/Filter.h
+++ b/third_party/WebKit/Source/platform/graphics/filters/Filter.h
@@ -65,7 +65,7 @@
     void setLastEffect(PassRefPtrWillBeRawPtr<FilterEffect>);
     FilterEffect* lastEffect() const { return m_lastEffect.get(); }
 
-    SourceGraphic* sourceGraphic() const { return m_sourceGraphic.get(); }
+    SourceGraphic* getSourceGraphic() const { return m_sourceGraphic.get(); }
 
 private:
     Filter(const FloatRect& referenceBox, const FloatRect& filterRegion, float scale, UnitScaling);
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.cpp b/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.cpp
index 344dd0c..ef5e9ab8 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.cpp
@@ -150,7 +150,7 @@
 
 FloatRect FilterEffect::determineFilterPrimitiveSubregion(DetermineSubregionFlags flags)
 {
-    Filter* filter = this->filter();
+    Filter* filter = this->getFilter();
     ASSERT(filter);
 
     // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect.
@@ -219,14 +219,14 @@
 {
     FloatRect rect;
     uint32_t flags = 0;
-    if (!hasConnectedInput() && !filter()->filterRegion().isEmpty()) {
-        rect = filter()->filterRegion();
+    if (!hasConnectedInput() && !getFilter()->filterRegion().isEmpty()) {
+        rect = getFilter()->filterRegion();
         flags = SkImageFilter::CropRect::kHasAll_CropEdge;
     }
 
     rect = applyEffectBoundaries(rect);
 
-    rect.scale(filter()->scale());
+    rect.scale(getFilter()->scale());
 
     flags |= hasX() ? SkImageFilter::CropRect::kHasLeft_CropEdge : 0;
     flags |= hasY() ? SkImageFilter::CropRect::kHasTop_CropEdge : 0;
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.h b/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.h
index 568c25f..087d0ec 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.h
+++ b/third_party/WebKit/Source/platform/graphics/filters/FilterEffect.h
@@ -128,8 +128,8 @@
     void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
     FloatRect applyEffectBoundaries(const FloatRect&) const;
 
-    Filter* filter() { return m_filter; }
-    const Filter* filter() const { return m_filter; }
+    Filter* getFilter() { return m_filter; }
+    const Filter* getFilter() const { return m_filter; }
 
     bool clipsToBounds() const { return m_clipsToBounds; }
     void setClipsToBounds(bool value) { m_clipsToBounds = value; }
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FilterOperation.h b/third_party/WebKit/Source/platform/graphics/filters/FilterOperation.h
index 79a83d1..f7a2668 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FilterOperation.h
+++ b/third_party/WebKit/Source/platform/graphics/filters/FilterOperation.h
@@ -125,7 +125,7 @@
     const String& url() const { return m_url; }
     const AtomicString& fragment() const { return m_fragment; }
 
-    Filter* filter() const { return m_filter.get(); }
+    Filter* getFilter() const { return m_filter.get(); }
     void setFilter(PassRefPtrWillBeRawPtr<Filter> filter) { m_filter = filter; }
 
     DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FilterOperations.cpp b/third_party/WebKit/Source/platform/graphics/filters/FilterOperations.cpp
index b584588..e1db93e 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FilterOperations.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FilterOperations.cpp
@@ -139,9 +139,9 @@
         }
         case FilterOperation::REFERENCE: {
             ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
-            if (referenceOperation->filter() && referenceOperation->filter()->lastEffect()) {
+            if (referenceOperation->getFilter() && referenceOperation->getFilter()->lastEffect()) {
                 FloatRect outsetRect(0, 0, 1, 1);
-                outsetRect = referenceOperation->filter()->lastEffect()->mapRectRecursive(outsetRect);
+                outsetRect = referenceOperation->getFilter()->lastEffect()->mapRectRecursive(outsetRect);
                 FilterOutsets outsets(
                     std::max(0.0f, -outsetRect.y()),
                     std::max(0.0f, outsetRect.x() + outsetRect.width() - 1),
diff --git a/third_party/WebKit/Source/platform/graphics/filters/ImageFilterBuilderTest.cpp b/third_party/WebKit/Source/platform/graphics/filters/ImageFilterBuilderTest.cpp
index c8c5ee5c..aff86a9 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/ImageFilterBuilderTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/ImageFilterBuilderTest.cpp
@@ -43,7 +43,7 @@
         RefPtrWillBeRawPtr<Filter> referenceFilter = Filter::create(1.0f);
 
         // Add a dummy source graphic input
-        RefPtrWillBeRawPtr<FilterEffect> sourceEffect = referenceFilter->sourceGraphic();
+        RefPtrWillBeRawPtr<FilterEffect> sourceEffect = referenceFilter->getSourceGraphic();
         sourceEffect->setOperatingColorSpace(ColorSpaceDeviceRGB);
 
         // Add a blur effect (with input : source)
diff --git a/third_party/WebKit/Source/platform/graphics/filters/SkiaImageFilterBuilder.cpp b/third_party/WebKit/Source/platform/graphics/filters/SkiaImageFilterBuilder.cpp
index 55cddf7..4724206 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/SkiaImageFilterBuilder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/SkiaImageFilterBuilder.cpp
@@ -80,7 +80,7 @@
         switch (op.type()) {
         case FilterOperation::REFERENCE: {
             RefPtr<SkImageFilter> filter;
-            Filter* referenceFilter = toReferenceFilterOperation(op).filter();
+            Filter* referenceFilter = toReferenceFilterOperation(op).getFilter();
             if (referenceFilter && referenceFilter->lastEffect()) {
                 FilterEffect* filterEffect = referenceFilter->lastEffect();
                 // Prepopulate SourceGraphic with two image filters: one with a null image
@@ -91,7 +91,7 @@
                 // these for the PM-validated options.
                 RefPtr<SkImageFilter> deviceFilter = transformColorSpace(nullFilter, currentColorSpace, ColorSpaceDeviceRGB);
                 RefPtr<SkImageFilter> linearFilter = transformColorSpace(nullFilter, currentColorSpace, ColorSpaceLinearRGB);
-                FilterEffect* sourceGraphic = referenceFilter->sourceGraphic();
+                FilterEffect* sourceGraphic = referenceFilter->getSourceGraphic();
                 sourceGraphic->setImageFilter(ColorSpaceDeviceRGB, false, deviceFilter.get());
                 sourceGraphic->setImageFilter(ColorSpaceLinearRGB, false, linearFilter.get());
                 sourceGraphic->setImageFilter(ColorSpaceDeviceRGB, true, deviceFilter.get());
diff --git a/third_party/WebKit/Source/platform/graphics/filters/SourceAlpha.cpp b/third_party/WebKit/Source/platform/graphics/filters/SourceAlpha.cpp
index a8b5617..0f99b21 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/SourceAlpha.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/SourceAlpha.cpp
@@ -35,7 +35,7 @@
 }
 
 SourceAlpha::SourceAlpha(FilterEffect* sourceEffect)
-    : FilterEffect(sourceEffect->filter())
+    : FilterEffect(sourceEffect->getFilter())
 {
     setOperatingColorSpace(sourceEffect->operatingColorSpace());
     inputEffects().append(sourceEffect);
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp b/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
index 96a3c83c..e9eee50 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp
@@ -2306,7 +2306,7 @@
 
     if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, width, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
         return false;
-    if (ImageObserver *observer = image->imageObserver())
+    if (ImageObserver *observer = image->getImageObserver())
         observer->didDraw(image);
     return true;
 }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipDisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/ClipDisplayItem.cpp
index e4563be..70dfdab0 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/ClipDisplayItem.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/ClipDisplayItem.cpp
@@ -26,7 +26,7 @@
 {
     WebVector<SkRRect> webRoundedRects(m_roundedRectClips.size());
     for (size_t i = 0; i < m_roundedRectClips.size(); ++i) {
-        FloatRoundedRect::Radii rectRadii = m_roundedRectClips[i].radii();
+        FloatRoundedRect::Radii rectRadii = m_roundedRectClips[i].getRadii();
         SkVector skRadii[4];
         skRadii[SkRRect::kUpperLeft_Corner].set(SkIntToScalar(rectRadii.topLeft().width()),
             SkIntToScalar(rectRadii.topLeft().height()));
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h
index 3455898..ce6f728 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPathDisplayItem.h
@@ -17,7 +17,7 @@
 public:
     BeginClipPathDisplayItem(const DisplayItemClient& client, const Path& clipPath)
         : PairedBeginDisplayItem(client, BeginClipPath, sizeof(*this))
-        , m_clipPath(clipPath.skPath()) { }
+        , m_clipPath(clipPath.getSkPath()) { }
 
     void replay(GraphicsContext&) const override;
     void appendToWebDisplayItemList(const IntRect&, WebDisplayItemList*) const override;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp
index 7d91ca5..ce476ef7 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/ClipPathRecorder.cpp
@@ -14,12 +14,12 @@
     : m_context(context)
     , m_client(client)
 {
-    m_context.paintController().createAndAppend<BeginClipPathDisplayItem>(m_client, clipPath);
+    m_context.getPaintController().createAndAppend<BeginClipPathDisplayItem>(m_client, clipPath);
 }
 
 ClipPathRecorder::~ClipPathRecorder()
 {
-    m_context.paintController().endItem<EndClipPathDisplayItem>(m_client);
+    m_context.getPaintController().endItem<EndClipPathDisplayItem>(m_client);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp
index 83d52e3..c7a66059 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/ClipRecorder.cpp
@@ -15,12 +15,12 @@
     , m_context(context)
     , m_type(type)
 {
-    m_context.paintController().createAndAppend<ClipDisplayItem>(m_client, type, pixelSnappedIntRect(clipRect));
+    m_context.getPaintController().createAndAppend<ClipDisplayItem>(m_client, type, pixelSnappedIntRect(clipRect));
 }
 
 ClipRecorder::~ClipRecorder()
 {
-    m_context.paintController().endItem<EndClipDisplayItem>(m_client, DisplayItem::clipTypeToEndClipType(m_type));
+    m_context.getPaintController().endItem<EndClipDisplayItem>(m_client, DisplayItem::clipTypeToEndClipType(m_type));
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp
index b2dceae..15fb79b 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/CompositingRecorder.cpp
@@ -25,12 +25,12 @@
 
 void CompositingRecorder::beginCompositing(GraphicsContext& graphicsContext, const DisplayItemClient& client, const SkXfermode::Mode xferMode, const float opacity, const FloatRect* bounds, ColorFilter colorFilter)
 {
-    graphicsContext.paintController().createAndAppend<BeginCompositingDisplayItem>(client, xferMode, opacity, bounds, colorFilter);
+    graphicsContext.getPaintController().createAndAppend<BeginCompositingDisplayItem>(client, xferMode, opacity, bounds, colorFilter);
 }
 
 void CompositingRecorder::endCompositing(GraphicsContext& graphicsContext, const DisplayItemClient& client)
 {
-    graphicsContext.paintController().endItem<EndCompositingDisplayItem>(client);
+    graphicsContext.getPaintController().endItem<EndCompositingDisplayItem>(client);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemCacheSkipper.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemCacheSkipper.h
index 61b99ed8..246147de 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemCacheSkipper.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemCacheSkipper.h
@@ -19,11 +19,11 @@
     DisplayItemCacheSkipper(GraphicsContext& context)
         : m_context(context)
     {
-        context.paintController().beginSkippingCache();
+        context.getPaintController().beginSkippingCache();
     }
     ~DisplayItemCacheSkipper()
     {
-        m_context.paintController().endSkippingCache();
+        m_context.getPaintController().endSkippingCache();
     }
 
 private:
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp
index 2d1c9ba2..202a06ec 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DrawingRecorder.cpp
@@ -17,10 +17,10 @@
 {
     ASSERT(DisplayItem::isDrawingType(type));
 
-    if (!context.paintController().clientCacheIsValid(client))
+    if (!context.getPaintController().clientCacheIsValid(client))
         return false;
 
-    context.paintController().createAndAppend<CachedDisplayItem>(client, DisplayItem::drawingTypeToCachedDrawingType(type));
+    context.getPaintController().createAndAppend<CachedDisplayItem>(client, DisplayItem::drawingTypeToCachedDrawingType(type));
 
 #if ENABLE(ASSERT)
     // When under-invalidation checking is enabled, we output CachedDrawing display item
@@ -38,15 +38,15 @@
     , m_displayItemType(displayItemType)
     , m_knownToBeOpaque(false)
 #if ENABLE(ASSERT)
-    , m_displayItemPosition(m_context.paintController().newDisplayItemList().size())
+    , m_displayItemPosition(m_context.getPaintController().newDisplayItemList().size())
     , m_underInvalidationCheckingMode(DrawingDisplayItem::CheckPicture)
 #endif
 {
-    if (context.paintController().displayItemConstructionIsDisabled())
+    if (context.getPaintController().displayItemConstructionIsDisabled())
         return;
 
     // Must check DrawingRecorder::useCachedDrawingIfPossible before creating the DrawingRecorder.
-    ASSERT((RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && context.paintController().paintOffsetWasInvalidated(displayItemClient))
+    ASSERT((RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && context.getPaintController().paintOffsetWasInvalidated(displayItemClient))
         || RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()
         || !useCachedDrawingIfPossible(m_context, m_displayItemClient, m_displayItemType));
 
@@ -77,7 +77,7 @@
 
 DrawingRecorder::~DrawingRecorder()
 {
-    if (m_context.paintController().displayItemConstructionIsDisabled())
+    if (m_context.getPaintController().displayItemConstructionIsDisabled())
         return;
 
 #if ENABLE(ASSERT)
@@ -85,10 +85,10 @@
         m_context.restore();
 
     m_context.setInDrawingRecorder(false);
-    ASSERT(m_displayItemPosition == m_context.paintController().newDisplayItemList().size());
+    ASSERT(m_displayItemPosition == m_context.getPaintController().newDisplayItemList().size());
 #endif
 
-    m_context.paintController().createAndAppend<DrawingDisplayItem>(m_displayItemClient
+    m_context.getPaintController().createAndAppend<DrawingDisplayItem>(m_displayItemClient
         , m_displayItemType
         , m_context.endRecording()
         , m_knownToBeOpaque
diff --git a/third_party/WebKit/Source/platform/graphics/paint/ForeignLayerDisplayItem.cpp b/third_party/WebKit/Source/platform/graphics/paint/ForeignLayerDisplayItem.cpp
index a08876b..5a47632e 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/ForeignLayerDisplayItem.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/ForeignLayerDisplayItem.cpp
@@ -66,7 +66,7 @@
     const DisplayItemClient& client, DisplayItem::Type type,
     WebLayer* webLayer, const FloatPoint& location, const IntSize& bounds)
 {
-    PaintController& paintController = context.paintController();
+    PaintController& paintController = context.getPaintController();
     if (paintController.displayItemConstructionIsDisabled())
         return;
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifact.h b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifact.h
index 20ffee7..5edd8ff 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifact.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifact.h
@@ -43,8 +43,8 @@
 
     bool isEmpty() const { return m_displayItemList.isEmpty(); }
 
-    DisplayItemList& displayItemList() { return m_displayItemList; }
-    const DisplayItemList& displayItemList() const { return m_displayItemList; }
+    DisplayItemList& getDisplayItemList() { return m_displayItemList; }
+    const DisplayItemList& getDisplayItemList() const { return m_displayItemList; }
 
     Vector<PaintChunk>& paintChunks() { return m_paintChunks; }
     const Vector<PaintChunk>& paintChunks() const { return m_paintChunks; }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp
index a04abf5..e95d83273 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintArtifactToSkCanvas.cpp
@@ -108,7 +108,7 @@
 void paintArtifactToSkCanvas(const PaintArtifact& artifact, SkCanvas* canvas)
 {
     SkAutoCanvasRestore restore(canvas, true);
-    const DisplayItemList& displayItems = artifact.displayItemList();
+    const DisplayItemList& displayItems = artifact.getDisplayItemList();
     const EffectPaintPropertyNode* previousEffect = nullptr;
     for (const PaintChunk& chunk : artifact.paintChunks()) {
         // Setup the canvas clip state first because it clobbers matrix state.
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 1da9267..6451c65b 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -223,9 +223,9 @@
 {
     ASSERT(clientCacheIsValid(id.client));
 
-    size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndicesByClient, m_currentPaintArtifact.displayItemList());
+    size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndicesByClient, m_currentPaintArtifact.getDisplayItemList());
     if (foundIndex != kNotFound)
-        return m_currentPaintArtifact.displayItemList().begin() + foundIndex;
+        return m_currentPaintArtifact.getDisplayItemList().begin() + foundIndex;
 
     return findOutOfOrderCachedItemForward(id, context);
 }
@@ -233,7 +233,7 @@
 // Find forward for the item and index all skipped indexable items.
 DisplayItemList::iterator PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& id, OutOfOrderIndexContext& context)
 {
-    DisplayItemList::iterator currentEnd = m_currentPaintArtifact.displayItemList().end();
+    DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItemList().end();
     for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) {
         const DisplayItem& item = *context.nextItemToIndex;
         ASSERT(item.hasValidClient());
@@ -241,7 +241,7 @@
             if (id.matches(item))
                 return context.nextItemToIndex++;
 
-            addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPaintArtifact.displayItemList().begin(), context.displayItemIndicesByClient);
+            addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPaintArtifact.getDisplayItemList().begin(), context.displayItemIndicesByClient);
         }
     }
     return currentEnd;
@@ -254,9 +254,9 @@
     DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::EndSubsequence, 0);
     do {
         // We should always find the EndSubsequence display item.
-        ASSERT(currentIt != m_currentPaintArtifact.displayItemList().end());
+        ASSERT(currentIt != m_currentPaintArtifact.getDisplayItemList().end());
         ASSERT(currentIt->hasValidClient());
-        updatedList.appendByMoving(*currentIt, currentList.visualRect(currentIt - m_currentPaintArtifact.displayItemList().begin()));
+        updatedList.appendByMoving(*currentIt, currentList.visualRect(currentIt - m_currentPaintArtifact.getDisplayItemList().begin()));
         ++currentIt;
     } while (!endSubsequenceId.matches(updatedList.last()));
 }
@@ -268,7 +268,7 @@
 #endif
     commitNewDisplayItemsInternal(offsetFromLayoutObject);
 #if ENABLE(ASSERT)
-    m_currentPaintArtifact.displayItemList().assertDisplayItemClientsAreAlive();
+    m_currentPaintArtifact.getDisplayItemList().assertDisplayItemClientsAreAlive();
 #endif
 }
 
@@ -293,7 +293,7 @@
 void PaintController::commitNewDisplayItemsInternal(const LayoutSize& offsetFromLayoutObject)
 {
     TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems",
-        "current_display_list_size", (int)m_currentPaintArtifact.displayItemList().size(),
+        "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemList().size(),
         "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCachedNewItems);
     m_numCachedNewItems = 0;
 
@@ -332,13 +332,13 @@
     // by later out-of-order CachedDisplayItems in m_newDisplayItemList. This ensures that when
     // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems
     // looking for potential matches. Thus we can ensure that the algorithm runs in linear time.
-    OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.displayItemList().begin());
+    OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.getDisplayItemList().begin());
 
     // TODO(jbroman): Consider revisiting this heuristic.
-    DisplayItemList updatedList(std::max(m_currentPaintArtifact.displayItemList().usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes()));
+    DisplayItemList updatedList(std::max(m_currentPaintArtifact.getDisplayItemList().usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes()));
     Vector<PaintChunk> updatedPaintChunks;
-    DisplayItemList::iterator currentIt = m_currentPaintArtifact.displayItemList().begin();
-    DisplayItemList::iterator currentEnd = m_currentPaintArtifact.displayItemList().end();
+    DisplayItemList::iterator currentIt = m_currentPaintArtifact.getDisplayItemList().begin();
+    DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItemList().end();
     for (DisplayItemList::iterator newIt = m_newDisplayItemList.begin(); newIt != m_newDisplayItemList.end(); ++newIt) {
         const DisplayItem& newDisplayItem = *newIt;
         const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId();
@@ -371,11 +371,11 @@
             }
 #endif
             if (newDisplayItem.isCachedDrawing()) {
-                updatedList.appendByMoving(*currentIt, m_currentPaintArtifact.displayItemList().visualRect(currentIt - m_currentPaintArtifact.displayItemList().begin()));
+                updatedList.appendByMoving(*currentIt, m_currentPaintArtifact.getDisplayItemList().visualRect(currentIt - m_currentPaintArtifact.getDisplayItemList().begin()));
                 ++currentIt;
             } else {
                 ASSERT(newDisplayItem.getType() == DisplayItem::CachedSubsequence);
-                copyCachedSubsequence(m_currentPaintArtifact.displayItemList(), currentIt, updatedList);
+                copyCachedSubsequence(m_currentPaintArtifact.getDisplayItemList(), currentIt, updatedList);
                 ASSERT(updatedList.last().getType() == DisplayItem::EndSubsequence);
             }
         } else {
@@ -441,7 +441,7 @@
     m_validlyCachedClientsDirty = false;
 
     const DisplayItemClient* lastAddedClient = nullptr;
-    for (const DisplayItem& displayItem : m_currentPaintArtifact.displayItemList()) {
+    for (const DisplayItem& displayItem : m_currentPaintArtifact.getDisplayItemList()) {
         if (&displayItem.client() == lastAddedClient)
             continue;
         if (displayItem.isCacheable()) {
@@ -542,7 +542,7 @@
 {
     ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled());
 
-    for (const auto& displayItem : m_currentPaintArtifact.displayItemList()) {
+    for (const auto& displayItem : m_currentPaintArtifact.getDisplayItemList()) {
         if (!displayItem.hasValidClient() || !displayItem.isCacheable() || !clientCacheIsValid(displayItem.client()))
             continue;
         showUnderInvalidationError("", "May be under-invalidation: no new display item", nullptr, &displayItem);
@@ -572,7 +572,7 @@
 
 void PaintController::showDebugData() const
 {
-    WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugString(m_currentPaintArtifact.displayItemList()).utf8().data());
+    WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugString(m_currentPaintArtifact.getDisplayItemList()).utf8().data());
     WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m_newDisplayItemList).utf8().data());
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
index fab3dbc..b9edbba 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -118,7 +118,7 @@
 
     // Get the artifact generated after the last commit.
     const PaintArtifact& paintArtifact() const;
-    const DisplayItemList& displayItemList() const { return paintArtifact().displayItemList(); }
+    const DisplayItemList& getDisplayItemList() const { return paintArtifact().getDisplayItemList(); }
     const Vector<PaintChunk>& paintChunks() const { return paintArtifact().paintChunks(); }
 
     bool clientCacheIsValid(const DisplayItemClient&) const;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index fd24cc3..20cbb290 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -24,11 +24,11 @@
 
     IntRect visualRect(const PaintArtifact& paintArtifact, unsigned index)
     {
-        return paintArtifact.displayItemList().visualRect(index);
+        return paintArtifact.getDisplayItemList().visualRect(index);
     }
 
 protected:
-    PaintController& paintController() { return *m_paintController; }
+    PaintController& getPaintController() { return *m_paintController; }
 
 private:
     void TearDown() override
@@ -104,14 +104,14 @@
 
 TEST_F(PaintControllerTest, NestedRecorders)
 {
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     TestDisplayItemClient client("client");
 
     drawClippedRect(context, client, clipType, backgroundDrawingType, FloatRect(100, 100, 200, 200));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 3,
         TestDisplayItem(client, clipType),
         TestDisplayItem(client, backgroundDrawingType),
         TestDisplayItem(client, DisplayItem::clipTypeToEndClipType(clipType)));
@@ -121,24 +121,24 @@
 {
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 300, 300));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 200, 200));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 300, 300));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 3,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType));
 
-    paintController().invalidate(second);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 300, 300));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 300, 300));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType));
 }
@@ -148,25 +148,25 @@
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
     TestDisplayItemClient unaffected("unaffected");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, unaffected, backgroundDrawingType, FloatRect(300, 300, 10, 10));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 3,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(unaffected, backgroundDrawingType));
 
-    paintController().invalidate(second);
+    getPaintController().invalidate(second);
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, unaffected, backgroundDrawingType, FloatRect(300, 300, 10, 10));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 3,
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(unaffected, backgroundDrawingType));
@@ -177,22 +177,22 @@
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
     TestDisplayItemClient third("third");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType));
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, third, backgroundDrawingType, FloatRect(125, 100, 200, 50));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 3,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(third, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType));
@@ -203,7 +203,7 @@
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
     TestDisplayItemClient third("third");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
@@ -211,9 +211,9 @@
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, second, foregroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, third, foregroundDrawingType, FloatRect(300, 100, 50, 50));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 6,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 6,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(third, backgroundDrawingType),
@@ -221,16 +221,16 @@
         TestDisplayItem(second, foregroundDrawingType),
         TestDisplayItem(third, foregroundDrawingType));
 
-    paintController().invalidate(second);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, third, backgroundDrawingType, FloatRect(300, 100, 50, 50));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, second, foregroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, third, foregroundDrawingType, FloatRect(300, 100, 50, 50));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 6,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 6,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(third, backgroundDrawingType),
@@ -243,36 +243,36 @@
 {
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
     drawRect(context, second, foregroundDrawingType, FloatRect(200, 200, 50, 50));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, foregroundDrawingType));
 
-    paintController().invalidate(first);
-    paintController().invalidate(second);
+    getPaintController().invalidate(first);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
     drawRect(context, second, foregroundDrawingType, FloatRect(200, 200, 50, 50));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 4,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 4,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, foregroundDrawingType));
 
-    paintController().invalidate(first);
+    getPaintController().invalidate(first);
     drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
     drawRect(context, second, foregroundDrawingType, FloatRect(200, 200, 50, 50));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, foregroundDrawingType));
 }
@@ -281,37 +281,37 @@
 {
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType));
 
-    paintController().invalidate(first);
-    paintController().invalidate(second);
+    getPaintController().invalidate(first);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
     drawRect(context, second, foregroundDrawingType, FloatRect(200, 200, 50, 50));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 4,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 4,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, foregroundDrawingType));
 
-    paintController().invalidate(first);
-    paintController().invalidate(second);
+    getPaintController().invalidate(first);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, first, foregroundDrawingType, FloatRect(100, 100, 150, 150));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(first, foregroundDrawingType));
 }
@@ -320,39 +320,39 @@
 {
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     {
         ClipRecorder clipRecorder(context, first, clipType, LayoutRect(1, 1, 2, 2));
         drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
         drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     }
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 4,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 4,
         TestDisplayItem(first, clipType),
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(first, DisplayItem::clipTypeToEndClipType(clipType)));
 
-    paintController().invalidate(first);
+    getPaintController().invalidate(first);
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 150));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType));
 
-    paintController().invalidate(second);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     {
         ClipRecorder clipRecorder(context, second, clipType, LayoutRect(1, 1, 2, 2));
         drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     }
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 4,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 4,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, clipType),
         TestDisplayItem(second, backgroundDrawingType),
@@ -363,41 +363,41 @@
 {
     TestDisplayItemClient first("first");
     TestDisplayItemClient second("second");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 150));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType));
-    EXPECT_TRUE(paintController().clientCacheIsValid(first));
-    EXPECT_TRUE(paintController().clientCacheIsValid(second));
-    const SkPicture* firstPicture = static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[0]).picture();
-    const SkPicture* secondPicture = static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[1]).picture();
+    EXPECT_TRUE(getPaintController().clientCacheIsValid(first));
+    EXPECT_TRUE(getPaintController().clientCacheIsValid(second));
+    const SkPicture* firstPicture = static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[0]).picture();
+    const SkPicture* secondPicture = static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[1]).picture();
 
-    paintController().invalidate(first);
-    EXPECT_FALSE(paintController().clientCacheIsValid(first));
-    EXPECT_TRUE(paintController().clientCacheIsValid(second));
+    getPaintController().invalidate(first);
+    EXPECT_FALSE(getPaintController().clientCacheIsValid(first));
+    EXPECT_TRUE(getPaintController().clientCacheIsValid(second));
 
     drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150));
     drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 150));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, backgroundDrawingType));
     // The first display item should be updated.
-    EXPECT_NE(firstPicture, static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[0]).picture());
+    EXPECT_NE(firstPicture, static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[0]).picture());
     // The second display item should be cached.
-    EXPECT_EQ(secondPicture, static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[1]).picture());
-    EXPECT_TRUE(paintController().clientCacheIsValid(first));
-    EXPECT_TRUE(paintController().clientCacheIsValid(second));
+    EXPECT_EQ(secondPicture, static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[1]).picture());
+    EXPECT_TRUE(getPaintController().clientCacheIsValid(first));
+    EXPECT_TRUE(getPaintController().clientCacheIsValid(second));
 
-    paintController().invalidateAll();
-    EXPECT_FALSE(paintController().clientCacheIsValid(first));
-    EXPECT_FALSE(paintController().clientCacheIsValid(second));
+    getPaintController().invalidateAll();
+    EXPECT_FALSE(getPaintController().clientCacheIsValid(first));
+    EXPECT_FALSE(getPaintController().clientCacheIsValid(second));
 }
 
 TEST_F(PaintControllerTest, ComplexUpdateSwapOrder)
@@ -406,7 +406,7 @@
     TestDisplayItemClient content1("content1");
     TestDisplayItemClient container2("container2");
     TestDisplayItemClient content2("content2");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     drawRect(context, container1, backgroundDrawingType, FloatRect(100, 100, 100, 100));
     drawRect(context, content1, backgroundDrawingType, FloatRect(100, 100, 50, 200));
@@ -416,9 +416,9 @@
     drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
     drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
     drawRect(context, container2, foregroundDrawingType, FloatRect(100, 200, 100, 100));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 8,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 8,
         TestDisplayItem(container1, backgroundDrawingType),
         TestDisplayItem(content1, backgroundDrawingType),
         TestDisplayItem(content1, foregroundDrawingType),
@@ -429,7 +429,7 @@
         TestDisplayItem(container2, foregroundDrawingType));
 
     // Simulate the situation when container1 e.g. gets a z-index that is now greater than container2.
-    paintController().invalidate(container1);
+    getPaintController().invalidate(container1);
     drawRect(context, container2, backgroundDrawingType, FloatRect(100, 200, 100, 100));
     drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
     drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
@@ -438,9 +438,9 @@
     drawRect(context, content1, backgroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, content1, foregroundDrawingType, FloatRect(100, 100, 50, 200));
     drawRect(context, container1, foregroundDrawingType, FloatRect(100, 100, 100, 100));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 8,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 8,
         TestDisplayItem(container2, backgroundDrawingType),
         TestDisplayItem(content2, backgroundDrawingType),
         TestDisplayItem(content2, foregroundDrawingType),
@@ -457,7 +457,7 @@
     TestDisplayItemClient content1("content1");
     TestDisplayItemClient container2("container2");
     TestDisplayItemClient content2("content2");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     {
         SubsequenceRecorder r(context, container1);
@@ -473,9 +473,9 @@
         drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
         drawRect(context, container2, foregroundDrawingType, FloatRect(100, 200, 100, 100));
     }
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 12,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 12,
         TestDisplayItem(container1, DisplayItem::Subsequence),
         TestDisplayItem(container1, backgroundDrawingType),
         TestDisplayItem(content1, backgroundDrawingType),
@@ -494,13 +494,13 @@
     EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container2));
     EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container1));
 
-    EXPECT_DISPLAY_LIST(paintController().newDisplayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().newDisplayItemList(), 2,
         TestDisplayItem(container2, DisplayItem::CachedSubsequence),
         TestDisplayItem(container1, DisplayItem::CachedSubsequence));
 
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 12,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 12,
         TestDisplayItem(container2, DisplayItem::Subsequence),
         TestDisplayItem(container2, backgroundDrawingType),
         TestDisplayItem(content2, backgroundDrawingType),
@@ -519,7 +519,7 @@
 TEST_F(PaintControllerTest, OutOfOrderNoCrash)
 {
     TestDisplayItemClient client("client");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     const DisplayItem::Type type1 = DisplayItem::DrawingFirst;
     const DisplayItem::Type type2 = static_cast<DisplayItem::Type>(DisplayItem::DrawingFirst + 1);
@@ -531,14 +531,14 @@
     drawRect(context, client, type3, FloatRect(100, 100, 50, 200));
     drawRect(context, client, type4, FloatRect(100, 100, 100, 100));
 
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
     drawRect(context, client, type2, FloatRect(100, 100, 50, 200));
     drawRect(context, client, type3, FloatRect(100, 100, 50, 200));
     drawRect(context, client, type1, FloatRect(100, 100, 100, 100));
     drawRect(context, client, type4, FloatRect(100, 100, 100, 100));
 
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 }
 
 TEST_F(PaintControllerTest, CachedNestedSubsequenceUpdate)
@@ -547,7 +547,7 @@
     TestDisplayItemClient content1("content1");
     TestDisplayItemClient container2("container2");
     TestDisplayItemClient content2("content2");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     {
         SubsequenceRecorder r(context, container1);
@@ -567,9 +567,9 @@
             drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
         }
     }
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 14,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 14,
         TestDisplayItem(container1, DisplayItem::Subsequence),
         TestDisplayItem(container1, backgroundDrawingType),
         TestDisplayItem(content1, DisplayItem::Subsequence),
@@ -587,13 +587,13 @@
         TestDisplayItem(container2, DisplayItem::EndSubsequence));
 
     // Invalidate container1 but not content1.
-    paintController().invalidate(container1);
+    getPaintController().invalidate(container1);
 
     // Container2 itself now becomes empty (but still has the 'content2' child),
     // and chooses not to output subsequence info.
 
-    paintController().invalidate(container2);
-    paintController().invalidate(content2);
+    getPaintController().invalidate(container2);
+    getPaintController().invalidate(content2);
     EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, container2));
     EXPECT_FALSE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, content2));
     // Content2 now outputs foreground only.
@@ -609,7 +609,7 @@
         EXPECT_TRUE(SubsequenceRecorder::useCachedSubsequenceIfPossible(context, content1));
         drawRect(context, container1, foregroundDrawingType, FloatRect(100, 100, 100, 100));
     }
-    EXPECT_DISPLAY_LIST(paintController().newDisplayItemList(), 7,
+    EXPECT_DISPLAY_LIST(getPaintController().newDisplayItemList(), 7,
         TestDisplayItem(content2, DisplayItem::Subsequence),
         TestDisplayItem(content2, foregroundDrawingType),
         TestDisplayItem(content2, DisplayItem::EndSubsequence),
@@ -618,9 +618,9 @@
         TestDisplayItem(container1, foregroundDrawingType),
         TestDisplayItem(container1, DisplayItem::EndSubsequence));
 
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 10,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 10,
         TestDisplayItem(content2, DisplayItem::Subsequence),
         TestDisplayItem(content2, foregroundDrawingType),
         TestDisplayItem(content2, DisplayItem::EndSubsequence),
@@ -638,7 +638,7 @@
 {
     TestDisplayItemClient multicol("multicol");
     TestDisplayItemClient content("content");
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
 
     FloatRect rect1(100, 100, 50, 50);
     FloatRect rect2(150, 100, 50, 50);
@@ -646,74 +646,74 @@
 
     drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 200, 100, 100));
 
-    paintController().beginScope();
+    getPaintController().beginScope();
     drawRect(context, content, foregroundDrawingType, rect1);
-    paintController().endScope();
+    getPaintController().endScope();
 
-    paintController().beginScope();
+    getPaintController().beginScope();
     drawRect(context, content, foregroundDrawingType, rect2);
-    paintController().endScope();
-    paintController().commitNewDisplayItems();
+    getPaintController().endScope();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 3,
         TestDisplayItem(multicol, backgroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType));
-    RefPtr<const SkPicture> picture1 = static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[1]).picture();
-    RefPtr<const SkPicture> picture2 = static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[2]).picture();
+    RefPtr<const SkPicture> picture1 = static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[1]).picture();
+    RefPtr<const SkPicture> picture2 = static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[2]).picture();
     EXPECT_NE(picture1, picture2);
 
     // Draw again with nothing invalidated.
-    EXPECT_TRUE(paintController().clientCacheIsValid(multicol));
+    EXPECT_TRUE(getPaintController().clientCacheIsValid(multicol));
     drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 200, 100, 100));
-    paintController().beginScope();
+    getPaintController().beginScope();
     drawRect(context, content, foregroundDrawingType, rect1);
-    paintController().endScope();
+    getPaintController().endScope();
 
-    paintController().beginScope();
+    getPaintController().beginScope();
     drawRect(context, content, foregroundDrawingType, rect2);
-    paintController().endScope();
+    getPaintController().endScope();
 
-    EXPECT_DISPLAY_LIST(paintController().newDisplayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().newDisplayItemList(), 3,
         TestDisplayItem(multicol, DisplayItem::drawingTypeToCachedDrawingType(backgroundDrawingType)),
         TestDisplayItem(content, foregroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType));
 
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 3,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 3,
         TestDisplayItem(multicol, backgroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType));
-    EXPECT_NE(picture1, static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[1]).picture());
-    EXPECT_NE(picture2, static_cast<const DrawingDisplayItem&>(paintController().displayItemList()[2]).picture());
+    EXPECT_NE(picture1, static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[1]).picture());
+    EXPECT_NE(picture2, static_cast<const DrawingDisplayItem&>(getPaintController().getDisplayItemList()[2]).picture());
 
     // Now the multicol becomes 3 columns and repaints.
-    paintController().invalidate(multicol);
+    getPaintController().invalidate(multicol);
     drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 100, 100, 100));
 
-    paintController().beginScope();
+    getPaintController().beginScope();
     drawRect(context, content, foregroundDrawingType, rect1);
-    paintController().endScope();
+    getPaintController().endScope();
 
-    paintController().beginScope();
+    getPaintController().beginScope();
     drawRect(context, content, foregroundDrawingType, rect2);
-    paintController().endScope();
+    getPaintController().endScope();
 
-    paintController().beginScope();
+    getPaintController().beginScope();
     drawRect(context, content, foregroundDrawingType, rect3);
-    paintController().endScope();
+    getPaintController().endScope();
 
     // We should repaint everything on invalidation of the scope container.
-    EXPECT_DISPLAY_LIST(paintController().newDisplayItemList(), 4,
+    EXPECT_DISPLAY_LIST(getPaintController().newDisplayItemList(), 4,
         TestDisplayItem(multicol, backgroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType),
         TestDisplayItem(content, foregroundDrawingType));
-    EXPECT_NE(picture1, static_cast<const DrawingDisplayItem&>(paintController().newDisplayItemList()[1]).picture());
-    EXPECT_NE(picture2, static_cast<const DrawingDisplayItem&>(paintController().newDisplayItemList()[2]).picture());
+    EXPECT_NE(picture1, static_cast<const DrawingDisplayItem&>(getPaintController().newDisplayItemList()[1]).picture());
+    EXPECT_NE(picture2, static_cast<const DrawingDisplayItem&>(getPaintController().newDisplayItemList()[2]).picture());
 
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 }
 
 TEST_F(PaintControllerTest, OptimizeNoopPairs)
@@ -722,7 +722,7 @@
     TestDisplayItemClient second("second");
     TestDisplayItemClient third("third");
 
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
     drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100));
     {
         ClipPathRecorder clipRecorder(context, second, Path());
@@ -730,29 +730,29 @@
     }
     drawRect(context, third, backgroundDrawingType, FloatRect(0, 0, 100, 100));
 
-    paintController().commitNewDisplayItems();
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 5,
+    getPaintController().commitNewDisplayItems();
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 5,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(second, DisplayItem::BeginClipPath),
         TestDisplayItem(second, backgroundDrawingType),
         TestDisplayItem(second, DisplayItem::EndClipPath),
         TestDisplayItem(third, backgroundDrawingType));
 
-    paintController().invalidate(second);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100));
     {
         ClipRecorder clipRecorder(context, second, clipType, LayoutRect(1, 1, 2, 2));
         // Do not draw anything for second.
     }
     drawRect(context, third, backgroundDrawingType, FloatRect(0, 0, 100, 100));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
     // Empty clips should have been optimized out.
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(third, backgroundDrawingType));
 
-    paintController().invalidate(second);
+    getPaintController().invalidate(second);
     drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100));
     {
         ClipRecorder clipRecorder(context, second, clipType, LayoutRect(1, 1, 2, 2));
@@ -762,10 +762,10 @@
         }
     }
     drawRect(context, third, backgroundDrawingType, FloatRect(0, 0, 100, 100));
-    paintController().commitNewDisplayItems();
+    getPaintController().commitNewDisplayItems();
 
     // Empty clips should have been optimized out.
-    EXPECT_DISPLAY_LIST(paintController().displayItemList(), 2,
+    EXPECT_DISPLAY_LIST(getPaintController().getDisplayItemList(), 2,
         TestDisplayItem(first, backgroundDrawingType),
         TestDisplayItem(third, backgroundDrawingType));
 }
@@ -775,11 +775,11 @@
     RuntimeEnabledFeatures::setSlimmingPaintV2Enabled(true);
     TestDisplayItemClient client("test client");
 
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
     drawRect(context, client, backgroundDrawingType, FloatRect(0, 0, 100, 100));
 
-    paintController().commitNewDisplayItems();
-    const auto& paintChunks = paintController().paintChunks();
+    getPaintController().commitNewDisplayItems();
+    const auto& paintChunks = getPaintController().paintChunks();
     ASSERT_EQ(1u, paintChunks.size());
     EXPECT_EQ(0u, paintChunks[0].beginIndex);
     EXPECT_EQ(1u, paintChunks[0].endIndex);
@@ -798,12 +798,12 @@
 {
     TestDisplayItemClient client("test client", LayoutRect(0, 0, 200, 100));
 
-    GraphicsContext context(paintController());
+    GraphicsContext context(getPaintController());
     drawRect(context, client, backgroundDrawingType, FloatRect(0, 0, 100, 100));
 
-    paintController().commitNewDisplayItems(LayoutSize(20, 30));
-    const auto& paintArtifact = paintController().paintArtifact();
-    ASSERT_EQ(1u, paintArtifact.displayItemList().size());
+    getPaintController().commitNewDisplayItems(LayoutSize(20, 30));
+    const auto& paintArtifact = getPaintController().paintArtifact();
+    ASSERT_EQ(1u, paintArtifact.getDisplayItemList().size());
     EXPECT_RECT_EQ(IntRect(-20, -30, 200, 100), visualRect(paintArtifact, 0));
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
index e046b9ec..aef96a3 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
@@ -14,13 +14,13 @@
 
 bool SubsequenceRecorder::useCachedSubsequenceIfPossible(GraphicsContext& context, const DisplayItemClient& client)
 {
-    if (context.paintController().displayItemConstructionIsDisabled() || context.paintController().subsequenceCachingIsDisabled())
+    if (context.getPaintController().displayItemConstructionIsDisabled() || context.getPaintController().subsequenceCachingIsDisabled())
         return false;
 
-    if (!context.paintController().clientCacheIsValid(client))
+    if (!context.getPaintController().clientCacheIsValid(client))
         return false;
 
-    context.paintController().createAndAppend<CachedDisplayItem>(client, DisplayItem::CachedSubsequence);
+    context.getPaintController().createAndAppend<CachedDisplayItem>(client, DisplayItem::CachedSubsequence);
 
 #if ENABLE(ASSERT)
     // When under-invalidation checking is enabled, we output CachedSubsequence display item
@@ -33,7 +33,7 @@
 }
 
 SubsequenceRecorder::SubsequenceRecorder(GraphicsContext& context, const DisplayItemClient& client)
-    : m_paintController(context.paintController())
+    : m_paintController(context.getPaintController())
     , m_client(client)
     , m_beginSubsequenceIndex(0)
 {
diff --git a/third_party/WebKit/Source/platform/heap/Handle.h b/third_party/WebKit/Source/platform/heap/Handle.h
index 3fd7ded..5b7cb21 100644
--- a/third_party/WebKit/Source/platform/heap/Handle.h
+++ b/third_party/WebKit/Source/platform/heap/Handle.h
@@ -245,7 +245,7 @@
         } else {
             ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state();
             ASSERT(state->checkThread());
-            m_persistentNode = state->persistentRegion()->allocatePersistentNode(this, traceCallback);
+            m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(this, traceCallback);
 #if ENABLE(ASSERT)
             m_state = state;
 #endif
@@ -264,7 +264,7 @@
             ASSERT(state->checkThread());
             // Persistent handle must be created and destructed in the same thread.
             ASSERT(m_state == state);
-            state->persistentRegion()->freePersistentNode(m_persistentNode);
+            state->getPersistentRegion()->freePersistentNode(m_persistentNode);
         }
         m_persistentNode = nullptr;
     }
@@ -601,7 +601,7 @@
         // FIXME: Derive affinity based on the collection.
         ThreadState* state = ThreadState::current();
         ASSERT(state->checkThread());
-        m_persistentNode = state->persistentRegion()->allocatePersistentNode(this, TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentHeapCollectionBase<Collection>::trace>::trampoline);
+        m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(this, TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentHeapCollectionBase<Collection>::trace>::trampoline);
 #if ENABLE(ASSERT)
         m_state = state;
 #endif
@@ -613,7 +613,7 @@
         ASSERT(state->checkThread());
         // Persistent handle must be created and destructed in the same thread.
         ASSERT(m_state == state);
-        state->persistentRegion()->freePersistentNode(m_persistentNode);
+        state->getPersistentRegion()->freePersistentNode(m_persistentNode);
     }
 
     PersistentNode* m_persistentNode;
diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp
index faa95c99..c44c9a3 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.cpp
+++ b/third_party/WebKit/Source/platform/heap/Heap.cpp
@@ -217,7 +217,7 @@
     ASSERT(ThreadState::current()->isInGC());
 
     // Trace should never reach an orphaned page.
-    ASSERT(!Heap::orphanedPagePool()->contains(object));
+    ASSERT(!Heap::getOrphanedPagePool()->contains(object));
     CallbackStack::Item* slot = s_markingStack->allocateEntry();
     *slot = CallbackStack::Item(object, callback);
 }
@@ -236,7 +236,7 @@
     ASSERT(ThreadState::current()->isInGC());
 
     // Trace should never reach an orphaned page.
-    ASSERT(!Heap::orphanedPagePool()->contains(object));
+    ASSERT(!Heap::getOrphanedPagePool()->contains(object));
     CallbackStack::Item* slot = s_postMarkingCallbackStack->allocateEntry();
     *slot = CallbackStack::Item(object, callback);
 }
@@ -255,7 +255,7 @@
     ASSERT(ThreadState::current()->isInGC());
 
     // Trace should never reach an orphaned page.
-    ASSERT(!Heap::orphanedPagePool()->contains(cell));
+    ASSERT(!Heap::getOrphanedPagePool()->contains(cell));
     CallbackStack::Item* slot = s_globalWeakCallbackStack->allocateEntry();
     *slot = CallbackStack::Item(cell, callback);
 }
@@ -265,8 +265,8 @@
     ASSERT(ThreadState::current()->isInGC());
 
     // Trace should never reach an orphaned page.
-    ASSERT(!Heap::orphanedPagePool()->contains(object));
-    ThreadState* state = pageFromObject(object)->arena()->threadState();
+    ASSERT(!Heap::getOrphanedPagePool()->contains(object));
+    ThreadState* state = pageFromObject(object)->arena()->getThreadState();
     state->pushThreadLocalWeakCallback(closure, callback);
 }
 
@@ -284,7 +284,7 @@
     ASSERT(ThreadState::current()->isInGC());
 
     // Trace should never reach an orphaned page.
-    ASSERT(!Heap::orphanedPagePool()->contains(table));
+    ASSERT(!Heap::getOrphanedPagePool()->contains(table));
     CallbackStack::Item* slot = s_ephemeronStack->allocateEntry();
     *slot = CallbackStack::Item(table, iterationCallback);
 
@@ -403,7 +403,7 @@
     // Now we can delete all orphaned pages because there are no dangling
     // pointers to the orphaned pages.  (If we have such dangling pointers,
     // we should have crashed during marking before getting here.)
-    orphanedPagePool()->decommitOrphanedPages();
+    getOrphanedPagePool()->decommitOrphanedPages();
 
     double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime;
     s_estimatedMarkingTimePerByte = totalObjectSize ? (markingTimeInMilliseconds / 1000 / totalObjectSize) : 0;
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h
index 1930694..4f27e2a 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.h
+++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -166,7 +166,7 @@
         BasePage* page = pageFromObject(objectPointer);
         if (page->hasBeenSwept())
             return false;
-        ASSERT(page->arena()->threadState()->isSweepingInProgress());
+        ASSERT(page->arena()->getThreadState()->isSweepingInProgress());
 
         return !Heap::isHeapObjectAlive(const_cast<T*>(objectPointer));
     }
@@ -252,8 +252,8 @@
 
     static void flushHeapDoesNotContainCache();
 
-    static FreePagePool* freePagePool() { return s_freePagePool; }
-    static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; }
+    static FreePagePool* getFreePagePool() { return s_freePagePool; }
+    static OrphanedPagePool* getOrphanedPagePool() { return s_orphanedPagePool; }
 
     // This look-up uses the region search tree and a negative contains cache to
     // provide an efficient mapping from arbitrary addresses to the containing
diff --git a/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp b/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp
index 60a373bf..73d6ab6 100644
--- a/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapAllocator.cpp
@@ -19,7 +19,7 @@
     // Don't promptly free large objects because their page is never reused.
     // Don't free backings allocated on other threads.
     BasePage* page = pageFromObject(address);
-    if (page->isLargeObjectPage() || page->arena()->threadState() != state)
+    if (page->isLargeObjectPage() || page->arena()->getThreadState() != state)
         return;
 
     HeapObjectHeader* header = HeapObjectHeader::fromPayload(address);
@@ -58,7 +58,7 @@
     // FIXME: Support expand for large objects.
     // Don't expand backings allocated on other threads.
     BasePage* page = pageFromObject(address);
-    if (page->isLargeObjectPage() || page->arena()->threadState() != state)
+    if (page->isLargeObjectPage() || page->arena()->getThreadState() != state)
         return false;
 
     HeapObjectHeader* header = HeapObjectHeader::fromPayload(address);
@@ -101,7 +101,7 @@
     // FIXME: Support shrink for large objects.
     // Don't shrink backings allocated on other threads.
     BasePage* page = pageFromObject(address);
-    if (page->isLargeObjectPage() || page->arena()->threadState() != state)
+    if (page->isLargeObjectPage() || page->arena()->getThreadState() != state)
         return false;
 
     HeapObjectHeader* header = HeapObjectHeader::fromPayload(address);
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 29de33fc..b7d24a5 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -128,7 +128,7 @@
     // Add the BaseArena's pages to the orphanedPagePool.
     for (BasePage* page = m_firstPage; page; page = page->next()) {
         Heap::decreaseAllocatedSpace(page->size());
-        Heap::orphanedPagePool()->addOrphanedPage(arenaIndex(), page);
+        Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), page);
     }
     m_firstPage = nullptr;
 }
@@ -245,7 +245,7 @@
 
 void BaseArena::prepareForSweep()
 {
-    ASSERT(threadState()->isInGC());
+    ASSERT(getThreadState()->isInGC());
     ASSERT(!m_firstUnsweptPage);
 
     // Move all pages to a list of unswept pages.
@@ -285,22 +285,22 @@
     if (!m_firstUnsweptPage)
         return nullptr;
 
-    RELEASE_ASSERT(threadState()->isSweepingInProgress());
+    RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
 
     // lazySweepPages() can be called recursively if finalizers invoked in
     // page->sweep() allocate memory and the allocation triggers
     // lazySweepPages(). This check prevents the sweeping from being executed
     // recursively.
-    if (threadState()->sweepForbidden())
+    if (getThreadState()->sweepForbidden())
         return nullptr;
 
     TRACE_EVENT0("blink_gc", "BaseArena::lazySweepPages");
-    ThreadState::SweepForbiddenScope sweepForbidden(threadState());
+    ThreadState::SweepForbiddenScope sweepForbidden(getThreadState());
     ScriptForbiddenIfMainThreadScope scriptForbidden;
 
     double startTime = WTF::currentTimeMS();
     Address result = lazySweepPages(allocationSize, gcInfoIndex);
-    threadState()->accumulateSweepingTime(WTF::currentTimeMS() - startTime);
+    getThreadState()->accumulateSweepingTime(WTF::currentTimeMS() - startTime);
     Heap::reportMemoryUsageForTracing();
 
     return result;
@@ -329,9 +329,9 @@
     // the deadline per 10 pages.
     static const int deadlineCheckInterval = 10;
 
-    RELEASE_ASSERT(threadState()->isSweepingInProgress());
-    ASSERT(threadState()->sweepForbidden());
-    ASSERT(!threadState()->isMainThread() || ScriptForbiddenScope::isScriptForbidden());
+    RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
+    ASSERT(getThreadState()->sweepForbidden());
+    ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptForbidden());
 
     int pageCount = 1;
     while (m_firstUnsweptPage) {
@@ -351,9 +351,9 @@
 
 void BaseArena::completeSweep()
 {
-    RELEASE_ASSERT(threadState()->isSweepingInProgress());
-    ASSERT(threadState()->sweepForbidden());
-    ASSERT(!threadState()->isMainThread() || ScriptForbiddenScope::isScriptForbidden());
+    RELEASE_ASSERT(getThreadState()->isSweepingInProgress());
+    ASSERT(getThreadState()->sweepForbidden());
+    ASSERT(!getThreadState()->isMainThread() || ScriptForbiddenScope::isScriptForbidden());
 
     while (m_firstUnsweptPage) {
         sweepUnsweptPage();
@@ -416,8 +416,8 @@
 
 void NormalPageArena::allocatePage()
 {
-    threadState()->shouldFlushHeapDoesNotContainCache();
-    PageMemory* pageMemory = Heap::freePagePool()->takeFreePage(arenaIndex());
+    getThreadState()->shouldFlushHeapDoesNotContainCache();
+    PageMemory* pageMemory = Heap::getFreePagePool()->takeFreePage(arenaIndex());
 
     if (!pageMemory) {
         // Allocate a memory region for blinkPagesPerRegion pages that
@@ -440,7 +440,7 @@
                 RELEASE_ASSERT(result);
                 pageMemory = memory;
             } else {
-                Heap::freePagePool()->addFreePage(arenaIndex(), memory);
+                Heap::getFreePagePool()->addFreePage(arenaIndex(), memory);
             }
         }
     }
@@ -474,11 +474,11 @@
         // ensures that tracing the dangling pointer in the next global GC just
         // crashes instead of causing use-after-frees.  After the next global
         // GC, the orphaned pages are removed.
-        Heap::orphanedPagePool()->addOrphanedPage(arenaIndex(), page);
+        Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), page);
     } else {
         PageMemory* memory = page->storage();
         page->~NormalPage();
-        Heap::freePagePool()->addFreePage(arenaIndex(), memory);
+        Heap::getFreePagePool()->addFreePage(arenaIndex(), memory);
     }
 }
 
@@ -493,7 +493,7 @@
     if (m_promptlyFreedSize < 1024 * 1024)
         return false;
 
-    if (threadState()->sweepForbidden())
+    if (getThreadState()->sweepForbidden())
         return false;
 
     ASSERT(!hasCurrentAllocationArea());
@@ -543,7 +543,7 @@
         if (startOfGap != page->payloadEnd())
             addToFreeList(startOfGap, page->payloadEnd() - startOfGap);
     }
-    threadState()->decreaseAllocatedObjectSize(freedSize);
+    getThreadState()->decreaseAllocatedObjectSize(freedSize);
     ASSERT(m_promptlyFreedSize == freedSize);
     m_promptlyFreedSize = 0;
     return true;
@@ -551,7 +551,7 @@
 
 void NormalPageArena::promptlyFreeObject(HeapObjectHeader* header)
 {
-    ASSERT(!threadState()->sweepForbidden());
+    ASSERT(!getThreadState()->sweepForbidden());
     ASSERT(header->checkHeader());
     Address address = reinterpret_cast<Address>(header);
     Address payload = header->payload();
@@ -561,7 +561,7 @@
     ASSERT(pageFromObject(address) == findPageFromAddress(address));
 
     {
-        ThreadState::SweepForbiddenScope forbiddenScope(threadState());
+        ThreadState::SweepForbiddenScope forbiddenScope(getThreadState());
         header->finalize(payload, payloadSize);
         if (address + size == m_currentAllocationPoint) {
             m_currentAllocationPoint = address;
@@ -661,16 +661,16 @@
     //  - if previous alloc checkpoint is larger, allocation size has increased.
     //  - if smaller, a net reduction in size since last call to updateRemainingAllocationSize().
     if (m_lastRemainingAllocationSize > m_remainingAllocationSize)
-        threadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationSize - m_remainingAllocationSize);
+        getThreadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationSize - m_remainingAllocationSize);
     else if (m_lastRemainingAllocationSize != m_remainingAllocationSize)
-        threadState()->decreaseAllocatedObjectSize(m_remainingAllocationSize - m_lastRemainingAllocationSize);
+        getThreadState()->decreaseAllocatedObjectSize(m_remainingAllocationSize - m_lastRemainingAllocationSize);
     m_lastRemainingAllocationSize = m_remainingAllocationSize;
 }
 
 void NormalPageArena::updateRemainingAllocationSize()
 {
     if (m_lastRemainingAllocationSize > remainingAllocationSize()) {
-        threadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationSize - remainingAllocationSize());
+        getThreadState()->increaseAllocatedObjectSize(m_lastRemainingAllocationSize - remainingAllocationSize());
         m_lastRemainingAllocationSize = remainingAllocationSize();
     }
     ASSERT(m_lastRemainingAllocationSize == remainingAllocationSize());
@@ -703,7 +703,7 @@
     if (allocationSize >= largeObjectSizeThreshold) {
         // TODO(sof): support eagerly finalized large objects, if ever needed.
         RELEASE_ASSERT(arenaIndex() != BlinkGC::EagerSweepArenaIndex);
-        LargeObjectArena* largeObjectArena = static_cast<LargeObjectArena*>(threadState()->arena(BlinkGC::LargeObjectArenaIndex));
+        LargeObjectArena* largeObjectArena = static_cast<LargeObjectArena*>(getThreadState()->arena(BlinkGC::LargeObjectArenaIndex));
         Address largeObject = largeObjectArena->allocateLargeObjectPage(allocationSize, gcInfoIndex);
         ASAN_MARK_LARGE_VECTOR_CONTAINER(this, largeObject);
         return largeObject;
@@ -733,10 +733,10 @@
     }
 
     // 6. Complete sweeping.
-    threadState()->completeSweep();
+    getThreadState()->completeSweep();
 
     // 7. Check if we should trigger a GC.
-    threadState()->scheduleGCIfNeeded();
+    getThreadState()->scheduleGCIfNeeded();
 
     // 8. Add a new page to this heap.
     allocatePage();
@@ -797,10 +797,10 @@
 
     // 2. If we have failed in sweeping allocationSize bytes,
     // we complete sweeping before allocating this large object.
-    threadState()->completeSweep();
+    getThreadState()->completeSweep();
 
     // 3. Check if we should trigger a GC.
-    threadState()->scheduleGCIfNeeded();
+    getThreadState()->scheduleGCIfNeeded();
 
     return doAllocateLargeObjectPage(allocationSize, gcInfoIndex);
 }
@@ -814,7 +814,7 @@
     largeObjectSize += allocationGranularity;
 #endif
 
-    threadState()->shouldFlushHeapDoesNotContainCache();
+    getThreadState()->shouldFlushHeapDoesNotContainCache();
     PageMemory* pageMemory = PageMemory::allocate(largeObjectSize);
     Address largeObjectAddress = pageMemory->writableStart();
     Address headerAddress = largeObjectAddress + LargeObjectPage::pageHeaderSize();
@@ -837,7 +837,7 @@
     largeObject->link(&m_firstPage);
 
     Heap::increaseAllocatedSpace(largeObject->size());
-    threadState()->increaseAllocatedObjectSize(largeObject->size());
+    getThreadState()->increaseAllocatedObjectSize(largeObject->size());
     return result;
 }
 
@@ -862,7 +862,7 @@
         // ensures that tracing the dangling pointer in the next global GC just
         // crashes instead of causing use-after-frees.  After the next global
         // GC, the orphaned pages are removed.
-        Heap::orphanedPagePool()->addOrphanedPage(arenaIndex(), object);
+        Heap::getOrphanedPagePool()->addOrphanedPage(arenaIndex(), object);
     } else {
         ASSERT(!ThreadState::current()->isTerminating());
         PageMemory* memory = object->storage();
@@ -1177,7 +1177,7 @@
     }
 
     if (markedObjectSize)
-        pageArena->threadState()->increaseMarkedObjectSize(markedObjectSize);
+        pageArena->getThreadState()->increaseMarkedObjectSize(markedObjectSize);
 }
 
 void NormalPage::makeConsistentForGC()
@@ -1202,7 +1202,7 @@
         headerAddress += header->size();
     }
     if (markedObjectSize)
-        arenaForNormalPage()->threadState()->increaseMarkedObjectSize(markedObjectSize);
+        arenaForNormalPage()->getThreadState()->increaseMarkedObjectSize(markedObjectSize);
 }
 
 void NormalPage::makeConsistentForMutator()
@@ -1466,7 +1466,7 @@
 void LargeObjectPage::sweep()
 {
     heapObjectHeader()->unmark();
-    arena()->threadState()->increaseMarkedObjectSize(size());
+    arena()->getThreadState()->increaseMarkedObjectSize(size());
 }
 
 void LargeObjectPage::makeConsistentForGC()
@@ -1474,7 +1474,7 @@
     HeapObjectHeader* header = heapObjectHeader();
     if (header->isMarked()) {
         header->unmark();
-        arena()->threadState()->increaseMarkedObjectSize(size());
+        arena()->getThreadState()->increaseMarkedObjectSize(size());
     } else {
         header->markDead();
     }
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index 77ff6fb..8895030 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -687,7 +687,7 @@
     bool lazySweepWithDeadline(double deadlineSeconds);
     void completeSweep();
 
-    ThreadState* threadState() { return m_threadState; }
+    ThreadState* getThreadState() { return m_threadState; }
     int arenaIndex() const { return m_index; }
 
 protected:
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index ee21153..c45c657 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -1415,7 +1415,7 @@
     {
         RefPtrWillBeRawPtr<SuperClass> target = targetPass;
         conservativelyCollectGarbage();
-        EXPECT_EQ(pointsBack, target->pointsBack());
+        EXPECT_EQ(pointsBack, target->getPointsBack());
         EXPECT_EQ(superClassCount, SuperClass::s_aliveCount);
     }
 
@@ -1424,7 +1424,7 @@
         visitor->trace(m_pointsBack);
     }
 
-    PointsBack* pointsBack() const { return m_pointsBack.get(); }
+    PointsBack* getPointsBack() const { return m_pointsBack.get(); }
 
     static int s_aliveCount;
 protected:
@@ -5153,7 +5153,7 @@
     }
 
     typedef HeapHashMap<WeakMember<IntWrapper>, Member<EphemeronWrapper>> Map;
-    Map& map() { return m_map; }
+    Map& getMap() { return m_map; }
 
 private:
     Map m_map;
@@ -5169,21 +5169,21 @@
         EphemeronWrapper* oldHead = chain;
         chain = new EphemeronWrapper();
         if (i == 50)
-            chain->map().add(key2, oldHead);
+            chain->getMap().add(key2, oldHead);
         else
-            chain->map().add(key, oldHead);
-        chain->map().add(IntWrapper::create(103), new EphemeronWrapper());
+            chain->getMap().add(key, oldHead);
+        chain->getMap().add(IntWrapper::create(103), new EphemeronWrapper());
     }
 
     preciselyCollectGarbage();
 
     EphemeronWrapper* wrapper = chain;
     for (int i = 0; i< 100; i++) {
-        EXPECT_EQ(1u, wrapper->map().size());
+        EXPECT_EQ(1u, wrapper->getMap().size());
         if (i == 49)
-            wrapper = wrapper->map().get(key2);
+            wrapper = wrapper->getMap().get(key2);
         else
-            wrapper = wrapper->map().get(key);
+            wrapper = wrapper->getMap().get(key);
     }
     EXPECT_EQ(nullptr, wrapper);
 
@@ -5192,14 +5192,14 @@
 
     wrapper = chain;
     for (int i = 0; i < 50; i++) {
-        EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->map().size());
-        wrapper = wrapper->map().get(key);
+        EXPECT_EQ(i == 49 ? 0u : 1u, wrapper->getMap().size());
+        wrapper = wrapper->getMap().get(key);
     }
     EXPECT_EQ(nullptr, wrapper);
 
     key.clear();
     preciselyCollectGarbage();
-    EXPECT_EQ(0u, chain->map().size());
+    EXPECT_EQ(0u, chain->getMap().size());
 }
 
 TEST(HeapTest, Ephemeron)
diff --git a/third_party/WebKit/Source/platform/heap/PagePool.cpp b/third_party/WebKit/Source/platform/heap/PagePool.cpp
index 12580d7..acb5fa3 100644
--- a/third_party/WebKit/Source/platform/heap/PagePool.cpp
+++ b/third_party/WebKit/Source/platform/heap/PagePool.cpp
@@ -101,7 +101,7 @@
             } else {
                 page->~BasePage();
                 clearMemory(memory);
-                Heap::freePagePool()->addFreePage(index, memory);
+                Heap::getFreePagePool()->addFreePage(index, memory);
             }
 
             PoolEntry* deadEntry = entry;
diff --git a/third_party/WebKit/Source/platform/heap/PersistentNode.cpp b/third_party/WebKit/Source/platform/heap/PersistentNode.cpp
index 4130a321..a88190e 100644
--- a/third_party/WebKit/Source/platform/heap/PersistentNode.cpp
+++ b/third_party/WebKit/Source/platform/heap/PersistentNode.cpp
@@ -126,7 +126,7 @@
             // but not invalidate its CrossThreadPersistent<>s.
             if (page->orphaned())
                 continue;
-            if (page->arena()->threadState() == threadState)
+            if (page->arena()->getThreadState() == threadState)
                 persistent->clear();
         }
         slots = slots->m_next;
diff --git a/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp b/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
index 8412e4ed..3c0a0395 100644
--- a/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
+++ b/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
@@ -18,11 +18,7 @@
 
 static const char* s_avoidOptimization = nullptr;
 
-uintptr_t StackFrameDepth::s_stackFrameLimit = 0;
-#if ENABLE(ASSERT)
-bool StackFrameDepth::s_isEnabled = false;
-bool StackFrameDepth::s_isUsingFallbackStackSize = false;
-#endif
+uintptr_t StackFrameDepth::s_stackFrameLimit = kMinimumStackLimit;
 
 // NEVER_INLINE ensures that |dummy| array on configureLimit() is not optimized away,
 // and the stack frame base register is adjusted |kSafeStackFrameSize|.
@@ -40,22 +36,11 @@
 
     // Check that the stack frame can be used.
     dummy[sizeof(dummy) - 1] = 0;
-#if ENABLE(ASSERT)
-    // Use a larger stack limit for what's acceptable if the platform
-    // thread ends up using the fallback size to decide if switching to
-    // lazy marking is in order.
-    s_isUsingFallbackStackSize = true;
-#endif
     return currentStackFrameBaseOnCallee(dummy);
 }
 
 void StackFrameDepth::enableStackLimit()
 {
-#if ENABLE(ASSERT)
-    s_isEnabled = true;
-    s_isUsingFallbackStackSize = false;
-#endif
-
     // All supported platforms will currently return a non-zero estimate,
     // except if ASan is enabled.
     size_t stackSize = getUnderestimatedStackSize();
@@ -72,11 +57,9 @@
     RELEASE_ASSERT(stackBase > reinterpret_cast<Address>(stackRoom));
     s_stackFrameLimit = reinterpret_cast<uintptr_t>(stackBase - stackRoom);
 
-#if ENABLE(ASSERT)
     // If current stack use is already exceeding estimated limit, mark as disabled.
     if (!isSafeToRecurse())
-        s_isEnabled = false;
-#endif
+        disableStackLimit();
 }
 
 size_t StackFrameDepth::getUnderestimatedStackSize()
diff --git a/third_party/WebKit/Source/platform/heap/StackFrameDepth.h b/third_party/WebKit/Source/platform/heap/StackFrameDepth.h
index 05cd6c6..94379aa 100644
--- a/third_party/WebKit/Source/platform/heap/StackFrameDepth.h
+++ b/third_party/WebKit/Source/platform/heap/StackFrameDepth.h
@@ -14,15 +14,16 @@
 namespace blink {
 
 // StackFrameDepth keeps track of current call stack frame depth.
-// Use isSafeToRecurse() to query if there is a room in current
-// call stack for more recursive call.
+// It is specifically used to control stack usage while tracing
+// the object graph during a GC.
+//
+// Use isSafeToRecurse() to determine if it is safe to consume
+// more stack by invoking another recursive call.
 class PLATFORM_EXPORT StackFrameDepth final {
     STATIC_ONLY(StackFrameDepth);
 public:
     inline static bool isSafeToRecurse()
     {
-        ASSERT(s_stackFrameLimit || !s_isEnabled);
-
         // Asssume that the stack grows towards lower addresses, which
         // all the ABIs currently supported do.
         //
@@ -34,27 +35,18 @@
     static void enableStackLimit();
     static void disableStackLimit()
     {
-        s_stackFrameLimit = 0;
-#if ENABLE(ASSERT)
-        s_isEnabled = false;
-#endif
+        s_stackFrameLimit = kMinimumStackLimit;
     }
 
 #if ENABLE(ASSERT)
-    inline static bool isEnabled() { return s_isEnabled; }
+    inline static bool isEnabled() { return s_stackFrameLimit != kMinimumStackLimit; }
     inline static bool isAcceptableStackUse()
     {
-        // ASan adds extra stack usage leading to too noisy asserts.
 #if defined(ADDRESS_SANITIZER)
+        // ASan adds extra stack usage leading to too noisy asserts.
         return true;
 #else
-        // If a conservative fallback stack size is in effect, use
-        // a larger stack limit so as to avoid false positives.
-        if (!s_isEnabled || isSafeToRecurse())
-            return true;
-        if (s_isUsingFallbackStackSize)
-            return (s_stackFrameLimit - currentStackFrame()) < 3 * kSafeStackFrameSize;
-        return false;
+        return !isEnabled() || isSafeToRecurse();
 #endif
     }
 #endif
@@ -85,16 +77,19 @@
 
 private:
     // The maximum depth of eager, unrolled trace() calls that is
-    // considered safe and allowed.
+    // considered safe and allowed for targets with an unknown
+    // thread stack size.
     static const int kSafeStackFrameSize = 32 * 1024;
 
+    // The stack pointer is assumed to grow towards lower addresses;
+    // |kMinimumStackLimit| then being the limit that a stack
+    // pointer will always exceed.
+    static const uintptr_t kMinimumStackLimit = ~0ul;
+
     static uintptr_t getFallbackStackLimit();
 
+    // The (pointer-valued) stack limit.
     static uintptr_t s_stackFrameLimit;
-#if ENABLE(ASSERT)
-    static bool s_isEnabled;
-    static bool s_isUsingFallbackStackSize;
-#endif
 };
 
 class StackFrameDepthScope {
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
index f0d95f8d..beaaf304 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
@@ -290,12 +290,12 @@
         // Do thread local GC's as long as the count of thread local Persistents
         // changes and is above zero.
         int oldCount = -1;
-        int currentCount = persistentRegion()->numberOfPersistents();
+        int currentCount = getPersistentRegion()->numberOfPersistents();
         ASSERT(currentCount >= 0);
         while (currentCount != oldCount) {
             Heap::collectGarbageForTerminatingThread(this);
             oldCount = currentCount;
-            currentCount = persistentRegion()->numberOfPersistents();
+            currentCount = getPersistentRegion()->numberOfPersistents();
         }
         // We should not have any persistents left when getting to this point,
         // if we have it is probably a bug so adding a debug ASSERT to catch this.
@@ -1368,7 +1368,7 @@
 void ThreadState::releaseStaticPersistentNodes()
 {
     for (PersistentNode* node : m_staticPersistents)
-        persistentRegion()->freePersistentNode(node);
+        getPersistentRegion()->freePersistentNode(node);
 
     m_staticPersistents.clear();
 }
diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.h b/third_party/WebKit/Source/platform/heap/ThreadState.h
index 22a5856..d5a5669 100644
--- a/third_party/WebKit/Source/platform/heap/ThreadState.h
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.h
@@ -368,7 +368,7 @@
 #endif
 
     // A region of PersistentNodes allocated on the given thread.
-    PersistentRegion* persistentRegion() const { return m_persistentRegion.get(); }
+    PersistentRegion* getPersistentRegion() const { return m_persistentRegion.get(); }
     // A region of PersistentNodes not owned by any particular thread.
 
     // Visit local thread stack and trace all pointers conservatively.
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
index c346fff..824764c5 100644
--- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -117,7 +117,7 @@
     if (!width || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
         return true;
 
-    const GIFColorMap::Table& colorTable = frameContext->localColorMap().isDefined() ? frameContext->localColorMap().table() : m_reader->globalColorMap().table();
+    const GIFColorMap::Table& colorTable = frameContext->localColorMap().isDefined() ? frameContext->localColorMap().getTable() : m_reader->globalColorMap().getTable();
 
     if (colorTable.isEmpty())
         return true;
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h
index 42234e7a..6172377 100644
--- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h
+++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h
@@ -171,7 +171,7 @@
 
     // Build RGBA table using the data stream.
     void buildTable(blink::FastSharedBufferReader*);
-    const Table& table() const { return m_table; }
+    const Table& getTable() const { return m_table; }
 
 private:
     bool m_isDefined;
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
index 97c0ec56..f3b5926 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -496,7 +496,7 @@
 
 - (ScrollAnimatorMac&)scrollAnimator
 {
-    return static_cast<ScrollAnimatorMac&>(_scrollbar->scrollableArea()->scrollAnimator());
+    return static_cast<ScrollAnimatorMac&>(_scrollbar->getScrollableArea()->scrollAnimator());
 }
 
 - (NSRect)convertRectToBacking:(NSRect)aRect
@@ -516,7 +516,7 @@
 
     ASSERT_UNUSED(scrollerImp, scrollerImp == scrollbarPainterForScrollbar(*_scrollbar));
 
-    return _scrollbar->convertFromContainingWidget(_scrollbar->scrollableArea()->lastKnownMousePosition());
+    return _scrollbar->convertFromContainingWidget(_scrollbar->getScrollableArea()->lastKnownMousePosition());
 }
 
 - (void)setUpAlphaAnimation:(RetainPtr<BlinkScrollbarPartAnimation>&)scrollbarPartAnimation scrollerPainter:(ScrollbarPainter)scrollerPainter part:(blink::ScrollbarPart)part animateAlphaTo:(CGFloat)newAlpha duration:(NSTimeInterval)duration
@@ -528,7 +528,7 @@
     if ([self scrollAnimator].scrollbarPaintTimerIsActive() && !mustAnimate)
         return;
 
-    if (_scrollbar->scrollableArea()->shouldSuspendScrollAnimations() && !mustAnimate) {
+    if (_scrollbar->getScrollableArea()->shouldSuspendScrollAnimations() && !mustAnimate) {
         [self scrollAnimator].startScrollbarPaintTimer();
         return;
     }
@@ -779,7 +779,7 @@
     FloatPoint adjustedPosition = adjustScrollPositionIfNecessary(newPosition);
 
     bool positionChanged = adjustedPosition != m_currentPos;
-    if (!positionChanged && !scrollableArea()->scrollOriginChanged())
+    if (!positionChanged && !getScrollableArea()->scrollOriginChanged())
         return;
 
     FloatSize delta = adjustedPosition - m_currentPos;
@@ -797,35 +797,35 @@
 
 void ScrollAnimatorMac::contentAreaWillPaint() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() contentAreaWillDraw];
 }
 
 void ScrollAnimatorMac::mouseEnteredContentArea() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() mouseEnteredContentArea];
 }
 
 void ScrollAnimatorMac::mouseExitedContentArea() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() mouseExitedContentArea];
 }
 
 void ScrollAnimatorMac::mouseMovedInContentArea() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() mouseMovedInContentArea];
 }
 
 void ScrollAnimatorMac::mouseEnteredScrollbar(Scrollbar& scrollbar) const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
 
     if (!supportsUIStateTransitionProgress())
@@ -836,7 +836,7 @@
 
 void ScrollAnimatorMac::mouseExitedScrollbar(Scrollbar& scrollbar) const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
 
     if (!supportsUIStateTransitionProgress())
@@ -847,42 +847,42 @@
 
 void ScrollAnimatorMac::contentsResized() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() contentAreaDidResize];
 }
 
 void ScrollAnimatorMac::contentAreaDidShow() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() windowOrderedIn];
 }
 
 void ScrollAnimatorMac::contentAreaDidHide() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() windowOrderedOut];
 }
 
 void ScrollAnimatorMac::didBeginScrollGesture() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() beginScrollGesture];
 }
 
 void ScrollAnimatorMac::didEndScrollGesture() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() endScrollGesture];
 }
 
 void ScrollAnimatorMac::mayBeginScrollGesture() const
 {
-    if (!scrollableArea()->scrollbarsCanBeActive())
+    if (!getScrollableArea()->scrollbarsCanBeActive())
         return;
     [m_scrollbarPainterController.get() beginScrollGesture];
     [m_scrollbarPainterController.get() contentAreaScrolled];
@@ -965,7 +965,7 @@
     // This function is called when a page is going into the page cache, but the page
     // isn't really scrolling in that case. We should only pass the message on to the
     // ScrollbarPainterController when we're really scrolling on an active page.
-    if (scrollableArea()->scrollbarsCanBeActive())
+    if (getScrollableArea()->scrollbarsCanBeActive())
         sendContentAreaScrolledSoon(delta);
 }
 
@@ -1003,7 +1003,7 @@
 
 void ScrollAnimatorMac::updateScrollerStyle()
 {
-    if (!scrollableArea()->scrollbarsCanBeActive()) {
+    if (!getScrollableArea()->scrollbarsCanBeActive()) {
         m_needsScrollerStyleUpdate = true;
         return;
     }
@@ -1016,7 +1016,7 @@
 
     NSScrollerStyle newStyle = [m_scrollbarPainterController.get() scrollerStyle];
 
-    if (Scrollbar* verticalScrollbar = scrollableArea()->verticalScrollbar()) {
+    if (Scrollbar* verticalScrollbar = getScrollableArea()->verticalScrollbar()) {
         verticalScrollbar->setNeedsPaintInvalidation(AllParts);
 
         ScrollbarPainter oldVerticalPainter = [m_scrollbarPainterController.get() verticalScrollerImp];
@@ -1034,7 +1034,7 @@
         verticalScrollbar->setFrameRect(IntRect(0, 0, thickness, thickness));
     }
 
-    if (Scrollbar* horizontalScrollbar = scrollableArea()->horizontalScrollbar()) {
+    if (Scrollbar* horizontalScrollbar = getScrollableArea()->horizontalScrollbar()) {
         horizontalScrollbar->setNeedsPaintInvalidation(AllParts);
 
         ScrollbarPainter oldHorizontalPainter = [m_scrollbarPainterController.get() horizontalScrollerImp];
@@ -1055,7 +1055,7 @@
     // If m_needsScrollerStyleUpdate is true, then the page is restoring from the page cache, and
     // a relayout will happen on its own. Otherwise, we must initiate a re-layout ourselves.
     if (!m_needsScrollerStyleUpdate)
-        scrollableArea()->scrollbarStyleChanged();
+        getScrollableArea()->scrollbarStyleChanged();
 
     m_needsScrollerStyleUpdate = false;
 }
diff --git a/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h b/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h
index 7594056..adb95cb 100644
--- a/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h
+++ b/third_party/WebKit/Source/platform/mediastream/MediaStreamComponent.h
@@ -71,7 +71,7 @@
     AudioSourceProvider* getAudioSourceProvider() { return &m_sourceProvider; }
     void setSourceProvider(WebAudioSourceProvider* provider) { m_sourceProvider.wrap(provider); }
 
-    ExtraData* extraData() const { return m_extraData.get(); }
+    ExtraData* getExtraData() const { return m_extraData.get(); }
     void setExtraData(PassOwnPtr<ExtraData> extraData) { m_extraData = std::move(extraData); }
 
     DECLARE_TRACE();
diff --git a/third_party/WebKit/Source/platform/mediastream/MediaStreamDescriptor.h b/third_party/WebKit/Source/platform/mediastream/MediaStreamDescriptor.h
index 13c0b56..15c7891 100644
--- a/third_party/WebKit/Source/platform/mediastream/MediaStreamDescriptor.h
+++ b/third_party/WebKit/Source/platform/mediastream/MediaStreamDescriptor.h
@@ -89,7 +89,7 @@
     bool ended() const { return m_ended; }
     void setEnded() { m_ended = true; }
 
-    ExtraData* extraData() const { return m_extraData.get(); }
+    ExtraData* getExtraData() const { return m_extraData.get(); }
     void setExtraData(PassOwnPtr<ExtraData> extraData) { m_extraData = std::move(extraData); }
 
     // |m_extraData| may hold pointers to GC objects, and it may touch them in destruction.
diff --git a/third_party/WebKit/Source/platform/mediastream/MediaStreamSource.h b/third_party/WebKit/Source/platform/mediastream/MediaStreamSource.h
index 8802ae5..d37d4b9 100644
--- a/third_party/WebKit/Source/platform/mediastream/MediaStreamSource.h
+++ b/third_party/WebKit/Source/platform/mediastream/MediaStreamSource.h
@@ -83,7 +83,7 @@
 
     void addObserver(Observer*);
 
-    ExtraData* extraData() const { return m_extraData.get(); }
+    ExtraData* getExtraData() const { return m_extraData.get(); }
     void setExtraData(PassOwnPtr<ExtraData> extraData) { m_extraData = std::move(extraData); }
 
     void setConstraints(WebMediaConstraints constraints) { m_constraints = constraints; }
diff --git a/third_party/WebKit/Source/platform/network/ResourceRequest.h b/third_party/WebKit/Source/platform/network/ResourceRequest.h
index 5abfaec..81bd43a 100644
--- a/third_party/WebKit/Source/platform/network/ResourceRequest.h
+++ b/third_party/WebKit/Source/platform/network/ResourceRequest.h
@@ -206,7 +206,7 @@
     void setShouldResetAppCache(bool shouldResetAppCache) { m_shouldResetAppCache = shouldResetAppCache; }
 
     // Extra data associated with this request.
-    ExtraData* extraData() const { return m_extraData.get(); }
+    ExtraData* getExtraData() const { return m_extraData.get(); }
     void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; }
 
     WebURLRequest::RequestContext requestContext() const { return m_requestContext; }
diff --git a/third_party/WebKit/Source/platform/network/ResourceResponse.cpp b/third_party/WebKit/Source/platform/network/ResourceResponse.cpp
index 4c3fe12..bb00a85 100644
--- a/third_party/WebKit/Source/platform/network/ResourceResponse.cpp
+++ b/third_party/WebKit/Source/platform/network/ResourceResponse.cpp
@@ -51,7 +51,6 @@
     , m_securityStyle(SecurityStyleUnknown)
     , m_httpVersion(HTTPVersionUnknown)
     , m_appCacheID(0)
-    , m_isMultipartPayload(false)
     , m_wasFetchedViaSPDY(false)
     , m_wasNpnNegotiated(false)
     , m_wasAlternateProtocolAvailable(false)
@@ -88,7 +87,6 @@
     , m_securityStyle(SecurityStyleUnknown)
     , m_httpVersion(HTTPVersionUnknown)
     , m_appCacheID(0)
-    , m_isMultipartPayload(false)
     , m_wasFetchedViaSPDY(false)
     , m_wasNpnNegotiated(false)
     , m_wasAlternateProtocolAvailable(false)
@@ -130,7 +128,7 @@
     m_httpVersion = data->m_httpVersion;
     m_appCacheID = data->m_appCacheID;
     m_appCacheManifestURL = data->m_appCacheManifestURL.copy();
-    m_isMultipartPayload = data->m_isMultipartPayload;
+    m_multipartBoundary = data->m_multipartBoundary;
     m_wasFetchedViaSPDY = data->m_wasFetchedViaSPDY;
     m_wasNpnNegotiated = data->m_wasNpnNegotiated;
     m_wasAlternateProtocolAvailable = data->m_wasAlternateProtocolAvailable;
@@ -177,7 +175,7 @@
     data->m_httpVersion = m_httpVersion;
     data->m_appCacheID = m_appCacheID;
     data->m_appCacheManifestURL = m_appCacheManifestURL.copy();
-    data->m_isMultipartPayload = m_isMultipartPayload;
+    data->m_multipartBoundary = m_multipartBoundary;
     data->m_wasFetchedViaSPDY = m_wasFetchedViaSPDY;
     data->m_wasNpnNegotiated = m_wasNpnNegotiated;
     data->m_wasAlternateProtocolAvailable = m_wasAlternateProtocolAvailable;
diff --git a/third_party/WebKit/Source/platform/network/ResourceResponse.h b/third_party/WebKit/Source/platform/network/ResourceResponse.h
index 5977377b..03505d4 100644
--- a/third_party/WebKit/Source/platform/network/ResourceResponse.h
+++ b/third_party/WebKit/Source/platform/network/ResourceResponse.h
@@ -175,7 +175,7 @@
     SecurityStyle getSecurityStyle() const { return m_securityStyle; }
     void setSecurityStyle(SecurityStyle securityStyle) { m_securityStyle = securityStyle; }
 
-    const SecurityDetails* securityDetails() const { return &m_securityDetails; }
+    const SecurityDetails* getSecurityDetails() const { return &m_securityDetails; }
     void setSecurityDetails(const String& protocol, const String& keyExchange, const String& cipher, const String& mac, int certId, size_t numUnknownScts, size_t numInvalidScts, size_t numValidScts);
 
     long long appCacheID() const { return m_appCacheID; }
@@ -214,8 +214,12 @@
     const KURL& originalURLViaServiceWorker() const { return m_originalURLViaServiceWorker; }
     void setOriginalURLViaServiceWorker(const KURL& url) { m_originalURLViaServiceWorker = url; }
 
-    bool isMultipartPayload() const { return m_isMultipartPayload; }
-    void setIsMultipartPayload(bool value) { m_isMultipartPayload = value; }
+    const Vector<char>& multipartBoundary() const { return m_multipartBoundary; }
+    void setMultipartBoundary(const char* bytes, size_t size)
+    {
+        m_multipartBoundary.clear();
+        m_multipartBoundary.append(bytes, size);
+    }
 
     int64_t responseTime() const { return m_responseTime; }
     void setResponseTime(int64_t responseTime) { m_responseTime = responseTime; }
@@ -230,7 +234,7 @@
     void setDownloadedFilePath(const String&);
 
     // Extra data associated with this response.
-    ExtraData* extraData() const { return m_extraData.get(); }
+    ExtraData* getExtraData() const { return m_extraData.get(); }
     void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; }
 
     // The ResourceResponse subclass may "shadow" this method to provide platform-specific memory usage information
@@ -305,8 +309,8 @@
     // Note: only valid for main resource responses.
     KURL m_appCacheManifestURL;
 
-    // Set to true if this is part of a multipart response.
-    bool m_isMultipartPayload;
+    // The multipart boundary of this response.
+    Vector<char> m_multipartBoundary;
 
     // Was the resource fetched over SPDY.  See http://dev.chromium.org/spdy
     bool m_wasFetchedViaSPDY;
@@ -379,7 +383,7 @@
     ResourceResponse::HTTPVersion m_httpVersion;
     long long m_appCacheID;
     KURL m_appCacheManifestURL;
-    bool m_isMultipartPayload;
+    Vector<char> m_multipartBoundary;
     bool m_wasFetchedViaSPDY;
     bool m_wasNpnNegotiated;
     bool m_wasAlternateProtocolAvailable;
diff --git a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h
index 601ccc8e..fd09f72 100644
--- a/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h
+++ b/third_party/WebKit/Source/platform/scroll/ProgrammaticScrollAnimator.h
@@ -36,7 +36,7 @@
     void resetAnimationState() override;
     void cancelAnimation() override;
     void takeoverCompositorAnimation() override { };
-    ScrollableArea* scrollableArea() const override { return m_scrollableArea; }
+    ScrollableArea* getScrollableArea() const override { return m_scrollableArea; }
     void tickAnimation(double monotonicTime) override;
     void updateCompositorAnimations() override;
     void notifyCompositorAnimationFinished(int groupId) override;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
index bd011191..7c5380a 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimator.cpp
@@ -199,7 +199,7 @@
     if (isFinished)
         m_runState = RunState::PostAnimationCleanup;
     else
-        scrollableArea()->scheduleAnimation();
+        getScrollableArea()->scheduleAnimation();
 
     TRACE_EVENT0("blink", "ScrollAnimator::notifyPositionChanged");
     notifyPositionChanged();
@@ -320,7 +320,7 @@
 
 void ScrollAnimator::addMainThreadScrollingReason()
 {
-    if (WebLayer* scrollLayer = toWebLayer(scrollableArea()->layerForScrolling())) {
+    if (WebLayer* scrollLayer = toWebLayer(getScrollableArea()->layerForScrolling())) {
         scrollLayer->addMainThreadScrollingReasons(
             MainThreadScrollingReason::kAnimatingScrollOnMainThread);
     }
@@ -328,7 +328,7 @@
 
 void ScrollAnimator::removeMainThreadScrollingReason()
 {
-    if (WebLayer* scrollLayer = toWebLayer(scrollableArea()->layerForScrolling())) {
+    if (WebLayer* scrollLayer = toWebLayer(getScrollableArea()->layerForScrolling())) {
         scrollLayer->clearMainThreadScrollingReasons(
             MainThreadScrollingReason::kAnimatingScrollOnMainThread);
     }
@@ -391,7 +391,7 @@
 
 bool ScrollAnimator::registerAndScheduleAnimation()
 {
-    scrollableArea()->registerForAnimation();
+    getScrollableArea()->registerForAnimation();
     if (!m_scrollableArea->scheduleAnimation()) {
         scrollToOffsetWithoutAnimation(m_targetOffset);
         resetAnimationState();
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
index 39da482..4acba921 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorBase.h
@@ -78,7 +78,7 @@
 
 
     // ScrollAnimatorCompositorCoordinator implementation.
-    ScrollableArea* scrollableArea() const override { return m_scrollableArea; }
+    ScrollableArea* getScrollableArea() const override { return m_scrollableArea; }
     void tickAnimation(double monotonicTime) override { };
     void cancelAnimation() override { }
     void takeoverCompositorAnimation() override { }
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp
index b340b18..4bbbc82 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.cpp
@@ -114,7 +114,7 @@
         m_runState = RunState::WaitingToCancelOnCompositor;
 
         // Get serviced the next time compositor updates are allowed.
-        scrollableArea()->registerForAnimation();
+        getScrollableArea()->registerForAnimation();
     }
 }
 
@@ -138,7 +138,7 @@
         m_runState = RunState::RunningOnCompositorButNeedsTakeover;
 
         // Get serviced the next time compositor updates are allowed.
-        scrollableArea()->registerForAnimation();
+        getScrollableArea()->registerForAnimation();
     }
 }
 
@@ -165,8 +165,8 @@
     case RunState::WaitingToCancelOnCompositor:
         m_runState = RunState::PostAnimationCleanup;
         // Get serviced the next time compositor updates are allowed.
-        if (scrollableArea())
-            scrollableArea()->registerForAnimation();
+        if (getScrollableArea())
+            getScrollableArea()->registerForAnimation();
         else
             resetAnimationState();
     }
@@ -177,8 +177,8 @@
 {
     bool reattached = false;
     int compositorAnimationAttachedToLayerId = 0;
-    if (scrollableArea()->layerForScrolling())
-        compositorAnimationAttachedToLayerId = scrollableArea()->layerForScrolling()->platformLayer()->id();
+    if (getScrollableArea()->layerForScrolling())
+        compositorAnimationAttachedToLayerId = getScrollableArea()->layerForScrolling()->platformLayer()->id();
 
     if (compositorAnimationAttachedToLayerId != m_compositorAnimationAttachedToLayerId) {
         if (m_compositorPlayer && timeline) {
@@ -193,7 +193,7 @@
                 ASSERT(!m_compositorPlayer->isLayerAttached());
                 timeline->playerAttached(*this);
                 m_compositorPlayer->attachLayer(
-                    scrollableArea()->layerForScrolling()->platformLayer());
+                    getScrollableArea()->layerForScrolling()->platformLayer());
                 reattached = true;
             }
             m_compositorAnimationAttachedToLayerId = compositorAnimationAttachedToLayerId;
@@ -229,13 +229,13 @@
 
 FloatPoint ScrollAnimatorCompositorCoordinator::compositorOffsetFromBlinkOffset(FloatPoint offset)
 {
-    offset.moveBy(scrollableArea()->scrollOrigin());
+    offset.moveBy(getScrollableArea()->scrollOrigin());
     return offset;
 }
 
 FloatPoint ScrollAnimatorCompositorCoordinator::blinkOffsetFromCompositorOffset(FloatPoint offset)
 {
-    offset.moveBy(-scrollableArea()->scrollOrigin());
+    offset.moveBy(-getScrollableArea()->scrollOrigin());
     return offset;
 }
 
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h
index bedc476..bf914d4 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorCompositorCoordinator.h
@@ -42,7 +42,7 @@
     // DocumentLifecycle::LifecycleState::CompositingClean state.
     virtual void takeoverCompositorAnimation();
 
-    virtual ScrollableArea* scrollableArea() const = 0;
+    virtual ScrollableArea* getScrollableArea() const = 0;
     virtual void tickAnimation(double monotonicTime) = 0;
     virtual void updateCompositorAnimations() = 0;
     virtual void notifyCompositorAnimationFinished(int groupId) = 0;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
index 441a976..904518d 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
@@ -482,8 +482,8 @@
 
 bool ScrollableArea::scheduleAnimation()
 {
-    if (HostWindow* window = hostWindow()) {
-        window->scheduleAnimation(widget());
+    if (HostWindow* window = getHostWindow()) {
+        window->scheduleAnimation(getWidget());
         return true;
     }
     return false;
@@ -577,7 +577,7 @@
 
 int ScrollableArea::lineStep(ScrollbarOrientation) const
 {
-    return pixelsPerLineStep(hostWindow());
+    return pixelsPerLineStep(getHostWindow());
 }
 
 int ScrollableArea::pageStep(ScrollbarOrientation orientation) const
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index f371838..b01d1be 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -84,7 +84,7 @@
 
     // The window that hosts the ScrollableArea. The ScrollableArea will communicate scrolls and repaints to the
     // host window in the window's coordinate space.
-    virtual HostWindow* hostWindow() const { return 0; }
+    virtual HostWindow* getHostWindow() const { return 0; }
 
     virtual ScrollResult userScroll(ScrollGranularity, const FloatSize&);
 
@@ -273,7 +273,7 @@
     IntSize excludeScrollbars(const IntSize&) const;
 
     // Returns the widget associated with this ScrollableArea.
-    virtual Widget* widget() { return nullptr; }
+    virtual Widget* getWidget() { return nullptr; }
 
     virtual bool isFrameView() const { return false; }
     virtual bool isPaintLayerScrollableArea() const { return false; }
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.h b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
index 6390c67..c1dfe8e 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.h
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
@@ -101,7 +101,7 @@
     void offsetDidChange();
 
     void disconnectFromScrollableArea();
-    ScrollableArea* scrollableArea() const { return m_scrollableArea; }
+    ScrollableArea* getScrollableArea() const { return m_scrollableArea; }
 
     int pressedPos() const { return m_pressedPos; }
 
diff --git a/third_party/WebKit/Source/platform/testing/GeometryPrinters.cpp b/third_party/WebKit/Source/platform/testing/GeometryPrinters.cpp
index 04f33ec..2d7226da 100644
--- a/third_party/WebKit/Source/platform/testing/GeometryPrinters.cpp
+++ b/third_party/WebKit/Source/platform/testing/GeometryPrinters.cpp
@@ -93,7 +93,7 @@
     *os << "FloatRoundedRect(";
     PrintTo(roundedRect.rect(), os);
     *os << ", ";
-    PrintTo(roundedRect.radii(), os);
+    PrintTo(roundedRect.getRadii(), os);
     *os << ")";
 }
 
diff --git a/third_party/WebKit/Source/platform/testing/RunAllTests.cpp b/third_party/WebKit/Source/platform/testing/RunAllTests.cpp
index dc8ed0f..15791e5 100644
--- a/third_party/WebKit/Source/platform/testing/RunAllTests.cpp
+++ b/third_party/WebKit/Source/platform/testing/RunAllTests.cpp
@@ -33,6 +33,7 @@
 #include "mojo/edk/test/scoped_ipc_support.h"
 #include "platform/EventTracer.h"
 #include "platform/HTTPNames.h"
+#include "platform/graphics/CompositorFactory.h"
 #include "platform/heap/Heap.h"
 #include "platform/testing/TestingPlatformSupport.h"
 #include "public/platform/Platform.h"
@@ -73,40 +74,38 @@
 {
     base::CommandLine::Init(argc, argv);
 
+    OwnPtr<DummyPlatform> platform = adoptPtr(new DummyPlatform);
+    blink::Platform::setCurrentPlatformForTesting(platform.get());
+
     WTF::Partitions::initialize(nullptr);
     WTF::setTimeFunctionsForTesting(dummyCurrentTime);
-    WTF::initialize(nullptr);
+    WTF::initialize();
     WTF::initializeMainThread(0);
+    blink::CompositorFactory::initializeDefault();
     int result = 0;
     {
-        OwnPtr<DummyPlatform> platform = adoptPtr(new DummyPlatform);
-        blink::Platform::initialize(platform.get());
-        {
-            blink::TestingPlatformSupport::Config platformConfig;
-            cc_blink::WebCompositorSupportImpl compositorSupport;
-            platformConfig.compositorSupport = &compositorSupport;
-            blink::TestingPlatformSupport platform(platformConfig);
+        blink::TestingPlatformSupport::Config platformConfig;
+        cc_blink::WebCompositorSupportImpl compositorSupport;
+        platformConfig.compositorSupport = &compositorSupport;
+        blink::TestingPlatformSupport platform(platformConfig);
 
-            blink::Heap::init();
-            blink::ThreadState::attachMainThread();
-            blink::ThreadState::current()->registerTraceDOMWrappers(nullptr, nullptr);
-            blink::EventTracer::initialize();
+        blink::Heap::init();
+        blink::ThreadState::attachMainThread();
+        blink::ThreadState::current()->registerTraceDOMWrappers(nullptr, nullptr);
+        blink::EventTracer::initialize();
+        blink::HTTPNames::init();
 
-            blink::HTTPNames::init();
+        base::TestSuite testSuite(argc, argv);
 
-            base::TestSuite testSuite(argc, argv);
+        mojo::edk::Init();
+        base::TestIOThread testIoThread(base::TestIOThread::kAutoStart);
+        WTF::OwnPtr<mojo::edk::test::ScopedIPCSupport> ipcSupport(adoptPtr(new mojo::edk::test::ScopedIPCSupport(testIoThread.task_runner())));
+        result = base::LaunchUnitTests(argc, argv, base::Bind(runTestSuite, base::Unretained(&testSuite)));
 
-            mojo::edk::Init();
-            base::TestIOThread testIoThread(base::TestIOThread::kAutoStart);
-            WTF::OwnPtr<mojo::edk::test::ScopedIPCSupport> ipcSupport(adoptPtr(new mojo::edk::test::ScopedIPCSupport(testIoThread.task_runner())));
-            result = base::LaunchUnitTests(argc, argv, base::Bind(runTestSuite, base::Unretained(&testSuite)));
-
-            blink::ThreadState::detachMainThread();
-            blink::Heap::shutdown();
-        }
-        blink::Platform::shutdown();
+        blink::ThreadState::detachMainThread();
+        blink::Heap::shutdown();
     }
-
+    blink::CompositorFactory::shutdown();
     WTF::shutdown();
     WTF::Partitions::shutdown();
     return result;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
index 0db8693..dfe9817 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
@@ -148,7 +148,7 @@
 PassOwnPtr<V8DebuggerAgent> V8DebuggerAgent::create(V8RuntimeAgent* runtimeAgent, int contextGroupId)
 {
     V8RuntimeAgentImpl* runtimeAgentImpl = static_cast<V8RuntimeAgentImpl*>(runtimeAgent);
-    return adoptPtr(new V8DebuggerAgentImpl(runtimeAgentImpl->injectedScriptManager(), runtimeAgentImpl->debugger(), contextGroupId));
+    return adoptPtr(new V8DebuggerAgentImpl(runtimeAgentImpl->getInjectedScriptManager(), runtimeAgentImpl->debugger(), contextGroupId));
 }
 
 V8DebuggerAgentImpl::V8DebuggerAgentImpl(InjectedScriptManager* injectedScriptManager, V8DebuggerImpl* debugger, int contextGroupId)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
index 683a2f3..d6225c5a 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
@@ -48,7 +48,7 @@
         int contextId = V8Debugger::contextId(object->CreationContext());
         if (!contextId)
             return "";
-        InjectedScript* injectedScript = m_runtimeAgent->injectedScriptManager()->findInjectedScript(contextId);
+        InjectedScript* injectedScript = m_runtimeAgent->getInjectedScriptManager()->findInjectedScript(contextId);
         if (!injectedScript)
             return "";
         String16 name = injectedScript->origin().latin1Data();
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h
index 30ba32be..92318f4 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h
@@ -110,7 +110,7 @@
         Maybe<protocol::Runtime::ExceptionDetails>*) override;
 
     V8DebuggerImpl* debugger() { return m_debugger; }
-    InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager.get(); }
+    InjectedScriptManager* getInjectedScriptManager() { return m_injectedScriptManager.get(); }
 
     void setClearConsoleCallback(PassOwnPtr<ClearConsoleCallback>) override;
     void setInspectObjectCallback(PassOwnPtr<InspectCallback>) override;
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
index e2e82f9..60b805e 100644
--- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -764,7 +764,7 @@
 {
     // TODO(jbroman): This doesn't handle OOPIF correctly. We probably need a
     // branch for WebFrameWidget, like attachRootGraphicsLayer.
-    m_webView->paintArtifactCompositor().update(paintArtifact);
+    m_webView->getPaintArtifactCompositor().update(paintArtifact);
 }
 
 void ChromeClientImpl::attachCompositorAnimationTimeline(CompositorAnimationTimeline* compositorTimeline, LocalFrame* localRoot)
diff --git a/third_party/WebKit/Source/web/ExternalPopupMenu.cpp b/third_party/WebKit/Source/web/ExternalPopupMenu.cpp
index 2b89766..2e2275b 100644
--- a/third_party/WebKit/Source/web/ExternalPopupMenu.cpp
+++ b/third_party/WebKit/Source/web/ExternalPopupMenu.cpp
@@ -260,8 +260,8 @@
     }
 
     const ComputedStyle& menuStyle = ownerElement.computedStyle() ? *ownerElement.computedStyle() : *ownerElement.ensureComputedStyle();
-    info.itemHeight = menuStyle.font().fontMetrics().height();
-    info.itemFontSize = static_cast<int>(menuStyle.font().fontDescription().computedSize());
+    info.itemHeight = menuStyle.font().getFontMetrics().height();
+    info.itemFontSize = static_cast<int>(menuStyle.font().getFontDescription().computedSize());
     info.selectedIndex = toExternalPopupMenuItemIndex(ownerElement.optionToListIndex(ownerElement.selectedIndex()), ownerElement);
     info.rightAligned = menuStyle.direction() == RTL;
     info.allowMultipleSelection = ownerElement.multiple();
diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
index 4ac562a..11da846 100644
--- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
+++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp
@@ -594,7 +594,7 @@
     WebFrameClient::NavigationPolicyInfo navigationInfo(wrappedResourceRequest);
     navigationInfo.navigationType = static_cast<WebNavigationType>(type);
     navigationInfo.defaultPolicy = static_cast<WebNavigationPolicy>(policy);
-    navigationInfo.extraData = ds ? ds->extraData() : nullptr;
+    navigationInfo.extraData = ds ? ds->getExtraData() : nullptr;
     navigationInfo.replacesCurrentHistoryItem = replacesCurrentHistoryItem;
     navigationInfo.isHistoryNavigationInNewChildFrame = isHistoryNavigationInNewChildFrame;
     navigationInfo.isClientRedirect = isClientRedirect;
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp
index 3d380b7..b53fd0f 100644
--- a/third_party/WebKit/Source/web/InspectorOverlay.cpp
+++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -386,7 +386,7 @@
     if (!view)
         return;
 
-    IntRect visibleRectInDocument = view->scrollableArea()->visibleContentRect();
+    IntRect visibleRectInDocument = view->getScrollableArea()->visibleContentRect();
     IntSize viewportSize = m_webViewImpl->page()->frameHost().visualViewport().size();
     toLocalFrame(overlayPage()->mainFrame())->view()->resize(viewportSize);
     overlayPage()->frameHost().visualViewport().setSize(viewportSize);
diff --git a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
index 39da22b..edb360a0 100644
--- a/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
+++ b/third_party/WebKit/Source/web/LinkHighlightImpl.cpp
@@ -271,7 +271,7 @@
     paint.setStyle(SkPaint::kFill_Style);
     paint.setFlags(SkPaint::kAntiAlias_Flag);
     paint.setColor(m_node->layoutObject()->style()->tapHighlightColor().rgb());
-    canvas->drawPath(m_path.skPath(), paint);
+    canvas->drawPath(m_path.getSkPath(), paint);
 
     RefPtr<const SkPicture> picture = adoptRef(recorder.endRecording());
     webDisplayItemList->appendDrawingItem(WebRect(visualRect.x(), visualRect.y(), visualRect.width(), visualRect.height()), picture.get());
diff --git a/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp b/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
index 0a121eb..05ce3f23 100644
--- a/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
+++ b/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
@@ -86,14 +86,14 @@
     // Shouldn't crash.
     webViewImpl->enableTapHighlightAtPoint(getTargetedEvent(webViewImpl, touchEvent));
 
-    EXPECT_TRUE(webViewImpl->linkHighlight(0));
-    EXPECT_TRUE(webViewImpl->linkHighlight(0)->contentLayer());
-    EXPECT_TRUE(webViewImpl->linkHighlight(0)->clipLayer());
+    EXPECT_TRUE(webViewImpl->getLinkHighlight(0));
+    EXPECT_TRUE(webViewImpl->getLinkHighlight(0)->contentLayer());
+    EXPECT_TRUE(webViewImpl->getLinkHighlight(0)->clipLayer());
 
     // Find a target inside a scrollable div
     touchEvent.y = 100;
     webViewImpl->enableTapHighlightAtPoint(getTargetedEvent(webViewImpl, touchEvent));
-    ASSERT_TRUE(webViewImpl->linkHighlight(0));
+    ASSERT_TRUE(webViewImpl->getLinkHighlight(0));
 
     // Don't highlight if no "hand cursor"
     touchEvent.y = 220; // An A-link with cross-hair cursor.
@@ -151,11 +151,11 @@
     ASSERT_TRUE(touchNode);
 
     webViewImpl->enableTapHighlightAtPoint(targetedEvent);
-    ASSERT_TRUE(webViewImpl->linkHighlight(0));
+    ASSERT_TRUE(webViewImpl->getLinkHighlight(0));
 
-    GraphicsLayer* highlightLayer = webViewImpl->linkHighlight(0)->currentGraphicsLayerForTesting();
+    GraphicsLayer* highlightLayer = webViewImpl->getLinkHighlight(0)->currentGraphicsLayerForTesting();
     ASSERT_TRUE(highlightLayer);
-    EXPECT_TRUE(highlightLayer->linkHighlight(0));
+    EXPECT_TRUE(highlightLayer->getLinkHighlight(0));
 
     touchNode->remove(IGNORE_EXCEPTION);
     webViewImpl->updateAllLifecyclePhases();
@@ -192,11 +192,11 @@
     ASSERT_TRUE(touchNode);
 
     webViewImpl->enableTapHighlightAtPoint(targetedEvent);
-    ASSERT_TRUE(webViewImpl->linkHighlight(0));
+    ASSERT_TRUE(webViewImpl->getLinkHighlight(0));
 
-    GraphicsLayer* highlightLayer = webViewImpl->linkHighlight(0)->currentGraphicsLayerForTesting();
+    GraphicsLayer* highlightLayer = webViewImpl->getLinkHighlight(0)->currentGraphicsLayerForTesting();
     ASSERT_TRUE(highlightLayer);
-    EXPECT_TRUE(highlightLayer->linkHighlight(0));
+    EXPECT_TRUE(highlightLayer->getLinkHighlight(0));
 
     // Mimic the logic from RenderWidget::Close:
     webViewImpl->willCloseLayerTreeView();
diff --git a/third_party/WebKit/Source/web/PageOverlayTest.cpp b/third_party/WebKit/Source/web/PageOverlayTest.cpp
index 3869698..935ae39 100644
--- a/third_party/WebKit/Source/web/PageOverlayTest.cpp
+++ b/third_party/WebKit/Source/web/PageOverlayTest.cpp
@@ -127,7 +127,7 @@
     IntRect intRect = rect;
     graphicsLayer->paint(&intRect);
 
-    PaintController& paintController = graphicsLayer->paintController();
+    PaintController& paintController = graphicsLayer->getPaintController();
     GraphicsContext graphicsContext(paintController);
     graphicsContext.beginRecording(intRect);
     paintController.paintArtifact().replay(graphicsContext);
diff --git a/third_party/WebKit/Source/web/PopupMenuImpl.cpp b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
index 93373ab..30e34d7b 100644
--- a/third_party/WebKit/Source/web/PopupMenuImpl.cpp
+++ b/third_party/WebKit/Source/web/PopupMenuImpl.cpp
@@ -205,7 +205,7 @@
     // Do not use baseStyle() for background-color, use backgroundColor()
     // instead.
     const ComputedStyle& baseStyle() { return m_isInGroup ? *m_groupStyle : m_baseStyle; }
-    const FontDescription& baseFont() { return m_isInGroup ? m_groupStyle->fontDescription() : m_baseStyle.fontDescription(); }
+    const FontDescription& baseFont() { return m_isInGroup ? m_groupStyle->getFontDescription() : m_baseStyle.getFontDescription(); }
     void startGroupChildren(const ComputedStyle& groupStyle)
     {
         ASSERT(!m_isInGroup);
@@ -325,7 +325,7 @@
     if (context.backgroundColor() != backgroundColor && backgroundColor != Color::transparent)
         addProperty("backgroundColor", backgroundColor.serialized(), data);
     const FontDescription& baseFont = context.baseFont();
-    const FontDescription& fontDescription = style->font().fontDescription();
+    const FontDescription& fontDescription = style->font().getFontDescription();
     if (baseFont.computedPixelSize() != fontDescription.computedPixelSize()) {
         // We don't use FontDescription::specifiedSize() because this element
         // might have its own zoom level.
diff --git a/third_party/WebKit/Source/web/ResizeViewportAnchor.cpp b/third_party/WebKit/Source/web/ResizeViewportAnchor.cpp
index 0be18f6..8c79f08 100644
--- a/third_party/WebKit/Source/web/ResizeViewportAnchor.cpp
+++ b/third_party/WebKit/Source/web/ResizeViewportAnchor.cpp
@@ -14,13 +14,13 @@
 
 ResizeViewportAnchor::ResizeViewportAnchor(FrameView& rootFrameView, VisualViewport& visualViewport)
     : ViewportAnchor(rootFrameView, visualViewport)
-    , m_visualViewportInDocument(rootFrameView.scrollableArea()->visibleContentRectDouble().location())
+    , m_visualViewportInDocument(rootFrameView.getScrollableArea()->visibleContentRectDouble().location())
 {
 }
 
 ResizeViewportAnchor::~ResizeViewportAnchor()
 {
-    m_rootFrameView->scrollableArea()->setScrollPosition(m_visualViewportInDocument, ProgrammaticScroll);
+    m_rootFrameView->getScrollableArea()->setScrollPosition(m_visualViewportInDocument, ProgrammaticScroll);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/web/RotationViewportAnchor.cpp b/third_party/WebKit/Source/web/RotationViewportAnchor.cpp
index edb62e9..674c933 100644
--- a/third_party/WebKit/Source/web/RotationViewportAnchor.cpp
+++ b/third_party/WebKit/Source/web/RotationViewportAnchor.cpp
@@ -101,13 +101,13 @@
     // FIXME: Scroll offsets are now fractional (DoublePoint and FloatPoint for the FrameView and VisualViewport
     //        respectively. This path should be rewritten without pixel snapping.
     IntRect outerViewRect = m_rootFrameView->layoutViewportScrollableArea()->visibleContentRect(IncludeScrollbars);
-    IntRect innerViewRect = enclosedIntRect(m_rootFrameView->scrollableArea()->visibleContentRectDouble());
+    IntRect innerViewRect = enclosedIntRect(m_rootFrameView->getScrollableArea()->visibleContentRectDouble());
 
     m_oldPageScaleFactor = m_visualViewport->scale();
     m_oldMinimumPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().minimumScale;
 
     // Save the absolute location in case we won't find the anchor node, we'll fall back to that.
-    m_visualViewportInDocument = FloatPoint(m_rootFrameView->scrollableArea()->visibleContentRectDouble().location());
+    m_visualViewportInDocument = FloatPoint(m_rootFrameView->getScrollableArea()->visibleContentRectDouble().location());
 
     m_anchorNode.clear();
     m_anchorNodeBounds = LayoutRect();
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
index 283ccca..08eff3f 100644
--- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
+++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
@@ -56,7 +56,9 @@
 #include "modules/serviceworkers/ExtendableMessageEvent.h"
 #include "modules/serviceworkers/FetchEvent.h"
 #include "modules/serviceworkers/InstallEvent.h"
+#include "modules/serviceworkers/ServiceWorkerClient.h"
 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h"
+#include "modules/serviceworkers/ServiceWorkerWindowClient.h"
 #include "modules/serviceworkers/WaitUntilObserver.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "public/platform/WebCrossOriginServiceWorkerClient.h"
@@ -102,18 +104,39 @@
     workerGlobalScope()->dispatchExtendableEvent(event.release(), observer);
 }
 
-void ServiceWorkerGlobalScopeProxy::dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebMessagePortChannelArray& webChannels)
+void ServiceWorkerGlobalScopeProxy::dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebSecurityOrigin& sourceOrigin, const WebMessagePortChannelArray& webChannels, const WebServiceWorkerClientInfo& client)
 {
     ASSERT(RuntimeEnabledFeatures::serviceWorkerExtendableMessageEventEnabled());
 
     WebSerializedScriptValue value = WebSerializedScriptValue::fromString(message);
     MessagePortArray* ports = MessagePort::toMessagePortArray(m_workerGlobalScope, webChannels);
-    // TODO(nhiroki): Support |origin| and |source| attributes.
-    // (http://crbug.com/543198)
-
+    String origin;
+    if (!sourceOrigin.isUnique())
+        origin = sourceOrigin.toString();
+    ServiceWorkerClient* source = nullptr;
+    if (client.clientType == WebServiceWorkerClientTypeWindow)
+        source = ServiceWorkerWindowClient::create(client);
+    else
+        source = ServiceWorkerClient::create(client);
     WaitUntilObserver* observer = WaitUntilObserver::create(workerGlobalScope(), WaitUntilObserver::Message, eventID);
 
-    RefPtrWillBeRawPtr<Event> event(ExtendableMessageEvent::create(value, String(), ports, observer));
+    RefPtrWillBeRawPtr<Event> event(ExtendableMessageEvent::create(value, origin, ports, source, observer));
+    workerGlobalScope()->dispatchExtendableEvent(event.release(), observer);
+}
+
+void ServiceWorkerGlobalScopeProxy::dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebSecurityOrigin& sourceOrigin, const WebMessagePortChannelArray& webChannels, WebPassOwnPtr<WebServiceWorker::Handle> handle)
+{
+    ASSERT(RuntimeEnabledFeatures::serviceWorkerExtendableMessageEventEnabled());
+
+    WebSerializedScriptValue value = WebSerializedScriptValue::fromString(message);
+    MessagePortArray* ports = MessagePort::toMessagePortArray(m_workerGlobalScope, webChannels);
+    String origin;
+    if (!sourceOrigin.isUnique())
+        origin = sourceOrigin.toString();
+    ServiceWorker* source = ServiceWorker::from(m_workerGlobalScope->getExecutionContext(), handle.release());
+    WaitUntilObserver* observer = WaitUntilObserver::create(workerGlobalScope(), WaitUntilObserver::Message, eventID);
+
+    RefPtrWillBeRawPtr<Event> event(ExtendableMessageEvent::create(value, origin, ports, source, observer));
     workerGlobalScope()->dispatchExtendableEvent(event.release(), observer);
 }
 
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h
index e1fd8162..c84e358 100644
--- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h
+++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h
@@ -75,7 +75,8 @@
     void setRegistration(WebPassOwnPtr<WebServiceWorkerRegistration::Handle>) override;
     void dispatchActivateEvent(int) override;
     void dispatchCrossOriginMessageEvent(const WebCrossOriginServiceWorkerClient&, const WebString& message, const WebMessagePortChannelArray&) override;
-    void dispatchExtendableMessageEvent(int, const WebString& message, const WebMessagePortChannelArray&) override;
+    void dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebSecurityOrigin& sourceOrigin, const WebMessagePortChannelArray&, const WebServiceWorkerClientInfo&) override;
+    void dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebSecurityOrigin& sourceOrigin, const WebMessagePortChannelArray&, WebPassOwnPtr<WebServiceWorker::Handle>) override;
     void dispatchFetchEvent(int, const WebServiceWorkerRequest&) override;
     void dispatchForeignFetchEvent(int, const WebServiceWorkerRequest&) override;
     void dispatchGeofencingEvent(int, WebGeofencingEventType, const WebString& regionID, const WebCircularGeofencingRegion&) override;
diff --git a/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp b/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp
index 131393e..1774c10 100644
--- a/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ValidationMessageClientImpl.cpp
@@ -73,7 +73,7 @@
         hideValidationMessage(*m_currentAnchor);
     m_currentAnchor = &anchor;
     IntRect anchorInViewport = currentView()->contentsToViewport(anchor.pixelSnappedBoundingBox());
-    m_lastAnchorRectInScreen = currentView()->hostWindow()->viewportToScreen(anchorInViewport);
+    m_lastAnchorRectInScreen = currentView()->getHostWindow()->viewportToScreen(anchorInViewport);
     m_lastPageScaleFactor = m_webView.pageScaleFactor();
     m_message = message;
     const double minimumSecondToShowValidationMessage = 5.0;
@@ -132,7 +132,7 @@
         return;
     }
 
-    IntRect newAnchorRectInViewportInScreen = currentView()->hostWindow()->viewportToScreen(newAnchorRectInViewport);
+    IntRect newAnchorRectInViewportInScreen = currentView()->getHostWindow()->viewportToScreen(newAnchorRectInViewport);
     if (newAnchorRectInViewportInScreen == m_lastAnchorRectInScreen && m_webView.pageScaleFactor() == m_lastPageScaleFactor)
         return;
     m_lastAnchorRectInScreen = newAnchorRectInViewportInScreen;
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp
index 9576037..658656ee 100644
--- a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp
+++ b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp
@@ -95,7 +95,7 @@
     return toWebNavigationType(DocumentLoader::getNavigationType());
 }
 
-WebDataSource::ExtraData* WebDataSourceImpl::extraData() const
+WebDataSource::ExtraData* WebDataSourceImpl::getExtraData() const
 {
     return m_extraData.get();
 }
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.h b/third_party/WebKit/Source/web/WebDataSourceImpl.h
index b948d879..035385fb 100644
--- a/third_party/WebKit/Source/web/WebDataSourceImpl.h
+++ b/third_party/WebKit/Source/web/WebDataSourceImpl.h
@@ -63,7 +63,7 @@
     bool isClientRedirect() const override;
     bool replacesCurrentHistoryItem() const override;
     WebNavigationType navigationType() const override;
-    ExtraData* extraData() const override;
+    ExtraData* getExtraData() const override;
     void setExtraData(ExtraData*) override;
     void setNavigationStartTime(double) override;
 
diff --git a/third_party/WebKit/Source/web/WebKit.cpp b/third_party/WebKit/Source/web/WebKit.cpp
index 73141c0..c5a10a9 100644
--- a/third_party/WebKit/Source/web/WebKit.cpp
+++ b/third_party/WebKit/Source/web/WebKit.cpp
@@ -30,34 +30,22 @@
 
 #include "public/web/WebKit.h"
 
-#include "bindings/core/v8/ScriptStreamerThread.h"
 #include "bindings/core/v8/V8Binding.h"
 #include "bindings/core/v8/V8GCController.h"
 #include "bindings/core/v8/V8Initializer.h"
 #include "core/Init.h"
 #include "core/animation/AnimationClock.h"
 #include "core/dom/Microtask.h"
-#include "core/fetch/WebCacheMemoryDumpProvider.h"
-#include "core/frame/Settings.h"
 #include "core/page/Page.h"
-#include "core/workers/WorkerGlobalScopeProxy.h"
 #include "gin/public/v8_platform.h"
 #include "modules/InitModules.h"
-#include "platform/Histogram.h"
 #include "platform/LayoutTestSupport.h"
 #include "platform/Logging.h"
-#include "platform/RuntimeEnabledFeatures.h"
-#include "platform/ThreadSafeFunctional.h"
-#include "platform/fonts/FontCacheMemoryDumpProvider.h"
-#include "platform/graphics/ImageDecodingStore.h"
-#include "platform/heap/GCTaskRunner.h"
 #include "platform/heap/Heap.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebPrerenderingSupport.h"
 #include "public/platform/WebThread.h"
 #include "web/IndexedDBClientImpl.h"
 #include "wtf/Assertions.h"
-#include "wtf/CryptographicallyRandomNumber.h"
 #include "wtf/MainThread.h"
 #include "wtf/Partitions.h"
 #include "wtf/WTF.h"
@@ -86,11 +74,6 @@
 } // namespace
 
 static WebThread::TaskObserver* s_endOfTaskRunner = nullptr;
-static GCTaskRunner* s_gcTaskRunner = nullptr;
-
-// Make sure we are not re-initialized in the same address space.
-// Doing so may cause hard to reproduce crashes.
-static bool s_webKitInitialized = false;
 
 static ModulesInitializer& modulesInitializer()
 {
@@ -100,7 +83,7 @@
 
 void initialize(Platform* platform)
 {
-    initializeWithoutV8(platform);
+    Platform::initialize(platform);
 
     modulesInitializer().init();
     setIndexedDBClientCreateFunction(IndexedDBClientImpl::create);
@@ -112,10 +95,6 @@
         ASSERT(!s_endOfTaskRunner);
         s_endOfTaskRunner = new EndOfTaskRunner;
         currentThread->addTaskObserver(s_endOfTaskRunner);
-
-        // Register web cache dump provider for tracing.
-        platform->registerMemoryDumpProvider(WebCacheMemoryDumpProvider::instance(), "MemoryCache");
-        platform->registerMemoryDumpProvider(FontCacheMemoryDumpProvider::instance(), "FontCaches");
     }
 }
 
@@ -124,47 +103,10 @@
     return V8PerIsolateData::mainThreadIsolate();
 }
 
-static void maxObservedSizeFunction(size_t sizeInMB)
-{
-    const size_t supportedMaxSizeInMB = 4 * 1024;
-    if (sizeInMB >= supportedMaxSizeInMB)
-        sizeInMB = supportedMaxSizeInMB - 1;
-
-    // Send a UseCounter only when we see the highest memory usage
-    // we've ever seen.
-    DEFINE_STATIC_LOCAL(EnumerationHistogram, committedSizeHistogram, ("PartitionAlloc.CommittedSize", supportedMaxSizeInMB));
-    committedSizeHistogram.count(sizeInMB);
-}
-
-static void callOnMainThreadFunction(WTF::MainThreadFunction function, void* context)
-{
-    Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(function, AllowCrossThreadAccess(context)));
-}
-
-static void adjustAmountOfExternalAllocatedMemory(int size)
-{
-    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size);
-}
-
+// TODO(haraken): Remove this function.
 void initializeWithoutV8(Platform* platform)
 {
-    ASSERT(!s_webKitInitialized);
-    s_webKitInitialized = true;
-
-    WTF::Partitions::initialize(maxObservedSizeFunction);
-    WTF::initialize(adjustAmountOfExternalAllocatedMemory);
-    WTF::initializeMainThread(callOnMainThreadFunction);
-
-    ASSERT(platform);
     Platform::initialize(platform);
-    Heap::init();
-
-    ThreadState::attachMainThread();
-    // currentThread() is null if we are running on a thread without a message loop.
-    if (WebThread* currentThread = platform->currentThread()) {
-        ASSERT(!s_gcTaskRunner);
-        s_gcTaskRunner = new GCTaskRunner(currentThread);
-    }
 }
 
 void shutdown()
@@ -188,9 +130,6 @@
 
     // currentThread() is null if we are running on a thread without a message loop.
     if (Platform::current()->currentThread()) {
-        Platform::current()->unregisterMemoryDumpProvider(WebCacheMemoryDumpProvider::instance());
-        Platform::current()->unregisterMemoryDumpProvider(FontCacheMemoryDumpProvider::instance());
-
         // We don't need to (cannot) remove s_endOfTaskRunner from the current
         // message loop, because the message loop is already destructed before
         // the shutdown() is called.
@@ -202,30 +141,13 @@
 
     modulesInitializer().shutdown();
 
-    shutdownWithoutV8();
+    Platform::shutdown();
 }
 
+// TODO(haraken): Remove this function.
 void shutdownWithoutV8()
 {
-    ASSERT(isMainThread());
-    // currentThread() is null if we are running on a thread without a message loop.
-    if (Platform::current()->currentThread()) {
-        ASSERT(s_gcTaskRunner);
-        delete s_gcTaskRunner;
-        s_gcTaskRunner = nullptr;
-    }
-
-    // Detach the main thread before starting the shutdown sequence
-    // so that the main thread won't get involved in a GC during the shutdown.
-    ThreadState::detachMainThread();
-
-    ASSERT(!s_endOfTaskRunner);
-    Heap::shutdown();
     Platform::shutdown();
-
-    WTF::shutdown();
-    WebPrerenderingSupport::shutdown();
-    WTF::Partitions::shutdown();
 }
 
 // TODO(tkent): The following functions to wrap LayoutTestSupport should be
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 99081bb..6e4f6621 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -964,8 +964,8 @@
             setPageScaleFactor(newScale);
 
             FrameView* view = mainFrameImpl()->frameView();
-            if (view && view->scrollableArea())
-                view->scrollableArea()->setScrollPosition(DoublePoint(clampedPoint.x, clampedPoint.y), ProgrammaticScroll);
+            if (view && view->getScrollableArea())
+                view->getScrollableArea()->setScrollPosition(DoublePoint(clampedPoint.x, clampedPoint.y), ProgrammaticScroll);
 
             return false;
         }
@@ -4553,7 +4553,7 @@
     // TODO(jbroman): This should probably have hookups for overlays, visual
     // viewport, etc.
 
-    WebLayer* rootLayer = m_paintArtifactCompositor.webLayer();
+    WebLayer* rootLayer = m_paintArtifactCompositor.getWebLayer();
     ASSERT(rootLayer);
     m_layerTreeView->setRootLayer(*rootLayer);
 
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h
index e6d5b2cf..cacaf39 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.h
+++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -495,7 +495,7 @@
 
     // Exposed for tests.
     unsigned numLinkHighlights() { return m_linkHighlights.size(); }
-    LinkHighlightImpl* linkHighlight(int i) { return m_linkHighlights[i].get(); }
+    LinkHighlightImpl* getLinkHighlight(int i) { return m_linkHighlights[i].get(); }
 
     WebSettingsImpl* settingsImpl();
 
@@ -532,7 +532,7 @@
     void detachPaintArtifactCompositor();
 
     // Use in Slimming Paint v2 to update the layer tree for the content.
-    PaintArtifactCompositor& paintArtifactCompositor() { return m_paintArtifactCompositor; }
+    PaintArtifactCompositor& getPaintArtifactCompositor() { return m_paintArtifactCompositor; }
 
     bool isTransparent() const;
     void setIsTransparent(bool value);
diff --git a/third_party/WebKit/Source/web/WebViewImplPaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/web/WebViewImplPaintArtifactCompositorTest.cpp
index fe594f13..ec3446d 100644
--- a/third_party/WebKit/Source/web/WebViewImplPaintArtifactCompositorTest.cpp
+++ b/third_party/WebKit/Source/web/WebViewImplPaintArtifactCompositorTest.cpp
@@ -57,7 +57,7 @@
 
     MockWebLayerTreeView& webLayerTreeView() { return m_webLayerTreeView; }
     WebViewImpl& webViewImpl() { return *m_helper.webViewImpl(); }
-    PaintArtifactCompositor& paintArtifactCompositor() { return webViewImpl().paintArtifactCompositor(); }
+    PaintArtifactCompositor& getPaintArtifactCompositor() { return webViewImpl().getPaintArtifactCompositor(); }
 
 private:
     RuntimeEnabledFeatures::Backup m_featuresBackup;
@@ -68,7 +68,7 @@
 
 TEST_F(WebViewImplPaintArtifactCompositorTest, AttachAndDetach)
 {
-    cc::Layer* rootLayer = paintArtifactCompositor().rootLayer();
+    cc::Layer* rootLayer = getPaintArtifactCompositor().rootLayer();
     ASSERT_TRUE(rootLayer);
 
     EXPECT_CALL(webLayerTreeView(), setRootLayer(Property(&WebLayer::ccLayer, rootLayer)));
diff --git a/third_party/WebKit/Source/web/mac/WebSubstringUtil.mm b/third_party/WebKit/Source/web/mac/WebSubstringUtil.mm
index e0045ac..af5d327 100644
--- a/third_party/WebKit/Source/web/mac/WebSubstringUtil.mm
+++ b/third_party/WebKit/Source/web/mac/WebSubstringUtil.mm
@@ -86,7 +86,7 @@
         // to use the font.
         // TODO(shuchen): Support scaling the font as necessary according to CSS transforms.
         if (!font || floor(fontPlatformData.size()) != floor([[font fontDescriptor] pointSize]))
-            font = [NSFont systemFontOfSize:style->font().fontDescription().computedSize()];
+            font = [NSFont systemFontOfSize:style->font().getFontDescription().computedSize()];
         [attrs setObject:font forKey:NSFontAttributeName];
 
         if (style->visitedDependentColor(CSSPropertyColor).alpha())
diff --git a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
index cffad59..afe0aff7 100644
--- a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
@@ -415,7 +415,7 @@
     ASSERT(compositedLayerMapping->scrollingContentsLayer());
 
     GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
-    ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());
+    ASSERT_EQ(box->layer()->getScrollableArea(), graphicsLayer->getScrollableArea());
 
     WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
     ASSERT_TRUE(webScrollLayer->scrollable());
@@ -455,7 +455,7 @@
     ASSERT(compositedLayerMapping->scrollingContentsLayer());
 
     GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
-    ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());
+    ASSERT_EQ(box->layer()->getScrollableArea(), graphicsLayer->getScrollableArea());
 
     WebLayer* webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
     ASSERT_TRUE(webScrollLayer->scrollable());
@@ -470,7 +470,7 @@
     ASSERT_TRUE(layoutObject->hasLayer());
 
     box = toLayoutBox(layoutObject);
-    ASSERT_TRUE(box->scrollableArea()->usesCompositedScrolling());
+    ASSERT_TRUE(box->getScrollableArea()->usesCompositedScrolling());
     ASSERT_EQ(PaintsIntoOwnBacking, box->layer()->compositingState());
 
     compositedLayerMapping = box->layer()->compositedLayerMapping();
@@ -478,7 +478,7 @@
     ASSERT(compositedLayerMapping->scrollingContentsLayer());
 
     graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
-    ASSERT_EQ(box->layer()->scrollableArea(), graphicsLayer->scrollableArea());
+    ASSERT_EQ(box->layer()->getScrollableArea(), graphicsLayer->getScrollableArea());
 
     webScrollLayer = compositedLayerMapping->scrollingContentsLayer()->platformLayer();
     ASSERT_TRUE(webScrollLayer->scrollable());
@@ -516,7 +516,7 @@
     ASSERT_TRUE(innerCompositor->scrollLayer());
 
     GraphicsLayer* scrollLayer = innerCompositor->scrollLayer();
-    ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea());
+    ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea());
 
     WebLayer* webScrollLayer = scrollLayer->platformLayer();
     ASSERT_TRUE(webScrollLayer->scrollable());
@@ -560,7 +560,7 @@
     ASSERT_TRUE(innerCompositor->scrollLayer());
 
     GraphicsLayer* scrollLayer = innerCompositor->scrollLayer();
-    ASSERT_EQ(innerFrameView, scrollLayer->scrollableArea());
+    ASSERT_EQ(innerFrameView, scrollLayer->getScrollableArea());
 
     WebLayer* webScrollLayer = scrollLayer->platformLayer();
     ASSERT_TRUE(webScrollLayer->scrollable());
diff --git a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
index f8b02f28..e6a39ff 100644
--- a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
@@ -206,7 +206,7 @@
     // initialize top controls to be shown and position page at 100px.
     webView->setTopControlsHeight(50.f, true);
     webView->topControls().setShownRatio(1);
-    frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
+    frame()->view()->getScrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
 
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
     EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
@@ -244,7 +244,7 @@
     // initialize top controls to be hidden and position page at 100px.
     webView->setTopControlsHeight(50.f, false);
     webView->topControls().setShownRatio(0);
-    frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
+    frame()->view()->getScrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
 
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
     EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
@@ -302,12 +302,12 @@
     // Top controls should be scrolled partially and page should not scroll.
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20.f));
     EXPECT_FLOAT_EQ(30.f, webView->topControls().contentOffset());
-    EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollableArea()->scrollPositionDouble());
+    EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->getScrollableArea()->scrollPositionDouble());
 
     // Top controls should consume 30px and become hidden. Excess scroll should be consumed by the page at 2x scale.
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -70.f));
     EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
-    EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
+    EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->getScrollableArea()->scrollPositionDouble());
 
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollEnd));
 
@@ -316,16 +316,16 @@
 
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
     EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
-    EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
+    EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->getScrollableArea()->scrollPositionDouble());
 
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 50.f));
     EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
-    EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
+    EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->getScrollableArea()->scrollPositionDouble());
 
     // At 0.5x scale scrolling 10px should take us to the top of the page.
     webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 10.f));
     EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
-    EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollableArea()->scrollPositionDouble());
+    EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->getScrollableArea()->scrollPositionDouble());
 }
 
 // Some scroll deltas result in a shownRatio that can't be realized in a
@@ -358,7 +358,7 @@
     WebViewImpl* webView = initialize("overflow-scrolling.html");
     webView->setTopControlsHeight(50.f, true);
     webView->topControls().setShownRatio(1);
-    frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll);
+    frame()->view()->getScrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll);
 
     // Test scroll down
     // Scroll down should scroll the overflow div first but top controls and main frame should not scroll.
@@ -400,7 +400,7 @@
     WebViewImpl* webView = initialize("iframe-scrolling.html");
     webView->setTopControlsHeight(50.f, true);
     webView->topControls().setShownRatio(1);
-    frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll);
+    frame()->view()->getScrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll);
 
     // Test scroll down
     // Scroll down should scroll the iframe first but top controls and main frame should not scroll.
@@ -463,7 +463,7 @@
     WebViewImpl* webView = initialize();
     webView->setTopControlsHeight(0, false);
     webView->topControls().setShownRatio(0);
-    frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
+    frame()->view()->getScrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
 
     EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
 
@@ -517,7 +517,7 @@
 {
     WebViewImpl* webView = initialize();
     webView->setTopControlsHeight(50.f, false);
-    frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
+    frame()->view()->getScrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
 
     // Setting permitted state should not change content offset
     webView->updateTopControlsState(WebTopControlsShown, WebTopControlsShown, false);
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
index 4a777bf..439e73a 100644
--- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -265,18 +265,18 @@
     ASSERT_POINT_EQ(FloatPoint(400, 300), visualViewport.location());
     ASSERT_POINT_EQ(DoublePoint(200, 1400), frameView.layoutViewportScrollableArea()->scrollPositionDouble());
 
-    DoublePoint expectedLocation = frameView.scrollableArea()->visibleContentRectDouble().location();
+    DoublePoint expectedLocation = frameView.getScrollableArea()->visibleContentRectDouble().location();
 
     // Shrink the WebView, this should cause both viewports to shrink and
     // WebView should do whatever it needs to do to preserve the visible
     // location.
     webViewImpl()->resize(IntSize(700, 550));
 
-    EXPECT_POINT_EQ(expectedLocation, frameView.scrollableArea()->visibleContentRectDouble().location());
+    EXPECT_POINT_EQ(expectedLocation, frameView.getScrollableArea()->visibleContentRectDouble().location());
 
     webViewImpl()->resize(IntSize(800, 600));
 
-    EXPECT_POINT_EQ(expectedLocation, frameView.scrollableArea()->visibleContentRectDouble().location());
+    EXPECT_POINT_EQ(expectedLocation, frameView.getScrollableArea()->visibleContentRectDouble().location());
 }
 
 
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
index e2dc25c..edbb1270 100644
--- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -567,7 +567,7 @@
     {
     }
 
-    WebLayer* webLayer() const { return m_layer.get(); }
+    WebLayer* getWebLayer() const { return m_layer.get(); }
 
     // WebPlugin
 
@@ -622,12 +622,12 @@
     container->paint(graphicsContext, CullRect(IntRect(10, 10, 400, 300)));
     paintController->commitNewDisplayItems();
 
-    const auto& displayItems = paintController->paintArtifact().displayItemList();
+    const auto& displayItems = paintController->paintArtifact().getDisplayItemList();
     ASSERT_EQ(1u, displayItems.size());
     EXPECT_EQ(element->layoutObject(), &displayItems[0].client());
     ASSERT_EQ(DisplayItem::ForeignLayerPlugin, displayItems[0].getType());
     const auto& foreignLayerDisplayItem = static_cast<const ForeignLayerDisplayItem&>(displayItems[0]);
-    EXPECT_EQ(plugin->webLayer()->ccLayer(), foreignLayerDisplayItem.layer());
+    EXPECT_EQ(plugin->getWebLayer()->ccLayer(), foreignLayerDisplayItem.layer());
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/web/tests/WebURLRequestTest.cpp b/third_party/WebKit/Source/web/tests/WebURLRequestTest.cpp
index 1796138..388d5a9 100644
--- a/third_party/WebKit/Source/web/tests/WebURLRequestTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebURLRequestTest.cpp
@@ -58,15 +58,15 @@
 
         urlRequest.initialize();
         urlRequest.setExtraData(extraData);
-        EXPECT_EQ(extraData, urlRequest.extraData());
+        EXPECT_EQ(extraData, urlRequest.getExtraData());
         {
             WebURLRequest otherUrlRequest = urlRequest;
             EXPECT_TRUE(alive);
-            EXPECT_EQ(extraData, otherUrlRequest.extraData());
-            EXPECT_EQ(extraData, urlRequest.extraData());
+            EXPECT_EQ(extraData, otherUrlRequest.getExtraData());
+            EXPECT_EQ(extraData, urlRequest.getExtraData());
         }
         EXPECT_TRUE(alive);
-        EXPECT_EQ(extraData, urlRequest.extraData());
+        EXPECT_EQ(extraData, urlRequest.getExtraData());
     }
     EXPECT_FALSE(alive);
 }
diff --git a/third_party/WebKit/Source/web/tests/WebURLResponseTest.cpp b/third_party/WebKit/Source/web/tests/WebURLResponseTest.cpp
index 95f7e23d..81dcff68 100644
--- a/third_party/WebKit/Source/web/tests/WebURLResponseTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebURLResponseTest.cpp
@@ -58,15 +58,15 @@
 
         urlResponse.initialize();
         urlResponse.setExtraData(extraData);
-        EXPECT_EQ(extraData, urlResponse.extraData());
+        EXPECT_EQ(extraData, urlResponse.getExtraData());
         {
             WebURLResponse otherUrlResponse = urlResponse;
             EXPECT_TRUE(alive);
-            EXPECT_EQ(extraData, otherUrlResponse.extraData());
-            EXPECT_EQ(extraData, urlResponse.extraData());
+            EXPECT_EQ(extraData, otherUrlResponse.getExtraData());
+            EXPECT_EQ(extraData, urlResponse.getExtraData());
         }
         EXPECT_TRUE(alive);
-        EXPECT_EQ(extraData, urlResponse.extraData());
+        EXPECT_EQ(extraData, urlResponse.getExtraData());
     }
     EXPECT_FALSE(alive);
 }
diff --git a/third_party/WebKit/Source/wtf/ArrayBufferContents.h b/third_party/WebKit/Source/wtf/ArrayBufferContents.h
index 3050379..cc768c9 100644
--- a/third_party/WebKit/Source/wtf/ArrayBufferContents.h
+++ b/third_party/WebKit/Source/wtf/ArrayBufferContents.h
@@ -29,6 +29,7 @@
 
 #include "wtf/Allocator.h"
 #include "wtf/Assertions.h"
+#include "wtf/MainThread.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/RefPtr.h"
 #include "wtf/ThreadSafeRefCounted.h"
@@ -37,6 +38,8 @@
 
 namespace WTF {
 
+typedef void(*AdjustAmountOfExternalAllocatedMemoryFunction)(int size);
+
 class WTF_EXPORT ArrayBufferContents {
     WTF_MAKE_NONCOPYABLE(ArrayBufferContents);
     DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
@@ -76,8 +79,9 @@
     static void allocateMemory(size_t, InitializationPolicy, void*&);
     static void allocateMemoryOrNull(size_t, InitializationPolicy, void*&);
     static void freeMemory(void*, size_t);
-    static void setAdjustAmoutOfExternalAllocatedMemoryFunction(AdjustAmountOfExternalAllocatedMemoryFunction function)
+    static void initialize(AdjustAmountOfExternalAllocatedMemoryFunction function)
     {
+        ASSERT(isMainThread());
         ASSERT(!s_adjustAmountOfExternalAllocatedMemoryFunction);
         s_adjustAmountOfExternalAllocatedMemoryFunction = function;
     }
diff --git a/third_party/WebKit/Source/wtf/TypeTraits.h b/third_party/WebKit/Source/wtf/TypeTraits.h
index c6a05230..4b9fef3 100644
--- a/third_party/WebKit/Source/wtf/TypeTraits.h
+++ b/third_party/WebKit/Source/wtf/TypeTraits.h
@@ -106,14 +106,41 @@
     static const bool value = IsTriviallyCopyAssignable<T>::value;
 };
 
+// Same as above, but for __has_trivial_constructor and __has_trivial_destructor. For IsTriviallyDefaultConstructible,
+// we don't have to write IsDefaultConstructible ourselves since we can use std::is_constructible<T>. For
+// IsTriviallyDestructible, though, we can't rely on std::is_destructible<T> right now.
+#if !COMPILER(MSVC) || COMPILER(CLANG)
+template <typename T>
+class IsDestructible {
+    typedef char YesType;
+    struct NoType {
+        char padding[8];
+    };
+
+    template <typename T2, typename = decltype(std::declval<T2>().~T2())>
+    static YesType checkDestructibility(int);
+    template <typename T2>
+    static NoType checkDestructibility(...);
+
+public:
+    static const bool value = sizeof(checkDestructibility<T>(0)) == sizeof(YesType);
+};
+#endif
+
 template <typename T> struct IsTriviallyDefaultConstructible {
-    // TODO(yutak): Below has the same issue as crbug.com/592767.
+#if COMPILER(MSVC) && !COMPILER(CLANG)
     static const bool value = __has_trivial_constructor(T);
+#else
+    static const bool value = __has_trivial_constructor(T) && std::is_constructible<T>::value;
+#endif
 };
 
 template <typename T> struct IsTriviallyDestructible {
-    // TODO(yutak): Ditto.
+#if COMPILER(MSVC) && !COMPILER(CLANG)
     static const bool value = __has_trivial_destructor(T);
+#else
+    static const bool value = __has_trivial_destructor(T) && IsDestructible<T>::value;
+#endif
 };
 
 template <typename T, typename U> struct IsSubclass {
diff --git a/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp b/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp
index 79fddfc..165ec0d 100644
--- a/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp
+++ b/third_party/WebKit/Source/wtf/TypeTraitsTest.cpp
@@ -164,6 +164,22 @@
 
 #endif // !COMPILER(MSVC) || COMPILER(CLANG)
 
+class DefaultConstructorDeleted final {
+private:
+    DefaultConstructorDeleted() = delete;
+};
+
+class DestructorDeleted final {
+private:
+    ~DestructorDeleted() = delete;
+};
+
+static_assert(!IsTriviallyDefaultConstructible<DefaultConstructorDeleted>::value,
+    "DefaultConstructorDeleted must not be trivially default constructible.");
+
+static_assert(!IsTriviallyDestructible<DestructorDeleted>::value,
+    "DestructorDeleted must not be trivially destructible.");
+
 } // anonymous namespace
 
 } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/WTF.cpp b/third_party/WebKit/Source/wtf/WTF.cpp
index f762cb6..f999ca2 100644
--- a/third_party/WebKit/Source/wtf/WTF.cpp
+++ b/third_party/WebKit/Source/wtf/WTF.cpp
@@ -41,14 +41,13 @@
 bool s_initialized;
 bool s_shutdown;
 
-void initialize(AdjustAmountOfExternalAllocatedMemoryFunction adjustAmountOfExternalAllocatedMemoryFunction)
+void initialize()
 {
     // WTF, and Blink in general, cannot handle being re-initialized, even if shutdown first.
     // Make that explicit here.
     RELEASE_ASSERT(!s_initialized);
     RELEASE_ASSERT(!s_shutdown);
     s_initialized = true;
-    ArrayBufferContents::setAdjustAmoutOfExternalAllocatedMemoryFunction(adjustAmountOfExternalAllocatedMemoryFunction);
     initializeThreading();
 }
 
diff --git a/third_party/WebKit/Source/wtf/WTF.h b/third_party/WebKit/Source/wtf/WTF.h
index 81f00eb..0a542b2b 100644
--- a/third_party/WebKit/Source/wtf/WTF.h
+++ b/third_party/WebKit/Source/wtf/WTF.h
@@ -36,10 +36,8 @@
 
 namespace WTF {
 
-typedef void(*AdjustAmountOfExternalAllocatedMemoryFunction)(int size);
-
 // This function must be called exactly once from the main thread before using anything else in WTF.
-WTF_EXPORT void initialize(AdjustAmountOfExternalAllocatedMemoryFunction);
+WTF_EXPORT void initialize();
 WTF_EXPORT void shutdown();
 WTF_EXPORT bool isShutdown();
 
diff --git a/third_party/WebKit/Source/wtf/testing/RunAllTests.cpp b/third_party/WebKit/Source/wtf/testing/RunAllTests.cpp
index c342f60..1ed14a8 100644
--- a/third_party/WebKit/Source/wtf/testing/RunAllTests.cpp
+++ b/third_party/WebKit/Source/wtf/testing/RunAllTests.cpp
@@ -45,7 +45,7 @@
 {
     WTF::Partitions::initialize(nullptr);
     WTF::setTimeFunctionsForTesting(dummyCurrentTime);
-    WTF::initialize(nullptr);
+    WTF::initialize();
     WTF::initializeMainThread(0);
     return base::RunUnitTestsUsingBaseTestSuite(argc, argv);
 }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
index 0cdf0ce..5d5f8ee 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
@@ -265,10 +265,12 @@
             raise ScriptError(message="Can't find a branch to diff against. %s does not exist" % remote_master_ref)
         return remote_master_ref
 
-    def commit_locally_with_message(self, message, commit_all_working_directory_changes=True):
+    def commit_locally_with_message(self, message, commit_all_working_directory_changes=True, author=None):
         command = ['commit', '-F', '-']
         if commit_all_working_directory_changes:
             command.insert(1, '--all')
+        if author:
+            command.insert(1, "--author='%s'" % (author))
         self._run_git(command, input=message)
 
     # These methods are git specific and are meant to provide support for the Git oriented workflow
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
index 4f208411..bb3c8ad 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
@@ -136,6 +136,6 @@
     def supports_local_commits():
         SCM._subclass_must_implement()
 
-    def commit_locally_with_message(self, message, commit_all_working_directory_changes=True):
+    def commit_locally_with_message(self, message, commit_all_working_directory_changes=True, author=None):
         _log.error("Your source control manager does not support local commits.")
         sys.exit(1)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
index 5bdaa5d..57fbbed 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
@@ -38,6 +38,7 @@
         self.added_paths = set()
         self._filesystem = filesystem or MockFileSystem()
         self._executive = executive or MockExecutive()
+        self._local_commits = []
 
     def add(self, destination_path, return_exit_code=False):
         self.add_list([destination_path], return_exit_code)
@@ -91,9 +92,15 @@
     def timestamp_of_revision(self, path, revision):
         return '2013-02-01 08:48:05 +0000'
 
-    def commit_locally_with_message(self, message, commit_all_working_directory_changes=True):
+    def commit_locally_with_message(self, message, commit_all_working_directory_changes=True, author=None):
+        self._local_commits.append([message, commit_all_working_directory_changes, author])
         pass
 
+    def local_commits(self):
+        """For testing purposes, returns the internal recording of commits made via commit_locally_with_message.
+        Format as [ message, commit_all_working_directory_changes, author ]."""
+        return self._local_commits
+
     def delete(self, path):
         return self.delete_list([path])
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_win.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_win.py
index 20d1702..850db9097 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_win.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/breakpad/dump_reader_win.py
@@ -86,6 +86,8 @@
             '%s\\Windows Kits\\8.0\\Debuggers\\x64',
             '%s\\Windows Kits\\8.1\\Debuggers\\x86',
             '%s\\Windows Kits\\8.1\\Debuggers\\x64',
+            '%s\\Windows Kits\\10\\Debuggers\\x86',
+            '%s\\Windows Kits\\10\\Debuggers\\x64',
         ]
 
         program_files_directories = ['C:\\Program Files']
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
index da2f098..0ceb3b3 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
@@ -515,7 +515,7 @@
 
         _log.debug("Uploading JSON files for builder: %s", self._options.builder_name)
         attrs = [("builder", self._options.builder_name),
-                 ("testtype", "webkit_tests"),
+                 ("testtype", self._options.step_name),
                  ("master", self._options.master_name)]
 
         files = [(file, self._filesystem.join(self._results_directory, file)) for file in ["failing_results.json", "full_results.json", "times_ms.json"]]
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index b355e556..ba0ee99f 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -85,207 +85,374 @@
 def parse_args(args):
     option_group_definitions = []
 
-    option_group_definitions.append(("Platform options", platform_options()))
-    option_group_definitions.append(("Configuration options", configuration_options()))
-    option_group_definitions.append(("Printing Options", printing.print_options()))
+    option_group_definitions.append(
+        ("Platform options", platform_options()))
 
-    option_group_definitions.append(("Android-specific Options", [
-        optparse.make_option("--adb-device",
-            action="append", default=[],
-            help="Run Android layout tests on these devices."),
+    option_group_definitions.append(
+        ("Configuration options", configuration_options()))
 
-        # FIXME: Flip this to be off by default once we can log the device setup more cleanly.
-        optparse.make_option("--no-android-logging",
-            action="store_false", dest='android_logging', default=True,
-            help="Do not log android-specific debug messages (default is to log as part of --debug-rwt-logging"),
-    ]))
+    option_group_definitions.append(
+        ("Printing Options", printing.print_options()))
 
-    option_group_definitions.append(("Results Options", [
-        optparse.make_option("--add-platform-exceptions", action="store_true", default=False,
-            help="Save generated results into the *most-specific-platform* directory rather than the *generic-platform* directory"),
-        optparse.make_option("--additional-driver-flag", "--additional-drt-flag", action="append", dest="additional_driver_flag",
-            default=[], help="Additional command line flag to pass to the driver "
-                 "Specify multiple times to add multiple flags."),
-        optparse.make_option("--additional-expectations", action="append", default=[],
-            help="Path to a test_expectations file that will override previous expectations. "
-                 "Specify multiple times for multiple sets of overrides."),
-        optparse.make_option("--additional-platform-directory", action="append",
-            default=[], help="Additional directory where to look for test "
-                 "baselines (will take precedence over platform baselines). "
-                 "Specify multiple times to add multiple search path entries."),
-        optparse.make_option("--build-directory",
-            help="Path to the directory under which build files are kept (should not include configuration)"),
-        optparse.make_option("--clobber-old-results", action="store_true",
-            default=False, help="Clobbers test results from previous runs."),
-        optparse.make_option("--compare-port", action="store", default=None,
-            help="Use the specified port's baselines first"),
-        optparse.make_option("--driver-name", type="string",
-            help="Alternative driver binary to use"),
-        optparse.make_option("--full-results-html", action="store_true",
-            default=False,
-            help="Show all failures in results.html, rather than only regressions"),
-        optparse.make_option("--new-baseline", action="store_true",
-            default=False, help="Save generated results as new baselines "
-                 "into the *most-specific-platform* directory, overwriting whatever's "
-                 "already there. Equivalent to --reset-results --add-platform-exceptions"),
+    option_group_definitions.append(
+        ("Android-specific Options", [
+            optparse.make_option(
+                "--adb-device",
+                action="append",
+                default=[],
+                help="Run Android layout tests on these devices."),
+            # FIXME: Flip this to be off by default once we can log the
+            # device setup more cleanly.
+            optparse.make_option(
+                "--no-android-logging",
+                dest="android_logging",
+                action="store_false",
+                default=True,
+                help=("Do not log android-specific debug messages (default is to log as part "
+                      "of --debug-rwt-logging")),
+        ]))
 
-        # TODO(ojan): Remove once bots stop using it.
-        optparse.make_option("--no-new-test-results",
-            help="This doesn't do anything. TODO(ojan): Remove once bots stop using it."),
+    option_group_definitions.append(
+        ("Results Options", [
+            optparse.make_option(
+                "--add-platform-exceptions",
+                action="store_true",
+                default=False,
+                help=("Save generated results into the *most-specific-platform* directory rather "
+                      "than the *generic-platform* directory")),
+            optparse.make_option(
+                "--additional-driver-flag",
+                "--additional-drt-flag",
+                dest="additional_driver_flag",
+                action="append",
+                default=[],
+                help=("Additional command line flag to pass to the driver. Specify multiple "
+                      "times to add multiple flags.")),
+            optparse.make_option(
+                "--additional-expectations",
+                action="append",
+                default=[],
+                help=("Path to a test_expectations file that will override previous "
+                      "expectations. Specify multiple times for multiple sets of overrides.")),
+            optparse.make_option(
+                "--additional-platform-directory",
+                action="append",
+                default=[],
+                help=("Additional directory where to look for test baselines (will take "
+                      "precedence over platform baselines). Specify multiple times to add "
+                      "multiple search path entries.")),
+            optparse.make_option(
+                "--build-directory",
+                help=("Path to the directory under which build files are kept (should not "
+                      "include configuration)")),
+            optparse.make_option(
+                "--clobber-old-results",
+                action="store_true",
+                default=False,
+                help="Clobbers test results from previous runs."),
+            optparse.make_option(
+                "--compare-port",
+                action="store",
+                default=None,
+                help="Use the specified port's baselines first"),
+            optparse.make_option(
+                "--driver-name",
+                type="string",
+                help="Alternative driver binary to use"),
+            optparse.make_option(
+                "--full-results-html",
+                action="store_true",
+                default=False,
+                help="Show all failures in results.html, rather than only regressions"),
+            optparse.make_option(
+                "--new-baseline",
+                action="store_true",
+                default=False,
+                help=("Save generated results as new baselines into the *most-specific-platform* "
+                      "directory, overwriting whatever's already there. Equivalent to "
+                      "--reset-results --add-platform-exceptions")),
+            # TODO(ojan): Remove once bots stop using it.
+            optparse.make_option(
+                "--no-new-test-results",
+                help="This doesn't do anything. TODO(ojan): Remove once bots stop using it."),
+            optparse.make_option(
+                "--new-test-results",
+                action="store_true",
+                default=False,
+                help="Create new baselines when no expected results exist"),
+            optparse.make_option(
+                "--no-show-results",
+                dest="show_results",
+                action="store_false",
+                default=True,
+                help="Don't launch a browser with results after the tests are done"),
+            optparse.make_option(
+                "-p",
+                "--pixel",
+                "--pixel-tests",
+                dest="pixel_tests",
+                action="store_true",
+                help="Enable pixel-to-pixel PNG comparisons"),
+            optparse.make_option(
+                "--no-pixel",
+                "--no-pixel-tests",
+                dest="pixel_tests",
+                action="store_false",
+                help="Disable pixel-to-pixel PNG comparisons"),
+            # FIXME: we should support a comma separated list with
+            # --pixel-test-directory as well.
+            optparse.make_option(
+                "--pixel-test-directory",
+                dest="pixel_test_directories",
+                action="append",
+                default=[],
+                help=("A directory where it is allowed to execute tests as pixel tests. Specify "
+                      "multiple times to add multiple directories. This option implies "
+                      "--pixel-tests. If specified, only those tests will be executed as pixel "
+                      "tests that are located in one of the" " directories enumerated with the "
+                      "option. Some ports may ignore this option while others can have a default "
+                      "value that can be overridden here.")),
+            optparse.make_option(
+                "--reset-results",
+                action="store_true",
+                default=False,
+                help="Reset expectations to the generated results in their existing location."),
+            optparse.make_option(
+                "--results-directory",
+                help="Location of test results"),
+            optparse.make_option(
+                "--skip-failing-tests",
+                action="store_true",
+                default=False,
+                help=("Skip tests that are expected to fail. Note: When using this option, "
+                      "you might miss new crashes in these tests.")),
+            optparse.make_option(
+                "--smoke",
+                action="store_true",
+                help="Run just the SmokeTests"),
+            optparse.make_option(
+                "--no-smoke",
+                dest="smoke",
+                action="store_false",
+                help="Do not run just the SmokeTests"),
+        ]))
 
-        optparse.make_option("--new-test-results", action="store_true",
-            default=False,
-            help="Create new baselines when no expected results exist"),
+    option_group_definitions.append(
+        ("Testing Options", [
+            optparse.make_option(
+                "--additional-env-var",
+                type="string",
+                action="append",
+                default=[],
+                help=("Passes that environment variable to the tests "
+                      "(--additional-env-var=NAME=VALUE)")),
+            optparse.make_option(
+                "--batch-size",
+                type="int",
+                default=None,
+                help=("Run a the tests in batches (n), after every n tests, the driver is "
+                      "relaunched.")),
+            optparse.make_option(
+                "--build",
+                dest="build",
+                action="store_true",
+                default=True,
+                help=("Check to ensure the build is up-to-date (default).")),
+            optparse.make_option(
+                "--no-build",
+                dest="build",
+                action="store_false",
+                help="Don't check to see if the build is up-to-date."),
+            optparse.make_option(
+                "--child-processes",
+                help="Number of drivers to run in parallel."),
+            optparse.make_option(
+                "--enable-wptserve",
+                dest="enable_wptserve",
+                action="store_true",
+                default=False,
+                help="Enable running web-platform-tests using WPTserve instead of Apache."),
+            optparse.make_option(
+                "--disable-breakpad",
+                action="store_true",
+                help="Don't use breakpad to symbolize unexpected crashes."),
+            optparse.make_option(
+                "--driver-logging",
+                action="store_true",
+                help="Print detailed logging of the driver/content_shell"),
+            optparse.make_option(
+                "--enable-leak-detection",
+                action="store_true",
+                help="Enable the leak detection of DOM objects."),
+            optparse.make_option(
+                "--enable-sanitizer",
+                action="store_true",
+                help="Only alert on sanitizer-related errors and crashes"),
+            optparse.make_option(
+                "--exit-after-n-crashes-or-timeouts",
+                type="int",
+                default=None,
+                help="Exit after the first N crashes instead of running all tests"),
+            optparse.make_option(
+                "--exit-after-n-failures",
+                type="int",
+                default=None,
+                help="Exit after the first N failures instead of running all tests"),
+            optparse.make_option(
+                "--ignore-builder-category",
+                action="store",
+                help=("The category of builders to use with the --ignore-flaky-tests option "
+                      "('layout' or 'deps').")),
+            optparse.make_option(
+                "--ignore-flaky-tests",
+                action="store",
+                help=("Control whether tests that are flaky on the bots get ignored. "
+                      "'very-flaky' == Ignore any tests that flaked more than once on the bot. "
+                      "'maybe-flaky' == Ignore any tests that flaked once on the bot. "
+                      "'unexpected' == Ignore any tests that had unexpected results on the bot.")),
+            optparse.make_option(
+                "--iterations",
+                type="int",
+                default=1,
+                help="Number of times to run the set of tests (e.g. ABCABCABC)"),
+            optparse.make_option(
+                "--max-locked-shards",
+                type="int",
+                default=0,
+                help="Set the maximum number of locked shards"),
+            optparse.make_option(
+                "--nocheck-sys-deps",
+                action="store_true",
+                default=False,
+                help="Don't check the system dependencies (themes)"),
+            optparse.make_option(
+                "--order",
+                action="store",
+                default="natural",
+                help=("determine the order in which the test cases will be run. "
+                      "'none' == use the order in which the tests were listed "
+                      "either in arguments or test list, "
+                      "'natural' == use the natural order (default), "
+                      "'random-seeded' == randomize the test order using a fixed seed, "
+                      "'random' == randomize the test order.")),
+            optparse.make_option(
+                "--profile",
+                action="store_true",
+                help="Output per-test profile information."),
+            optparse.make_option(
+                "--profiler",
+                action="store",
+                help="Output per-test profile information, using the specified profiler."),
+            optparse.make_option(
+                "--repeat-each",
+                type="int",
+                default=1,
+                help="Number of times to run each test (e.g. AAABBBCCC)"),
+            # TODO(joelo): Delete --retry-failures and --no-retry-failures as they
+            # are redundant with --num-retries.
+            optparse.make_option(
+                "--retry-failures",
+                action="store_true",
+                help=("Re-try any tests that produce unexpected results. Default is to not retry "
+                      "if an explicit list of tests is passed to run-webkit-tests.")),
+            optparse.make_option(
+                "--no-retry-failures",
+                dest="retry_failures",
+                action="store_false",
+                help="Don't re-try any tests that produce unexpected results."),
+            optparse.make_option(
+                "--num-retries",
+                type="int",
+                default=3,
+                help=("Number of times to retry failures, default is 3. Only relevant when "
+                      "failure retries are enabled.")),
+            optparse.make_option(
+                "--run-chunk",
+                help="Run a specified chunk (n:l), the nth of len l, of the layout tests"),
+            optparse.make_option(
+                "--run-part",
+                help="Run a specified part (n:m), the nth of m parts, of the layout tests"),
+            optparse.make_option(
+                "--run-singly",
+                action="store_true",
+                default=False,
+                help="DEPRECATED, same as --batch-size=1 --verbose"),
+            optparse.make_option(
+                "--skipped",
+                action="store",
+                default=None,
+                help=("control how tests marked SKIP are run. "
+                      "'default' == Skip tests unless explicitly listed on the command line, "
+                      "'ignore' == Run them anyway, "
+                      "'only' == only run the SKIP tests, "
+                      "'always' == always skip, even if listed on the command line.")),
+            optparse.make_option(
+                "--fastest",
+                action="store",
+                type="float",
+                help="Run the N% fastest tests as well as any tests listed on the command line"),
+            optparse.make_option(
+                "--test-list",
+                action="append",
+                metavar="FILE",
+                help="read list of tests to run from file"),
+            optparse.make_option(
+                "--time-out-ms",
+                help="Set the timeout for each test"),
+            optparse.make_option(
+                "--wrapper",
+                help=("wrapper command to insert before invocations of the driver; option "
+                      "is split on whitespace before running. (Example: --wrapper='valgrind "
+                      "--smc-check=all')")),
+            # FIXME: Display default number of child processes that will run.
+            optparse.make_option(
+                "-f", "--fully-parallel",
+                action="store_true",
+                help="run all tests in parallel"),
+            optparse.make_option(
+                "-i", "--ignore-tests",
+                action="append",
+                default=[],
+                help="directories or test to ignore (may specify multiple times)"),
+            optparse.make_option(
+                "-n", "--dry-run",
+                action="store_true",
+                default=False,
+                help="Do everything but actually run the tests or upload results."),
+        ]))
 
-        optparse.make_option("--no-show-results", action="store_false",
-            default=True, dest="show_results",
-            help="Don't launch a browser with results after the tests "
-                 "are done"),
-        optparse.make_option("-p", "--pixel", "--pixel-tests", action="store_true",
-            dest="pixel_tests", help="Enable pixel-to-pixel PNG comparisons"),
-        optparse.make_option("--no-pixel", "--no-pixel-tests", action="store_false",
-            dest="pixel_tests", help="Disable pixel-to-pixel PNG comparisons"),
-
-        #FIXME: we should support a comma separated list with --pixel-test-directory as well.
-        optparse.make_option("--pixel-test-directory", action="append", default=[], dest="pixel_test_directories",
-            help="A directory where it is allowed to execute tests as pixel tests. "
-                 "Specify multiple times to add multiple directories. "
-                 "This option implies --pixel-tests. If specified, only those tests "
-                 "will be executed as pixel tests that are located in one of the "
-                 "directories enumerated with the option. Some ports may ignore this "
-                 "option while others can have a default value that can be overridden here."),
-
-        optparse.make_option("--reset-results", action="store_true",
-            default=False, help="Reset expectations to the "
-                 "generated results in their existing location."),
-        optparse.make_option("--results-directory", help="Location of test results"),
-        optparse.make_option("--skip-failing-tests", action="store_true",
-            default=False, help="Skip tests that are expected to fail. "
-                 "Note: When using this option, you might miss new crashes "
-                 "in these tests."),
-        optparse.make_option("--smoke", action="store_true",
-            help="Run just the SmokeTests"),
-        optparse.make_option("--no-smoke", dest="smoke", action="store_false",
-            help="Do not run just the SmokeTests"),
-    ]))
-
-    option_group_definitions.append(("Testing Options", [
-        optparse.make_option("--additional-env-var", type="string", action="append", default=[],
-            help="Passes that environment variable to the tests (--additional-env-var=NAME=VALUE)"),
-        optparse.make_option("--batch-size",
-            help=("Run a the tests in batches (n), after every n tests, "
-                  "the driver is relaunched."), type="int", default=None),
-        optparse.make_option("--build", dest="build",
-            action="store_true", default=True,
-            help="Check to ensure the build is up-to-date (default)."),
-        optparse.make_option("--no-build", dest="build",
-            action="store_false", help="Don't check to see if the build is up-to-date."),
-        optparse.make_option("--child-processes",
-            help="Number of drivers to run in parallel."),
-        optparse.make_option("--enable-wptserve", dest="enable_wptserve",
-                             action="store_true", default=False,
-                             help="Enable running web-platform-tests using "
-                                  "WPTserve instead of Apache."),
-        optparse.make_option("--disable-breakpad", action="store_true",
-            help="Don't use breakpad to symbolize unexpected crashes."),
-        optparse.make_option("--driver-logging", action="store_true",
-            help="Print detailed logging of the driver/content_shell"),
-        optparse.make_option("--enable-leak-detection", action="store_true",
-            help="Enable the leak detection of DOM objects."),
-        optparse.make_option("--enable-sanitizer", action="store_true",
-            help="Only alert on sanitizer-related errors and crashes"),
-        optparse.make_option("--exit-after-n-crashes-or-timeouts", type="int",
-            default=None, help="Exit after the first N crashes instead of "
-            "running all tests"),
-        optparse.make_option("--exit-after-n-failures", type="int", default=None,
-            help="Exit after the first N failures instead of running all "
-            "tests"),
-        optparse.make_option("--ignore-builder-category", action="store",
-            help=("The category of builders to use with the --ignore-flaky-tests "
-                "option ('layout' or 'deps').")),
-        optparse.make_option("--ignore-flaky-tests", action="store",
-            help=("Control whether tests that are flaky on the bots get ignored."
-                "'very-flaky' == Ignore any tests that flaked more than once on the bot."
-                "'maybe-flaky' == Ignore any tests that flaked once on the bot."
-                "'unexpected' == Ignore any tests that had unexpected results on the bot.")),
-        optparse.make_option("--iterations", type="int", default=1, help="Number of times to run the set of tests (e.g. ABCABCABC)"),
-        optparse.make_option("--max-locked-shards", type="int", default=0,
-            help="Set the maximum number of locked shards"),
-        optparse.make_option("--nocheck-sys-deps", action="store_true",
-            default=False,
-            help="Don't check the system dependencies (themes)"),
-        optparse.make_option("--order", action="store", default="natural",
-            help=("determine the order in which the test cases will be run. "
-                  "'none' == use the order in which the tests were listed either in arguments or test list, "
-                  "'natural' == use the natural order (default), "
-                  "'random-seeded' == randomize the test order using a fixed seed, "
-                  "'random' == randomize the test order.")),
-        optparse.make_option("--profile", action="store_true",
-            help="Output per-test profile information."),
-        optparse.make_option("--profiler", action="store",
-            help="Output per-test profile information, using the specified profiler."),
-        optparse.make_option("--repeat-each", type="int", default=1, help="Number of times to run each test (e.g. AAABBBCCC)"),
-        # TODO(joelo): Delete --retry-failures and --no-retry-failures as they
-        # are redundant with --num-retries.
-        optparse.make_option("--retry-failures", action="store_true",
-            help="Re-try any tests that produce unexpected results. Default is to not retry if an explicit list of tests is passed to run-webkit-tests."),
-        optparse.make_option("--no-retry-failures", action="store_false", dest="retry_failures",
-                             help="Don't re-try any tests that produce unexpected results."),
-        optparse.make_option("--num-retries", type="int", default=3,
-                             help=("Number of times to retry failures, default is 3. "
-                                   "Only relevant when failure retries are enabled.")),
-        optparse.make_option("--run-chunk",
-            help=("Run a specified chunk (n:l), the nth of len l, "
-                 "of the layout tests")),
-        optparse.make_option("--run-part", help=("Run a specified part (n:m), "
-                  "the nth of m parts, of the layout tests")),
-        optparse.make_option("--run-singly", action="store_true",
-            default=False, help="DEPRECATED, same as --batch-size=1 --verbose"),
-        optparse.make_option("--skipped", action="store", default=None,
-            help=("control how tests marked SKIP are run. "
-                 "'default' == Skip tests unless explicitly listed on the command line, "
-                 "'ignore' == Run them anyway, "
-                 "'only' == only run the SKIP tests, "
-                 "'always' == always skip, even if listed on the command line.")),
-        optparse.make_option('--fastest', action='store', type='float',
-                             help='Run the N% fastest tests as well as any '
-                                  'tests listed on the command line'),
-        optparse.make_option("--test-list", action="append",
-            help="read list of tests to run from file", metavar="FILE"),
-        optparse.make_option("--time-out-ms",
-            help="Set the timeout for each test"),
-        optparse.make_option("--wrapper",
-            help="wrapper command to insert before invocations of "
-                 "the driver; option is split on whitespace before "
-                 "running. (Example: --wrapper='valgrind --smc-check=all')"),
-        # FIXME: Display default number of child processes that will run.
-        optparse.make_option("-f", "--fully-parallel", action="store_true",
-            help="run all tests in parallel"),
-        optparse.make_option("-i", "--ignore-tests", action="append", default=[],
-            help="directories or test to ignore (may specify multiple times)"),
-        optparse.make_option("-n", "--dry-run", action="store_true",
-            default=False,
-            help="Do everything but actually run the tests or upload results."),
-    ]))
-
-    # FIXME: Move these into json_results_generator.py
-    option_group_definitions.append(("Result JSON Options", [
-        optparse.make_option("--build-name", default="DUMMY_BUILD_NAME",
-            help=("The name of the builder used in its path, e.g. "
-                  "webkit-rel.")),
-        optparse.make_option("--build-number", default="DUMMY_BUILD_NUMBER",
-            help=("The build number of the builder running this script.")),
-        optparse.make_option("--builder-name", default="",
-            help=("The name of the builder shown on the waterfall running "
-                  "this script e.g. WebKit.")),
-        optparse.make_option("--master-name", help="The name of the buildbot master."),
-        optparse.make_option("--test-results-server", default="",
-            help=("If specified, upload results json files to this appengine "
-                  "server.")),
-        optparse.make_option("--write-full-results-to",
-            help=("If specified, copy full_results.json from the results dir "
-                  "to the specified path.")),
-    ]))
+    # FIXME: Move these into json_results_generator.py.
+    option_group_definitions.append(
+        ("Result JSON Options", [
+            optparse.make_option(
+                "--build-name",
+                default="DUMMY_BUILD_NAME",
+                help="The name of the builder used in its path, e.g. webkit-rel."),
+            optparse.make_option(
+                "--step-name",
+                default="webkit_tests",
+                help="The name of the step in a build running this script."),
+            optparse.make_option(
+                "--build-number",
+                default="DUMMY_BUILD_NUMBER",
+                help="The build number of the builder running this script."),
+            optparse.make_option(
+                "--builder-name",
+                default="",
+                help=("The name of the builder shown on the waterfall running this script "
+                      "e.g. WebKit.")),
+            optparse.make_option(
+                "--master-name",
+                help="The name of the buildbot master."),
+            optparse.make_option(
+                "--test-results-server",
+                default="",
+                help="If specified, upload results json files to this appengine server."),
+            optparse.make_option(
+                "--write-full-results-to",
+                help=("If specified, copy full_results.json from the results dir to the "
+                      "specified path.")),
+        ]))
 
     option_parser = optparse.OptionParser()
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
index fd94a5f..ce39fe5a 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -446,6 +446,10 @@
             for builder in self._builders_to_fetch_from(test_prefix_list[test]):
                 all_suffixes.update(self._suffixes_for_actual_failures(test, builder, test_prefix_list[test][builder]))
 
+            # No need to optimize baselines for a test with no failures.
+            if not all_suffixes:
+                continue
+
             # FIXME: We should propagate the platform options as well.
             cmd_line = ['--no-modify-scm', '--suffixes', ','.join(all_suffixes), test]
             if verbose:
@@ -501,6 +505,9 @@
                 SKIP not in generic_expectations.get_expectations(test))
 
     def _run_in_parallel_and_update_scm(self, commands):
+        if not commands:
+            return {}
+
         command_results = self._tool.executive.run_in_parallel(commands)
         log_output = '\n'.join(result[2] for result in command_results).replace('\n\n', '\n')
         for line in log_output.split('\n'):
@@ -523,10 +530,8 @@
         copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = self._rebaseline_commands(test_prefix_list, options)
         lines_to_remove = {}
 
-        if copy_baseline_commands:
-            self._run_in_parallel_and_update_scm(copy_baseline_commands)
-        if rebaseline_commands:
-            lines_to_remove = self._run_in_parallel_and_update_scm(rebaseline_commands)
+        self._run_in_parallel_and_update_scm(copy_baseline_commands)
+        lines_to_remove = self._run_in_parallel_and_update_scm(rebaseline_commands)
 
         for test in extra_lines_to_remove:
             if test in lines_to_remove:
@@ -538,6 +543,9 @@
             self._update_expectations_files(lines_to_remove)
 
         if options.optimize:
+            # TODO(wkorman): Consider changing temporary branch to base off of HEAD rather than
+            # origin/master to ensure we run baseline optimization processes with the same code as
+            # auto-rebaseline itself.
             self._run_in_parallel_and_update_scm(self._optimize_baselines(test_prefix_list, options.verbose))
 
     def _suffixes_for_actual_failures(self, test, builder_name, existing_suffixes):
@@ -679,7 +687,25 @@
             # FIXME: Remove this option.
             self.results_directory_option,
             optparse.make_option("--auth-refresh-token-json", help="Rietveld auth refresh JSON token."),
+            optparse.make_option("--commit-author",
+                help='Optionally specify an explicit author for local commit. Format as "Name <email>".'),
+            optparse.make_option("--dry-run", action='store_true', default=False,
+                help='Run without creating a temporary branch, committing locally, or uploading/landing '
+                'changes to the remote repository.')
             ])
+        self._blame_regex = re.compile(r"""
+                ^(\S*)      # Commit hash
+                [^(]* \(    # Whitespace and open parenthesis
+                <           # Email address is surrounded by <>
+                (
+                    [^@]+   # Username preceding @
+                    @
+                    [^@>]+  # Domain terminated by @ or >, some lines have an additional @ fragment after the email.
+                )
+                .*?([^ ]*)  # Test file name
+                \ \[        # Single space followed by opening [ for expectation specifier
+                [^[]*$      # Prevents matching previous [ for version specifiers instead of expectation specifiers
+            """, re.VERBOSE)
 
     def bot_revision_data(self):
         revisions = []
@@ -693,6 +719,12 @@
             })
         return revisions
 
+    def _strip_comments(self, line):
+        comment_index = line.find("#")
+        if comment_index == -1:
+            comment_index = len(line)
+        return re.sub(r"\s+", " ", line[:comment_index].strip())
+
     def tests_to_rebaseline(self, tool, min_revision, print_revisions):
         port = tool.port_factory.get()
         expectations_file_path = port.path_to_generic_test_expectations_file()
@@ -705,30 +737,19 @@
         has_any_needs_rebaseline_lines = False
 
         for line in tool.scm().blame(expectations_file_path).split("\n"):
-            comment_index = line.find("#")
-            if comment_index == -1:
-                comment_index = len(line)
-            line_without_comments = re.sub(r"\s+", " ", line[:comment_index].strip())
-
-            if "NeedsRebaseline" not in line_without_comments:
+            line = self._strip_comments(line)
+            if "NeedsRebaseline" not in line:
                 continue
 
             has_any_needs_rebaseline_lines = True
 
-            pattern = re.compile(r"""
-                ^(\S*)      # Commit hash
-                [^(]* \(    # Whitespace and open paranthesis
-                <           # Email address is surrounded by <>
-                (
-                    [^@]+   # Username preceding @
-                    @
-                    [^@>]+  # Domain terminated by @ or >, some lines have an additional @ fragment after the email.
-                )
-                .*?([^ ]*)  # Test file name
-                \ \[        # Single space followed by opening [ for expectation specifier
-                [^[]*$      # Prevents matching previous [ for version specifiers instead of expectation specifiers
-            """, re.VERBOSE)
-            parsed_line = pattern.match(line_without_comments)
+            parsed_line = self._blame_regex.match(line)
+            if not parsed_line:
+                # Deal gracefully with inability to parse blame info for a line in TestExpectations.
+                # Parsing could fail if for example during local debugging the developer modifies
+                # TestExpectations and does not commit.
+                _log.info("Couldn't find blame info for expectations line, skipping [line=%s]." % line)
+                continue
 
             commit_hash = parsed_line.group(1)
             commit_position = tool.scm().commit_position_from_git_commit(commit_hash)
@@ -748,7 +769,7 @@
                 commit = commit_hash
                 author = parsed_line.group(2)
 
-            bugs.update(re.findall("crbug\.com\/(\d+)", line_without_comments))
+            bugs.update(re.findall("crbug\.com\/(\d+)", line))
             tests.add(test)
 
             if len(tests) >= self.MAX_LINES_TO_REBASELINE:
@@ -833,7 +854,7 @@
             _log.error("Auto rebaseline only works with a git checkout.")
             return
 
-        if tool.scm().has_working_directory_changes():
+        if not options.dry_run and tool.scm().has_working_directory_changes():
             _log.error("Cannot proceed with working directory changes. Clean working directory first.")
             return
 
@@ -861,23 +882,29 @@
 
         test_prefix_list, lines_to_remove = self.get_test_prefix_list(tests)
 
+        did_switch_branches = False
         did_finish = False
         old_branch_name_or_ref = ''
         rebaseline_branch_name = self.AUTO_REBASELINE_BRANCH_NAME
         try:
-            # Save the current branch name and checkout a clean branch for the patch.
+            # Save the current branch name and check out a clean branch for the patch.
             old_branch_name_or_ref = _get_branch_name_or_ref(tool)
             if old_branch_name_or_ref == self.AUTO_REBASELINE_BRANCH_NAME:
                 rebaseline_branch_name = self.AUTO_REBASELINE_ALT_BRANCH_NAME
-            tool.scm().delete_branch(rebaseline_branch_name)
-            tool.scm().create_clean_branch(rebaseline_branch_name)
+            if not options.dry_run:
+                tool.scm().delete_branch(rebaseline_branch_name)
+                tool.scm().create_clean_branch(rebaseline_branch_name)
+                did_switch_branches = True
 
-            # If the tests are passing everywhere, then this list will be empty. We don't need
-            # to rebaseline, but we'll still need to update TestExpectations.
             if test_prefix_list:
                 self._rebaseline(options, test_prefix_list)
 
-            tool.scm().commit_locally_with_message(self.commit_message(author, revision, commit, bugs))
+            if options.dry_run:
+                return
+
+            tool.scm().commit_locally_with_message(
+                self.commit_message(author, revision, commit, bugs),
+                author=options.commit_author)
 
             # FIXME: It would be nice if we could dcommit the patch without uploading, but still
             # go through all the precommit hooks. For rebaselines with lots of files, uploading
@@ -895,18 +922,19 @@
         except:
             traceback.print_exc(file=sys.stderr)
         finally:
-            if did_finish:
-                # Close the issue if dcommit failed.
-                issue_already_closed = tool.executive.run_command(
-                    ['git', 'config', 'branch.%s.rietveldissue' % rebaseline_branch_name],
-                    return_exit_code=True)
-                if not issue_already_closed:
-                    self._run_git_cl_command(options, ['set_close'])
+            if did_switch_branches:
+                if did_finish:
+                    # Close the issue if dcommit failed.
+                    issue_already_closed = tool.executive.run_command(
+                        ['git', 'config', 'branch.%s.rietveldissue' % rebaseline_branch_name],
+                        return_exit_code=True)
+                    if not issue_already_closed:
+                        self._run_git_cl_command(options, ['set_close'])
 
-            tool.scm().ensure_cleanly_tracking_remote_master()
-            if old_branch_name_or_ref:
-                tool.scm().checkout_branch(old_branch_name_or_ref)
-            tool.scm().delete_branch(rebaseline_branch_name)
+                tool.scm().ensure_cleanly_tracking_remote_master()
+                if old_branch_name_or_ref:
+                    tool.scm().checkout_branch(old_branch_name_or_ref)
+                tool.scm().delete_branch(rebaseline_branch_name)
 
 
 class RebaselineOMatic(AbstractDeclarativeCommand):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
index c143504..c7a5b16e 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
@@ -375,9 +375,7 @@
 
         self.command._rebaseline(options,  {"userscripts/first-test.html": {"MOCK builder": ["txt", "png"]}})
 
-        # Note that we have one run_in_parallel() call followed by a run_command()
-        self.assertEqual(self.tool.executive.calls,
-            [[['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', '', 'userscripts/first-test.html', '--verbose']]])
+        self.assertEqual(self.tool.executive.calls, [])
 
     def test_rebaseline_all(self):
         self._setup_mock_builder_data()
@@ -903,6 +901,12 @@
 
         return test_port
 
+    def _execute_command_with_mock_options(self, auth_refresh_token_json=None, commit_author=None, dry_run=False):
+        self.command.execute(MockOptions(
+            optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=auth_refresh_token_json,
+            commit_author=commit_author, dry_run=dry_run),
+            [], self.tool)
+
     def setUp(self):
         super(TestAutoRebaseline, self).setUp()
         self.command.latest_revision_processed_on_all_bots = lambda: 9000
@@ -994,7 +998,7 @@
 """
         self.tool.scm().blame = blame
 
-        self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False), [], self.tool)
+        self._execute_command_with_mock_options()
         self.assertEqual(self.tool.executive.calls, [])
 
     def test_execute(self):
@@ -1066,12 +1070,12 @@
             }
 
             self.command.tree_status = lambda: 'closed'
-            self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=None), [], self.tool)
+            self._execute_command_with_mock_options()
             self.assertEqual(self.tool.executive.calls, [])
 
             self.command.tree_status = lambda: 'open'
             self.tool.executive.calls = []
-            self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=None), [], self.tool)
+            self._execute_command_with_mock_options()
 
             self.assertEqual(self.tool.executive.calls, [
                 [
@@ -1155,7 +1159,7 @@
             self.command.tree_status = lambda: 'open'
             self.tool.executive = MockExecutive()
             self.tool.executive.calls = []
-            self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=None), [], self.tool)
+            self._execute_command_with_mock_options()
 
             self.assertEqual(self.tool.executive.calls, [
                 [
@@ -1215,9 +1219,8 @@
             }
 
             self.command.tree_status = lambda: 'open'
-            self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=None), [], self.tool)
+            self._execute_command_with_mock_options()
             self.assertEqual(self.tool.executive.calls, [
-                [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', '', 'fast/dom/prototype-taco.html']],
                 ['git', 'cl', 'upload', '-f'],
                 ['git', 'pull'],
                 ['git', 'cl', 'land', '-f', '-v'],
@@ -1277,9 +1280,8 @@
 
             self.command.tree_status = lambda: 'open'
             webkitpy.tool.commands.rebaseline._get_branch_name_or_ref = lambda x: 'auto-rebaseline-temporary-branch'
-            self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=None), [], self.tool)
+            self._execute_command_with_mock_options()
             self.assertEqual(self.tool.executive.calls, [
-                [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', '', 'fast/dom/prototype-taco.html']],
                 ['git', 'cl', 'upload', '-f'],
                 ['git', 'pull'],
                 ['git', 'cl', 'land', '-f', '-v'],
@@ -1339,9 +1341,8 @@
 
             self.command.tree_status = lambda: 'open'
             webkitpy.tool.commands.rebaseline._get_branch_name_or_ref = lambda x: 'auto-rebaseline-alt-temporary-branch'
-            self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=None), [], self.tool)
+            self._execute_command_with_mock_options()
             self.assertEqual(self.tool.executive.calls, [
-                [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', '', 'fast/dom/prototype-taco.html']],
                 ['git', 'cl', 'upload', '-f'],
                 ['git', 'pull'],
                 ['git', 'cl', 'land', '-f', '-v'],
@@ -1355,9 +1356,7 @@
             builders._exact_matches = old_exact_matches
             webkitpy.tool.commands.rebaseline._get_branch_name_or_ref = old_branch_name
 
-    def test_execute_with_rietveld_auth_refresh_token(self):
-        RIETVELD_REFRESH_TOKEN = '/creds/refresh_tokens/test_rietveld_token'
-
+    def _basic_execute_test(self, expected_executive_calls, auth_refresh_token_json=None, commit_author=None, dry_run=False):
         def blame(path):
             return """
 6469e754a1 path/to/TestExpectations                   (<foobarbaz1@chromium.org> 2013-04-28 04:52:41 +0000   13) Bug(foo) fast/dom/prototype-taco.html [ NeedsRebaseline ]
@@ -1402,14 +1401,8 @@
             }
 
             self.command.tree_status = lambda: 'open'
-            self.command.execute(MockOptions(optimize=True, verbose=False, results_directory=False, auth_refresh_token_json=RIETVELD_REFRESH_TOKEN), [], self.tool)
-            self.assertEqual(self.tool.executive.calls, [
-                [['python', 'echo', 'optimize-baselines', '--no-modify-scm', '--suffixes', '', 'fast/dom/prototype-taco.html']],
-                ['git', 'cl', 'upload', '-f', '--auth-refresh-token-json', RIETVELD_REFRESH_TOKEN],
-                ['git', 'pull'],
-                ['git', 'cl', 'land', '-f', '-v', '--auth-refresh-token-json', RIETVELD_REFRESH_TOKEN],
-                ['git', 'config', 'branch.auto-rebaseline-temporary-branch.rietveldissue'],
-            ])
+            self._execute_command_with_mock_options(auth_refresh_token_json=auth_refresh_token_json, commit_author=commit_author, dry_run=dry_run)
+            self.assertEqual(self.tool.executive.calls, expected_executive_calls)
 
             # The mac ports should both be removed since they're the only ones in builders._exact_matches.
             self.assertEqual(self.tool.filesystem.read_text_file(test_port.path_to_generic_test_expectations_file()), """
@@ -1418,6 +1411,35 @@
         finally:
             builders._exact_matches = old_exact_matches
 
+    def test_execute_with_rietveld_auth_refresh_token(self):
+        RIETVELD_REFRESH_TOKEN = '/creds/refresh_tokens/test_rietveld_token'
+        self._basic_execute_test(
+            [
+                ['git', 'cl', 'upload', '-f', '--auth-refresh-token-json', RIETVELD_REFRESH_TOKEN],
+                ['git', 'pull'],
+                ['git', 'cl', 'land', '-f', '-v', '--auth-refresh-token-json', RIETVELD_REFRESH_TOKEN],
+                ['git', 'config', 'branch.auto-rebaseline-temporary-branch.rietveldissue'],
+            ],
+            auth_refresh_token_json=RIETVELD_REFRESH_TOKEN)
+
+    def test_execute_with_commit_author(self):
+        COMMIT_AUTHOR = "JRR Tolkien <tolkien@greyhavens.org>"
+        self._basic_execute_test(
+            [
+                ['git', 'cl', 'upload', '-f'],
+                ['git', 'pull'],
+                ['git', 'cl', 'land', '-f', '-v'],
+                ['git', 'config', 'branch.auto-rebaseline-temporary-branch.rietveldissue'],
+            ], commit_author=COMMIT_AUTHOR)
+        self.assertEqual(self.tool.scm().local_commits(),
+            [['Auto-rebaseline for r1234\n\nhttps://chromium.googlesource.com/chromium/src/+/6469e754a1\n\nTBR=foobarbaz1@chromium.org\n',
+            True,
+            COMMIT_AUTHOR]])
+
+    def test_execute_with_dry_run(self):
+        self._basic_execute_test([], dry_run=True)
+        self.assertEqual(self.tool.scm().local_commits(), [])
+
 
 class TestRebaselineOMatic(_BaseTestCase):
     command_constructor = RebaselineOMatic
diff --git a/third_party/WebKit/public/platform/WebFont.h b/third_party/WebKit/public/platform/WebFont.h
index 14498c4c..6084238 100644
--- a/third_party/WebKit/public/platform/WebFont.h
+++ b/third_party/WebKit/public/platform/WebFont.h
@@ -23,7 +23,7 @@
     BLINK_PLATFORM_EXPORT static WebFont* create(const WebFontDescription&);
     BLINK_PLATFORM_EXPORT ~WebFont();
 
-    BLINK_PLATFORM_EXPORT WebFontDescription fontDescription() const;
+    BLINK_PLATFORM_EXPORT WebFontDescription getFontDescription() const;
     BLINK_PLATFORM_EXPORT int ascent() const;
     BLINK_PLATFORM_EXPORT int descent() const;
     BLINK_PLATFORM_EXPORT int height() const;
diff --git a/third_party/WebKit/public/platform/WebMediaStream.h b/third_party/WebKit/public/platform/WebMediaStream.h
index 03b0172..e29a8b3 100644
--- a/third_party/WebKit/public/platform/WebMediaStream.h
+++ b/third_party/WebKit/public/platform/WebMediaStream.h
@@ -73,7 +73,7 @@
     // If non-null, the extra data pointer will be deleted when the object is destroyed.
     // Setting the extra data pointer will cause any existing non-null
     // extra data pointer to be deleted.
-    BLINK_PLATFORM_EXPORT ExtraData* extraData() const;
+    BLINK_PLATFORM_EXPORT ExtraData* getExtraData() const;
     BLINK_PLATFORM_EXPORT void setExtraData(ExtraData*);
 
 #if INSIDE_BLINK
diff --git a/third_party/WebKit/public/platform/WebMediaStreamTrack.h b/third_party/WebKit/public/platform/WebMediaStreamTrack.h
index 7bacd76..67050201 100644
--- a/third_party/WebKit/public/platform/WebMediaStreamTrack.h
+++ b/third_party/WebKit/public/platform/WebMediaStreamTrack.h
@@ -72,7 +72,7 @@
     // If non-null, the extra data pointer will be deleted when the object is destroyed.
     // Setting the extra data pointer will cause any existing non-null
     // extra data pointer to be deleted.
-    BLINK_PLATFORM_EXPORT ExtraData* extraData() const;
+    BLINK_PLATFORM_EXPORT ExtraData* getExtraData() const;
     BLINK_PLATFORM_EXPORT void setExtraData(ExtraData*);
 
     // The lifetime of the WebAudioSourceProvider should outlive the
diff --git a/third_party/WebKit/public/platform/WebPrerender.h b/third_party/WebKit/public/platform/WebPrerender.h
index 55937f4..77b261a 100644
--- a/third_party/WebKit/public/platform/WebPrerender.h
+++ b/third_party/WebKit/public/platform/WebPrerender.h
@@ -83,7 +83,7 @@
     BLINK_PLATFORM_EXPORT WebReferrerPolicy referrerPolicy() const;
 
     BLINK_PLATFORM_EXPORT void setExtraData(ExtraData*);
-    BLINK_PLATFORM_EXPORT const ExtraData* extraData() const;
+    BLINK_PLATFORM_EXPORT const ExtraData* getExtraData() const;
 
     BLINK_PLATFORM_EXPORT void didStartPrerender();
     BLINK_PLATFORM_EXPORT void didStopPrerender();
diff --git a/third_party/WebKit/public/platform/WebTrialTokenValidator.h b/third_party/WebKit/public/platform/WebTrialTokenValidator.h
index c6108b7..b11cb21 100644
--- a/third_party/WebKit/public/platform/WebTrialTokenValidator.h
+++ b/third_party/WebKit/public/platform/WebTrialTokenValidator.h
@@ -6,6 +6,7 @@
 #define WebTrialTokenValidator_h
 
 #include "public/platform/WebCallbacks.h"
+#include "public/platform/WebSecurityOrigin.h"
 #include "public/platform/WebString.h"
 
 namespace blink {
@@ -24,7 +25,7 @@
 
     // Returns true if the given token is valid for the specified origin and
     // feature name.
-    virtual bool validateToken(const WebString& token, const WebString& origin, const WebString& featureName) = 0;
+    virtual bool validateToken(const WebString& token, const WebSecurityOrigin&, const WebString& featureName) = 0;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/public/platform/WebURLRequest.h b/third_party/WebKit/public/platform/WebURLRequest.h
index 66d86b95..6caabf53 100644
--- a/third_party/WebKit/public/platform/WebURLRequest.h
+++ b/third_party/WebKit/public/platform/WebURLRequest.h
@@ -287,7 +287,7 @@
     // deleted when the last resource request is destroyed. Setting the extra
     // data pointer will cause the underlying resource request to be
     // dissociated from any existing non-null extra data pointer.
-    BLINK_PLATFORM_EXPORT ExtraData* extraData() const;
+    BLINK_PLATFORM_EXPORT ExtraData* getExtraData() const;
     BLINK_PLATFORM_EXPORT void setExtraData(ExtraData*);
 
     BLINK_PLATFORM_EXPORT Priority getPriority() const;
diff --git a/third_party/WebKit/public/platform/WebURLResponse.h b/third_party/WebKit/public/platform/WebURLResponse.h
index 7983419e..1b507d9 100644
--- a/third_party/WebKit/public/platform/WebURLResponse.h
+++ b/third_party/WebKit/public/platform/WebURLResponse.h
@@ -225,9 +225,8 @@
     BLINK_PLATFORM_EXPORT WebURL originalURLViaServiceWorker() const;
     BLINK_PLATFORM_EXPORT void setOriginalURLViaServiceWorker(const WebURL&);
 
-    // Flag whether this request is part of a multipart response.
-    BLINK_PLATFORM_EXPORT bool isMultipartPayload() const;
-    BLINK_PLATFORM_EXPORT void setIsMultipartPayload(bool);
+    // The boundary of the response. Set only when this is a multipart response.
+    BLINK_PLATFORM_EXPORT void setMultipartBoundary(const char* bytes, size_t /* size */);
 
     // This indicates the location of a downloaded response if the
     // WebURLRequest had the downloadToFile flag set to true. This file path
@@ -249,7 +248,7 @@
     // deleted when the last resource response is destroyed. Setting the extra
     // data pointer will cause the underlying resource response to be
     // dissociated from any existing non-null extra data pointer.
-    BLINK_PLATFORM_EXPORT ExtraData* extraData() const;
+    BLINK_PLATFORM_EXPORT ExtraData* getExtraData() const;
     BLINK_PLATFORM_EXPORT void setExtraData(ExtraData*);
 
 protected:
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorker.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorker.h
index 68348616..957bb4e 100644
--- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorker.h
+++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorker.h
@@ -40,6 +40,8 @@
 
 namespace blink {
 
+class WebSecurityOrigin;
+class WebServiceWorkerProvider;
 class WebServiceWorkerProxy;
 typedef WebVector<class WebMessagePortChannel*> WebMessagePortChannelArray;
 
@@ -69,7 +71,7 @@
 
     // Callee receives ownership of the passed vector.
     // FIXME: Blob refs should be passed to maintain ref counts. crbug.com/351753
-    virtual void postMessage(const WebString&, WebMessagePortChannelArray*) { BLINK_ASSERT_NOT_REACHED(); }
+    virtual void postMessage(WebServiceWorkerProvider*, const WebString&, const WebSecurityOrigin&, WebMessagePortChannelArray*) { BLINK_ASSERT_NOT_REACHED(); }
 
     virtual void terminate() { }
 };
diff --git a/third_party/WebKit/public/web/WebDataSource.h b/third_party/WebKit/public/web/WebDataSource.h
index 29d725f..a705fb4 100644
--- a/third_party/WebKit/public/web/WebDataSource.h
+++ b/third_party/WebKit/public/web/WebDataSource.h
@@ -93,7 +93,7 @@
     // data pointer will be deleted when the datasource is destroyed.
     // Setting the extra data pointer will cause any existing non-null
     // extra data pointer to be deleted.
-    virtual ExtraData* extraData() const = 0;
+    virtual ExtraData* getExtraData() const = 0;
     virtual void setExtraData(ExtraData*) = 0;
 
     // Sets the navigation start time for this datasource. Ordinarily,
diff --git a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h
index 9516a3c..6091d34 100644
--- a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h
+++ b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h
@@ -35,15 +35,17 @@
 #include "public/platform/WebMessagePortChannel.h"
 #include "public/platform/WebPassOwnPtr.h"
 #include "public/platform/modules/navigator_services/WebServicePortCallbacks.h"
+#include "public/platform/modules/serviceworker/WebServiceWorker.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerRegistration.h"
 
 namespace blink {
 
+class WebServiceWorkerRequest;
+class WebString;
 struct WebCircularGeofencingRegion;
 struct WebCrossOriginServiceWorkerClient;
 struct WebNotificationData;
-class WebServiceWorkerRequest;
-class WebString;
+struct WebServiceWorkerClientInfo;
 struct WebSyncRegistration;
 
 // A proxy interface to talk to the worker's GlobalScope implementation.
@@ -55,7 +57,8 @@
     virtual void setRegistration(WebPassOwnPtr<WebServiceWorkerRegistration::Handle>) = 0;
 
     virtual void dispatchActivateEvent(int eventID) = 0;
-    virtual void dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebMessagePortChannelArray&) = 0;
+    virtual void dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebSecurityOrigin& sourceOrigin, const WebMessagePortChannelArray&, const WebServiceWorkerClientInfo&) = 0;
+    virtual void dispatchExtendableMessageEvent(int eventID, const WebString& message, const WebSecurityOrigin& sourceOrigin, const WebMessagePortChannelArray&, WebPassOwnPtr<WebServiceWorker::Handle>) = 0;
     virtual void dispatchInstallEvent(int eventID) = 0;
     virtual void dispatchFetchEvent(int eventID, const WebServiceWorkerRequest& webRequest) = 0;
     virtual void dispatchForeignFetchEvent(int eventID, const WebServiceWorkerRequest& webRequest) = 0;
diff --git a/third_party/libvpx_new/BUILD.gn b/third_party/libvpx_new/BUILD.gn
deleted file mode 100644
index 24754db..0000000
--- a/third_party/libvpx_new/BUILD.gn
+++ /dev/null
@@ -1,15 +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.
-
-# This config is applied to targets that depend on libvpx.
-config("libvpx_external_config") {
-  include_dirs = [ "//third_party/libvpx/source/libvpx" ]
-}
-
-group("libvpx_new") {
-  public_deps = [
-    "//third_party/libvpx",
-  ]
-  public_configs = [ ":libvpx_external_config" ]
-}
diff --git a/third_party/libvpx_new/LICENSE b/third_party/libvpx_new/LICENSE
deleted file mode 100644
index 1ce4434..0000000
--- a/third_party/libvpx_new/LICENSE
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 2010, The WebM Project authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-  * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-
-  * Neither the name of Google, nor the WebM Project, 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
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/third_party/libvpx_new/OWNERS b/third_party/libvpx_new/OWNERS
deleted file mode 100644
index eb76b63..0000000
--- a/third_party/libvpx_new/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-tomfinegan@chromium.org
-johannkoenig@google.com
diff --git a/third_party/libvpx_new/README.chromium b/third_party/libvpx_new/README.chromium
deleted file mode 100644
index a1d381e..0000000
--- a/third_party/libvpx_new/README.chromium
+++ /dev/null
@@ -1,48 +0,0 @@
-Name: libvpx
-URL: http://www.webmproject.org
-Version: v1.4.0
-License: BSD
-License File: LICENSE
-Security Critical: yes
-
-Date: Tuesday February 16 2016
-Branch: master
-Commit: 89cc68252846478fa7f2d570d96ff93776cefac6
-
-Description:
-Contains the sources used to compile libvpx binaries used by Google Chrome and
-Chromium.
-
-The libvpx source is from webmproject.org:
-  http://www.webmproject.org/code/
-  https://chromium.googlesource.com/webm/libvpx
-
-Please follow these steps to update libvpx source code:
-
-1. Update the code:
-     roll_dep.py \
-       -r <libvpx OWNER> \
-       --log-limit 20 \
-       --roll-to <libvpx hash> \
-       src/third_party/libvpx_new/source/libvpx
-
-   Use the generated commit message for the roll.
-
-2. Generate .gypi, .gni and config files.
-
-   cd third_party/libvpx_new
-   ./generate_gypi.sh
-
-3. Update README.chromium with Date, Branch, and Commit.
-
-Tools needed to build libvpx:
-
-- generate_gypi.sh
-
-Generate config and .gypi files that contain the source list for each platform.
-Configuration for the build is taken from vpx_config.h for each platform.
-
-- lint_config.sh
-
-A tool to verify vpx_config.h and vpx_config.asm are matched. This also
-prints the final configuration after checking.
diff --git a/third_party/libvpx_new/libvpx.gyp b/third_party/libvpx_new/libvpx.gyp
deleted file mode 100644
index 7a3c45891..0000000
--- a/third_party/libvpx_new/libvpx.gyp
+++ /dev/null
@@ -1,19 +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.
-{
-  'targets': [
-    {
-      # This libvpx target contains both encoder and decoder.
-      # Encoder is configured to be realtime only.
-      'target_name': 'libvpx_new',
-      'type': 'none',
-      'dependencies': [
-        '<(DEPTH)/third_party/libvpx/libvpx.gyp:libvpx'
-      ],
-      'export_dependent_settings': [
-        '<(DEPTH)/third_party/libvpx/libvpx.gyp:libvpx'
-      ],
-    },
-  ],
-}
diff --git a/tools/copyright_scanner/third_party_files_whitelist.txt b/tools/copyright_scanner/third_party_files_whitelist.txt
index 7c34ebf9..43fc331 100644
--- a/tools/copyright_scanner/third_party_files_whitelist.txt
+++ b/tools/copyright_scanner/third_party_files_whitelist.txt
@@ -241,10 +241,6 @@
 # code is taken from WebKit, the license for which we already pick up from
 # webkit/.
 content/browser/appcache/appcache_manifest_parser.h
-# Copyright The Chromium Authors and Netscape Communications Corporation; BSD
-# and (MPL, GPL v2 or LGPL v2) licenses. This third-party code is taken from
-# Mozilla, the license for which we already pick up from third_party/npapi/.
-content/child/multipart_response_delegate.h
 # String 'copyright' used in code.
 ui/webui/resources/js/cr/ui/array_data_model.js
 # Copyright The Chromium Authors and Apple Inc; BSD license. This third-party
diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn
index b27ae70..37bce8d 100644
--- a/tools/gn/BUILD.gn
+++ b/tools/gn/BUILD.gn
@@ -24,8 +24,12 @@
     "builder.h",
     "builder_record.cc",
     "builder_record.h",
+    "bundle_data.cc",
+    "bundle_data.h",
     "bundle_data_target_generator.cc",
     "bundle_data_target_generator.h",
+    "bundle_file_rule.cc",
+    "bundle_file_rule.h",
     "c_include_iterator.cc",
     "c_include_iterator.h",
     "command_args.cc",
@@ -50,6 +54,8 @@
     "config_values_generator.h",
     "copy_target_generator.cc",
     "copy_target_generator.h",
+    "create_bundle_target_generator.cc",
+    "create_bundle_target_generator.h",
     "deps_iterator.cc",
     "deps_iterator.h",
     "eclipse_writer.cc",
@@ -116,6 +122,8 @@
     "ninja_bundle_data_target_writer.h",
     "ninja_copy_target_writer.cc",
     "ninja_copy_target_writer.h",
+    "ninja_create_bundle_target_writer.cc",
+    "ninja_create_bundle_target_writer.h",
     "ninja_group_target_writer.cc",
     "ninja_group_target_writer.h",
     "ninja_target_writer.cc",
@@ -278,6 +286,7 @@
     "ninja_action_target_writer_unittest.cc",
     "ninja_binary_target_writer_unittest.cc",
     "ninja_copy_target_writer_unittest.cc",
+    "ninja_create_bundle_target_writer_unittest.cc",
     "ninja_group_target_writer_unittest.cc",
     "ninja_target_writer_unittest.cc",
     "ninja_toolchain_writer_unittest.cc",
diff --git a/tools/gn/bundle_data.cc b/tools/gn/bundle_data.cc
new file mode 100644
index 0000000..e22612c
--- /dev/null
+++ b/tools/gn/bundle_data.cc
@@ -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.
+
+#include "tools/gn/bundle_data.h"
+
+#include "base/logging.h"
+#include "tools/gn/output_file.h"
+#include "tools/gn/settings.h"
+#include "tools/gn/target.h"
+
+namespace {
+
+// Return directory of |path| without the trailing directory separator.
+base::StringPiece FindDirNoTrailingSeparator(const base::StringPiece& path) {
+  base::StringPiece::size_type pos = path.find_last_of("/\\");
+  if (pos == base::StringPiece::npos)
+    return base::StringPiece();
+  return base::StringPiece(path.data(), pos);
+}
+
+}  // namespace
+
+bool IsSourceFileFromAssetCatalog(const SourceFile& source,
+                                  SourceFile* asset_catalog) {
+  // Check that the file matches the following pattern:
+  //    .*\.xcassets/[^/]*\.imageset/[^/]*
+  base::StringPiece dir;
+  dir = FindDirNoTrailingSeparator(source.value());
+  if (!dir.ends_with(".imageset"))
+    return false;
+  dir = FindDirNoTrailingSeparator(dir);
+  if (!dir.ends_with(".xcassets"))
+    return false;
+  if (asset_catalog) {
+    std::string asset_catalog_path = dir.as_string();
+    *asset_catalog = SourceFile(SourceFile::SWAP_IN, &asset_catalog_path);
+  }
+  return true;
+}
+
+BundleData::BundleData() {}
+
+BundleData::~BundleData() {}
+
+void BundleData::AddFileRuleFromTarget(const Target* target) {
+  DCHECK_EQ(target->output_type(), Target::BUNDLE_DATA);
+
+  std::vector<SourceFile> file_rule_sources;
+  for (const SourceFile& source_file : target->sources()) {
+    if (IsSourceFileFromAssetCatalog(source_file, nullptr)) {
+      asset_catalog_sources_.push_back(source_file);
+    } else {
+      file_rule_sources.push_back(source_file);
+    }
+  }
+
+  if (!file_rule_sources.empty()) {
+    DCHECK_EQ(target->action_values().outputs().list().size(), 1u);
+    file_rules_.push_back(BundleFileRule(
+        file_rule_sources, target->action_values().outputs().list()[0]));
+  }
+}
+
+void BundleData::GetSourceFiles(std::vector<SourceFile>* sources) const {
+  for (const BundleFileRule& file_rule : file_rules_) {
+    sources->insert(sources->end(), file_rule.sources().begin(),
+                    file_rule.sources().end());
+  }
+  sources->insert(sources->end(), asset_catalog_sources_.begin(),
+                  asset_catalog_sources_.end());
+}
+
+void BundleData::GetOutputFiles(const Settings* settings,
+                                std::vector<OutputFile>* outputs) const {
+  std::vector<SourceFile> outputs_as_sources;
+  GetOutputsAsSourceFiles(settings, &outputs_as_sources);
+  for (const SourceFile& source_file : outputs_as_sources)
+    outputs->push_back(OutputFile(settings->build_settings(), source_file));
+}
+
+void BundleData::GetOutputsAsSourceFiles(
+    const Settings* settings,
+    std::vector<SourceFile>* outputs_as_source) const {
+  for (const BundleFileRule& file_rule : file_rules_) {
+    for (const SourceFile& source : file_rule.sources()) {
+      outputs_as_source->push_back(
+          file_rule.ApplyPatternToSource(settings, *this, source));
+    }
+  }
+
+  if (!asset_catalog_sources_.empty())
+    outputs_as_source->push_back(GetCompiledAssetCatalogPath());
+}
+
+SourceFile BundleData::GetCompiledAssetCatalogPath() const {
+  DCHECK(!asset_catalog_sources_.empty());
+  std::string assets_car_path = resources_dir_ + "/Assets.car";
+  return SourceFile(SourceFile::SWAP_IN, &assets_car_path);
+}
diff --git a/tools/gn/bundle_data.h b/tools/gn/bundle_data.h
new file mode 100644
index 0000000..9d1df13f
--- /dev/null
+++ b/tools/gn/bundle_data.h
@@ -0,0 +1,91 @@
+// 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 TOOLS_GN_BUNDLE_DATA_H_
+#define TOOLS_GN_BUNDLE_DATA_H_
+
+#include <string>
+#include <vector>
+
+#include "tools/gn/bundle_file_rule.h"
+
+class OutputFile;
+class SourceFile;
+class Settings;
+class Target;
+
+// Returns true if |source| correspond to the path of a file in an asset
+// catalog. If defined |asset_catalog| is set to its path.
+//
+// An asset catalog is an OS X bundle with the ".xcassets" extension. It
+// contains one directory per assets each of them with the ".imageset"
+// extension.
+//
+// All asset catalogs are compiled by Xcode into single Assets.car file as
+// part of the creation of an application or framework bundle. BundleData
+// emulates this with the "compile_xcassets" tool.
+bool IsSourceFileFromAssetCatalog(const SourceFile& source,
+                                  SourceFile* asset_catalog);
+
+// BundleData holds the information required by "create_bundle" target.
+class BundleData {
+ public:
+  BundleData();
+  ~BundleData();
+
+  // Extracts the information required from a "bundle_data" target.
+  void AddFileRuleFromTarget(const Target* target);
+
+  // Returns the list of inputs.
+  void GetSourceFiles(std::vector<SourceFile>* sources) const;
+
+  // Returns the list of outputs.
+  void GetOutputFiles(const Settings* settings,
+                      std::vector<OutputFile>* outputs) const;
+
+  // Returns the list of outputs as SourceFile.
+  void GetOutputsAsSourceFiles(
+      const Settings* settings,
+      std::vector<SourceFile>* outputs_as_source) const;
+
+  // Returns the path to the compiled asset catalog. Only valid if
+  // asset_catalog_sources() is not empty.
+  SourceFile GetCompiledAssetCatalogPath() const;
+
+  // Returns the list of inputs for the compilation of the asset catalog.
+  std::vector<SourceFile>& asset_catalog_sources() {
+    return asset_catalog_sources_;
+  }
+  const std::vector<SourceFile>& asset_catalog_sources() const {
+    return asset_catalog_sources_;
+  }
+
+  std::vector<BundleFileRule>& file_rules() { return file_rules_; }
+  const std::vector<BundleFileRule>& file_rules() const { return file_rules_; }
+
+  std::string& root_dir() { return root_dir_; }
+  const std::string& root_dir() const { return root_dir_; }
+
+  std::string& resources_dir() { return resources_dir_; }
+  const std::string& resources_dir() const { return resources_dir_; }
+
+  std::string& executable_dir() { return executable_dir_; }
+  const std::string& executable_dir() const { return executable_dir_; }
+
+  std::string& plugins_dir() { return plugins_dir_; }
+  const std::string& plugins_dir() const { return plugins_dir_; }
+
+ private:
+  std::vector<SourceFile> asset_catalog_sources_;
+  std::vector<BundleFileRule> file_rules_;
+
+  // All those values are subdirectories relative to root_build_dir, and apart
+  // from root_dir, they are either equal to root_dir_ or subdirectories of it.
+  std::string root_dir_;
+  std::string resources_dir_;
+  std::string executable_dir_;
+  std::string plugins_dir_;
+};
+
+#endif  // TOOLS_GN_BUNDLE_DATA_H_
diff --git a/tools/gn/bundle_file_rule.cc b/tools/gn/bundle_file_rule.cc
new file mode 100644
index 0000000..0f42c8f1
--- /dev/null
+++ b/tools/gn/bundle_file_rule.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 "tools/gn/bundle_file_rule.h"
+
+#include "tools/gn/output_file.h"
+#include "tools/gn/settings.h"
+#include "tools/gn/substitution_pattern.h"
+#include "tools/gn/substitution_writer.h"
+#include "tools/gn/target.h"
+
+BundleFileRule::BundleFileRule(const std::vector<SourceFile> sources,
+                               const SubstitutionPattern& pattern)
+    : sources_(sources), pattern_(pattern) {}
+
+BundleFileRule::~BundleFileRule() {}
+
+SourceFile BundleFileRule::ApplyPatternToSource(
+    const Settings* settings,
+    const BundleData& bundle_data,
+    const SourceFile& source_file) const {
+  std::string output_path;
+  for (const auto& subrange : pattern_.ranges()) {
+    switch (subrange.type) {
+      case SUBSTITUTION_LITERAL:
+        output_path.append(subrange.literal);
+        break;
+      case SUBSTITUTION_BUNDLE_ROOT_DIR:
+        output_path.append(bundle_data.root_dir());
+        break;
+      case SUBSTITUTION_BUNDLE_RESOURCES_DIR:
+        output_path.append(bundle_data.resources_dir());
+        break;
+      case SUBSTITUTION_BUNDLE_EXECUTABLE_DIR:
+        output_path.append(bundle_data.executable_dir());
+        break;
+      case SUBSTITUTION_BUNDLE_PLUGINS_DIR:
+        output_path.append(bundle_data.plugins_dir());
+        break;
+      default:
+        output_path.append(SubstitutionWriter::GetSourceSubstitution(
+            settings, source_file, subrange.type,
+            SubstitutionWriter::OUTPUT_ABSOLUTE, SourceDir()));
+        break;
+    }
+  }
+  return SourceFile(SourceFile::SWAP_IN, &output_path);
+}
+
+OutputFile BundleFileRule::ApplyPatternToSourceAsOutputFile(
+    const Settings* settings,
+    const BundleData& bundle_data,
+    const SourceFile& source_file) const {
+  return OutputFile(settings->build_settings(),
+                    ApplyPatternToSource(settings, bundle_data, source_file));
+}
diff --git a/tools/gn/bundle_file_rule.h b/tools/gn/bundle_file_rule.h
new file mode 100644
index 0000000..3669cd2
--- /dev/null
+++ b/tools/gn/bundle_file_rule.h
@@ -0,0 +1,43 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_GN_BUNDLE_FILE_RULE_H_
+#define TOOLS_GN_BUNDLE_FILE_RULE_H_
+
+#include <vector>
+
+#include "tools/gn/source_file.h"
+#include "tools/gn/substitution_pattern.h"
+
+class BundleData;
+class Settings;
+class SourceFile;
+class OutputFile;
+
+// BundleFileRule contains the information found in a "bundle_data" target.
+class BundleFileRule {
+ public:
+  BundleFileRule(const std::vector<SourceFile> sources,
+                 const SubstitutionPattern& pattern);
+  ~BundleFileRule();
+
+  // Applies the substitution pattern to a source file, returning the result
+  // as either a SourceFile or an OutputFile.
+  SourceFile ApplyPatternToSource(const Settings* settings,
+                                  const BundleData& bundle_data,
+                                  const SourceFile& source_file) const;
+  OutputFile ApplyPatternToSourceAsOutputFile(
+      const Settings* settings,
+      const BundleData& bundle_data,
+      const SourceFile& source_file) const;
+
+  // Returns the list of SourceFiles.
+  const std::vector<SourceFile>& sources() const { return sources_; }
+
+ private:
+  std::vector<SourceFile> sources_;
+  SubstitutionPattern pattern_;
+};
+
+#endif  // TOOLS_GN_BUNDLE_FILE_RULE_H_
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc
index 801055b0..15efe77 100644
--- a/tools/gn/command_desc.cc
+++ b/tools/gn/command_desc.cc
@@ -327,6 +327,11 @@
     for (const auto& elem : target->action_values().outputs().list()) {
       OutputString("  " + elem.AsString() + "\n");
     }
+  } else if (target->output_type() == Target::CREATE_BUNDLE) {
+    std::vector<SourceFile> output_files;
+    target->bundle_data().GetOutputsAsSourceFiles(target->settings(),
+                                                  &output_files);
+    PrintFileList(output_files, "", true, false);
   } else {
     const SubstitutionList& outputs = target->action_values().outputs();
     if (!outputs.required_types().empty()) {
@@ -685,7 +690,8 @@
     target->output_type() != Target::COPY_FILES &&
     target->output_type() != Target::ACTION &&
     target->output_type() != Target::ACTION_FOREACH &&
-    target->output_type() != Target::BUNDLE_DATA;
+    target->output_type() != Target::BUNDLE_DATA &&
+    target->output_type() != Target::CREATE_BUNDLE;
 
   // Generally we only want to display toolchains on labels when the toolchain
   // is different than the default one for this target (which we always print
@@ -739,7 +745,8 @@
 
   if (target->output_type() == Target::ACTION ||
       target->output_type() == Target::ACTION_FOREACH ||
-      target->output_type() == Target::COPY_FILES) {
+      target->output_type() == Target::COPY_FILES ||
+      target->output_type() == Target::CREATE_BUNDLE) {
     PrintOutputs(target, true);
   }
 
diff --git a/tools/gn/create_bundle_target_generator.cc b/tools/gn/create_bundle_target_generator.cc
new file mode 100644
index 0000000..206a918
--- /dev/null
+++ b/tools/gn/create_bundle_target_generator.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 "tools/gn/create_bundle_target_generator.h"
+
+#include "tools/gn/filesystem_utils.h"
+#include "tools/gn/parse_tree.h"
+#include "tools/gn/scope.h"
+#include "tools/gn/substitution_type.h"
+#include "tools/gn/target.h"
+#include "tools/gn/value.h"
+#include "tools/gn/variables.h"
+
+CreateBundleTargetGenerator::CreateBundleTargetGenerator(
+    Target* target,
+    Scope* scope,
+    const FunctionCallNode* function_call,
+    Err* err)
+    : TargetGenerator(target, scope, function_call, err) {}
+
+CreateBundleTargetGenerator::~CreateBundleTargetGenerator() {}
+
+void CreateBundleTargetGenerator::DoRun() {
+  target_->set_output_type(Target::CREATE_BUNDLE);
+
+  BundleData& bundle_data = target_->bundle_data();
+  if (!GetBundleDir(std::string(),
+                    variables::kBundleRootDir,
+                    &bundle_data.root_dir()))
+    return;
+  if (!GetBundleDir(bundle_data.root_dir(),
+                    variables::kBundleResourcesDir,
+                    &bundle_data.resources_dir()))
+    return;
+  if (!GetBundleDir(bundle_data.root_dir(),
+                    variables::kBundleExecutableDir,
+                    &bundle_data.executable_dir()))
+    return;
+  if (!GetBundleDir(bundle_data.root_dir(),
+                    variables::kBundlePlugInsDir,
+                    &bundle_data.plugins_dir()))
+    return;
+}
+
+bool CreateBundleTargetGenerator::GetBundleDir(
+    const std::string& bundle_root_dir,
+    const base::StringPiece& name,
+    std::string* bundle_dir) {
+  const Value* value = scope_->GetValue(name, true);
+  if (!value)
+    return true;
+  if (!value->VerifyTypeIs(Value::STRING, err_))
+    return false;
+  const std::string& str = value->string_value();
+  if (!EnsureStringIsInOutputDir(GetBuildSettings()->build_dir(), str,
+                                 value->origin(), err_))
+    return false;
+  if (str != bundle_root_dir &&
+      !IsStringInOutputDir(SourceDir(bundle_root_dir), str)) {
+    *err_ = Err(value->origin(), "Path is not in bundle root dir.",
+        "The given file should be in the bundle root directory or below.\n"
+        "Normally you would do \"$bundle_root_dir/foo\". I interpreted this\n"
+        "as \"" + str + "\".");
+    return false;
+  }
+  bundle_dir->assign(value->string_value());
+  return true;
+}
diff --git a/tools/gn/create_bundle_target_generator.h b/tools/gn/create_bundle_target_generator.h
new file mode 100644
index 0000000..db82b8a
--- /dev/null
+++ b/tools/gn/create_bundle_target_generator.h
@@ -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.
+
+#ifndef TOOLS_GN_CREATE_BUNDLE_TARGET_GENERATOR_H_
+#define TOOLS_GN_CREATE_BUNDLE_TARGET_GENERATOR_H_
+
+#include "base/macros.h"
+#include "tools/gn/target_generator.h"
+
+// Populates a Target with the values from a create_bundle rule.
+class CreateBundleTargetGenerator : public TargetGenerator {
+ public:
+  CreateBundleTargetGenerator(Target* target,
+                              Scope* scope,
+                              const FunctionCallNode* function_call,
+                              Err* err);
+  ~CreateBundleTargetGenerator() override;
+
+ protected:
+  void DoRun() override;
+
+ private:
+  bool GetBundleDir(const std::string& bundle_root_dir,
+                    const base::StringPiece& name,
+                    std::string* bundle_dir);
+
+  DISALLOW_COPY_AND_ASSIGN(CreateBundleTargetGenerator);
+};
+
+#endif  // TOOLS_GN_CREATE_BUNDLE_TARGET_GENERATOR_H_
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md
index 40da46b2..6edacfce 100644
--- a/tools/gn/docs/reference.md
+++ b/tools/gn/docs/reference.md
@@ -1056,6 +1056,65 @@
 
 
 ```
+## **bundle_data**: [iOS/OS X] Declare a target without output.
+
+```
+  This target type allows to declare data that is required at runtime.
+  It is used to inform "create_bundle" targets of the files to copy
+  into generated bundle, see "gn help create_bundle" for help.
+
+  The target must define a list of files as "sources" and a single
+  "outputs". If there are multiple files, source expansions must be
+  used to express the output. The output must reference a file inside
+  of {{bundle_root_dir}}.
+
+  This target can be used on all platforms though it is designed only to
+  generate iOS/OS X bundle. In cross-platform projects, it is advised to
+  put it behind iOS/Mac conditionals.
+
+  See "gn help create_bundle" for more information.
+
+```
+
+### **Variables**
+
+```
+  sources*, outputs*, deps, data_deps, public_deps, visibility
+  * = required
+
+```
+
+### **Examples**
+
+```
+  bundle_data("icudata") {
+    sources = [ "sources/data/in/icudtl.dat" ]
+    outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
+  }
+
+  bundle_data("base_unittests_bundle_data]") {
+    sources = [ "test/data" ]
+    outputs = [
+      "{{bundle_resources_dir}}/{{source_root_relative_dir}}/" +
+          "{{source_file_part}}"
+    ]
+  }
+
+  bundle_data("material_typography_bundle_data") {
+    sources = [
+      "src/MaterialTypography.bundle/Roboto-Bold.ttf",
+      "src/MaterialTypography.bundle/Roboto-Italic.ttf",
+      "src/MaterialTypography.bundle/Roboto-Regular.ttf",
+      "src/MaterialTypography.bundle/Roboto-Thin.ttf",
+    ]
+    outputs = [
+      "{{bundle_resources_dir}}/MaterialTypography.bundle/"
+          "{{source_file_part}}"
+    ]
+  }
+
+
+```
 ## **config**: Defines a configuration object.
 
 ```
@@ -1154,6 +1213,103 @@
 
 
 ```
+## **create_bundle**: [iOS/OS X] Build an OS X / iOS bundle.
+
+```
+  This target generates an iOS/OS X bundle (which is a directory with a
+  well-know structure). This target does not define any sources, instead
+  they are computed from all "bundle_data" target this one depends on
+  transitively (the recursion stops at "create_bundle" targets).
+
+  The "bundle_*_dir" properties must be defined. They will be used for
+  the expansion of {{bundle_*_dir}} rules in "bundle_data" outputs.
+
+  This target can be used on all platforms though it is designed only to
+  generate iOS/OS X bundle. In cross-platform projects, it is advised to
+  put it behind iOS/Mac conditionals.
+
+```
+
+### **Variables**
+
+```
+  bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*,
+  bundle_plugins_dir*, deps, data_deps, public_deps, visibility
+  * = required
+
+```
+
+### **Example**
+
+```
+  # Defines a template to create an application. On most platform, this
+  # is just an alias for an "executable" target, but on iOS/OS X, it
+  # builds an application bundle.
+  template("app") {
+    if (!is_ios && !is_mac) {
+      executable(target_name) {
+        forward_variables_from(invoker, "*")
+      }
+    } else {
+      app_name = target_name
+      gen_path = target_gen_dir
+
+      action("${app_name}_generate_info_plist") {
+        script = [ "//build/ios/ios_gen_plist.py" ]
+        sources = [ "templates/Info.plist" ]
+        outputs = [ "$gen_path/Info.plist" ]
+        args = rebase_path(sources, root_build_dir) +
+               rebase_path(outputs, root_build_dir)
+      }
+
+      bundle_data("${app_name}_bundle_info_plist") {
+        deps = [ ":${app_name}_generate_info_plist" ]
+        sources = [ "$gen_path/Info.plist" ]
+        outputs = [ "{{bundle_root_dir}}/Info.plist" ]
+      }
+
+      executable("${app_name}_generate_executable") {
+        forward_variables_from(invoker, "*", [
+                                                "output_name",
+                                                "visibility",
+                                               ])
+        output_name =
+            rebase_path("$gen_path/$app_name", root_build_dir)
+      }
+
+      bundle_data("${app_name}_bundle_executable") {
+        deps = [ ":${app_name}_generate_executable" ]
+        sources = [ "$gen_path/$app_name" ]
+        outputs = [ "{{bundle_executable_dir}}/$app_name" ]
+      }
+
+      create_bundle("${app_name}.app") {
+        deps = [
+          ":${app_name}_bundle_executable",
+          ":${app_name}_bundle_info_plist",
+        ]
+        if (is_ios) {
+          bundle_root_dir = "${root_build_dir}/$target_name"
+          bundle_resources_dir = bundle_root_dir
+          bundle_executable_dir = bundle_root_dir
+          bundle_plugins_dir = bundle_root_dir + "/Plugins"
+        } else {
+          bundle_root_dir = "${root_build_dir}/target_name/Contents"
+          bundle_resources_dir = bundle_root_dir + "/Resources"
+          bundle_executable_dir = bundle_root_dir + "/MacOS"
+          bundle_plugins_dir = bundle_root_dir + "/Plugins"
+        }
+      }
+
+      group(target_name) {
+        forward_variables_from(invoker, ["visibility"])
+        deps = [ ":${app_name}.app" ]
+      }
+    }
+  }
+
+
+```
 ## **declare_args**: Declare build arguments.
 
 ```
@@ -2444,6 +2600,10 @@
       "stamp": Tool for creating stamp files
       "copy": Tool to copy files.
 
+    Platform specific tools:
+      "copy_bundle_data": [iOS, OS X] Tool to copy files in a bundle.
+      "compile_xcassets": [iOS, OS X] Tool to compile asset catalogs.
+
 ```
 
 ### **Tool variables**
@@ -2759,6 +2919,18 @@
   {{source}} which is the source of the copy. The stamp tool allows
   only the common tool substitutions.
 
+  The copy_bundle_data and compile_xcassets tools only allows the common
+  tool substitutions. Both tools are required to create iOS/OS X bundles
+  and need only be defined on those platforms.
+
+  The copy_bundle_data tool will be called with one source and needs to
+  copy (optionally optimizing the data representation) to its output. It
+  may be called with a directory as input and it needs to be recursively
+  copied.
+
+  The compile_xcassets tool will be called with one or more source (each
+  an asset catalog) that needs to be compiled to a single output.
+
 ```
 
 ### **Separate linking and dependencies for shared libraries**
@@ -3449,6 +3621,74 @@
 
 
 ```
+## **bundle_executable_dir**: Expansion of {{bundle_executable_dir}} in create_bundle.
+
+```
+  A string corresponding to a path in $root_build_dir.
+
+  This string is used by the "create_bundle" target to expand the
+  {{bundle_executable_dir}} of the "bundle_data" target it depends on.
+  This must correspond to a path under "bundle_root_dir".
+
+  See "gn help bundle_root_dir" for examples.
+
+
+```
+## **bundle_plugins_dir**: Expansion of {{bundle_plugins_dir}} in create_bundle.
+
+```
+  A string corresponding to a path in $root_build_dir.
+
+  This string is used by the "create_bundle" target to expand the
+  {{bundle_plugins_dir}} of the "bundle_data" target it depends on.
+  This must correspond to a path under "bundle_root_dir".
+
+  See "gn help bundle_root_dir" for examples.
+
+
+```
+## **bundle_resources_dir**: Expansion of {{bundle_resources_dir}} in create_bundle.
+
+```
+  A string corresponding to a path in $root_build_dir.
+
+  This string is used by the "create_bundle" target to expand the
+  {{bundle_resources_dir}} of the "bundle_data" target it depends on.
+  This must correspond to a path under "bundle_root_dir".
+
+  See "gn help bundle_root_dir" for examples.
+
+
+```
+## **bundle_root_dir**: Expansion of {{bundle_root_dir}} in create_bundle.
+
+```
+  A string corresponding to a path in root_build_dir.
+
+  This string is used by the "create_bundle" target to expand the
+  {{bundle_root_dir}} of the "bundle_data" target it depends on.
+  This must correspond to a path under root_build_dir.
+
+```
+
+### **Example**
+
+```
+  bundle_data("info_plist") {
+    sources = [ "Info.plist" ]
+    outputs = [ "{{bundle_root_dir}}/Info.plist" ]
+  }
+
+  create_bundle("doom_melon.app") {
+    deps = [ ":info_plist" ]
+    bundle_root_dir = root_build_dir + "/doom_melon.app/Contents"
+    bundle_resources_dir = bundle_root_dir + "/Resources"
+    bundle_executable_dir = bundle_root_dir + "/MacOS"
+    bundle_plugins_dir = bundle_root_dir + "/PlugIns"
+  }
+
+
+```
 ## **cflags***: Flags passed to the C compiler.
 
 ```
@@ -4046,7 +4286,7 @@
 ```
   For action and action_foreach targets, inputs should be the inputs to
   script that don't vary. These should be all .py files that the script
-  uses via imports (the main script itself will be an implcit dependency
+  uses via imports (the main script itself will be an implicit dependency
   of the action so need not be listed).
 
   For action targets, inputs and sources are treated the same, but from
@@ -5254,7 +5494,7 @@
   {{source_name_part}}
       The filename part of the source file with no directory or
       extension. This will generally be used for specifying a
-      transformation from a soruce file to a destination file with the
+      transformation from a source file to a destination file with the
       same name but different extension.
         "//foo/bar/baz.txt" => "baz"
 
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc
index 9eeae98..727be54 100644
--- a/tools/gn/function_toolchain.cc
+++ b/tools/gn/function_toolchain.cc
@@ -407,6 +407,10 @@
     "      \"stamp\": Tool for creating stamp files\n"
     "      \"copy\": Tool to copy files.\n"
     "\n"
+    "    Platform specific tools:\n"
+    "      \"copy_bundle_data\": [iOS, OS X] Tool to copy files in a bundle.\n"
+    "      \"compile_xcassets\": [iOS, OS X] Tool to compile asset catalogs.\n"
+    "\n"
     "Tool variables\n"
     "\n"
     "    command  [string with substitutions]\n"
@@ -718,6 +722,18 @@
     "  {{source}} which is the source of the copy. The stamp tool allows\n"
     "  only the common tool substitutions.\n"
     "\n"
+    "  The copy_bundle_data and compile_xcassets tools only allows the common\n"
+    "  tool substitutions. Both tools are required to create iOS/OS X bundles\n"
+    "  and need only be defined on those platforms.\n"
+    "\n"
+    "  The copy_bundle_data tool will be called with one source and needs to\n"
+    "  copy (optionally optimizing the data representation) to its output. It\n"
+    "  may be called with a directory as input and it needs to be recursively\n"
+    "  copied.\n"
+    "\n"
+    "  The compile_xcassets tool will be called with one or more source (each\n"
+    "  an asset catalog) that needs to be compiled to a single output.\n"
+    "\n"
     "Separate linking and dependencies for shared libraries\n"
     "\n"
     "  Shared libraries are special in that not all changes to them require\n"
@@ -812,9 +828,13 @@
   } else if (IsLinkerTool(tool_type)) {
     subst_validator = &IsValidLinkerSubstitution;
     subst_output_validator = &IsValidLinkerOutputsSubstitution;
-  } else if (tool_type == Toolchain::TYPE_COPY) {
+  } else if (tool_type == Toolchain::TYPE_COPY ||
+             tool_type == Toolchain::TYPE_COPY_BUNDLE_DATA) {
     subst_validator = &IsValidCopySubstitution;
     subst_output_validator = &IsValidCopySubstitution;
+  } else if (tool_type == Toolchain::TYPE_COMPILE_XCASSETS) {
+    subst_validator = &IsValidCompileXCassetsSubstitution;
+    subst_output_validator = &IsValidCompileXCassetsSubstitution;
   } else {
     subst_validator = &IsValidToolSubstitution;
     subst_output_validator = &IsValidToolSubstitution;
@@ -851,9 +871,12 @@
     return Value();
   }
 
-  if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP) {
-    // All tools except the copy and stamp tools should have outputs. The copy
-    // and stamp tool's outputs are generated internally.
+  if (tool_type != Toolchain::TYPE_COPY &&
+      tool_type != Toolchain::TYPE_STAMP &&
+      tool_type != Toolchain::TYPE_COPY_BUNDLE_DATA &&
+      tool_type != Toolchain::TYPE_COMPILE_XCASSETS) {
+    // All tools should have outputs, except the copy, stamp, copy_bundle_data
+    // and compile_xcassets tools that generate their outputs internally.
     if (!ReadOutputs(&block_scope, function, subst_output_validator,
                      tool.get(), err))
       return Value();
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc
index 37b3401..fc51cc8 100644
--- a/tools/gn/functions.cc
+++ b/tools/gn/functions.cc
@@ -804,6 +804,7 @@
     INSERT_FUNCTION(Action, true)
     INSERT_FUNCTION(ActionForEach, true)
     INSERT_FUNCTION(BundleData, true)
+    INSERT_FUNCTION(CreateBundle, true)
     INSERT_FUNCTION(Copy, true)
     INSERT_FUNCTION(Executable, true)
     INSERT_FUNCTION(Group, true)
diff --git a/tools/gn/functions.h b/tools/gn/functions.h
index 1341720..3ce945e 100644
--- a/tools/gn/functions.h
+++ b/tools/gn/functions.h
@@ -89,6 +89,15 @@
                     BlockNode* block,
                     Err* err);
 
+extern const char kCreateBundle[];
+extern const char kCreateBundle_HelpShort[];
+extern const char kCreateBundle_Help[];
+Value RunCreateBundle(Scope* scope,
+                      const FunctionCallNode* function,
+                      const std::vector<Value>& args,
+                      BlockNode* block,
+                      Err* err);
+
 extern const char kConfig[];
 extern const char kConfig_HelpShort[];
 extern const char kConfig_Help[];
diff --git a/tools/gn/functions_target.cc b/tools/gn/functions_target.cc
index 7a293c7c..7ec5a50 100644
--- a/tools/gn/functions_target.cc
+++ b/tools/gn/functions_target.cc
@@ -247,13 +247,57 @@
 
 const char kBundleData[] = "bundle_data";
 const char kBundleData_HelpShort[] =
-    "bundle_data: Declare a target without output.";
+    "bundle_data: [iOS/OS X] Declare a target without output.";
 const char kBundleData_Help[] =
-    "bundle_data: Declare a target without output.\n"
+    "bundle_data: [iOS/OS X] Declare a target without output.\n"
     "\n"
     "  This target type allows to declare data that is required at runtime.\n"
     "  It is used to inform \"create_bundle\" targets of the files to copy\n"
-    "  into generated bundle, see \"gn help create_bundle\" for help.\n";
+    "  into generated bundle, see \"gn help create_bundle\" for help.\n"
+    "\n"
+    "  The target must define a list of files as \"sources\" and a single\n"
+    "  \"outputs\". If there are multiple files, source expansions must be\n"
+    "  used to express the output. The output must reference a file inside\n"
+    "  of {{bundle_root_dir}}.\n"
+    "\n"
+    "  This target can be used on all platforms though it is designed only to\n"
+    "  generate iOS/OS X bundle. In cross-platform projects, it is advised to\n"
+    "  put it behind iOS/Mac conditionals.\n"
+    "\n"
+    "  See \"gn help create_bundle\" for more information.\n"
+    "\n"
+    "Variables\n"
+    "\n"
+    "  sources*, outputs*, deps, data_deps, public_deps, visibility\n"
+    "  * = required\n"
+    "\n"
+    "Examples\n"
+    "\n"
+    "  bundle_data(\"icudata\") {\n"
+    "    sources = [ \"sources/data/in/icudtl.dat\" ]\n"
+    "    outputs = [ \"{{bundle_resources_dir}}/{{source_file_part}}\" ]\n"
+    "  }\n"
+    "\n"
+    "  bundle_data(\"base_unittests_bundle_data]\") {\n"
+    "    sources = [ \"test/data\" ]\n"
+    "    outputs = [\n"
+    "      \"{{bundle_resources_dir}}/{{source_root_relative_dir}}/\" +\n"
+    "          \"{{source_file_part}}\"\n"
+    "    ]\n"
+    "  }\n"
+    "\n"
+    "  bundle_data(\"material_typography_bundle_data\") {\n"
+    "    sources = [\n"
+    "      \"src/MaterialTypography.bundle/Roboto-Bold.ttf\",\n"
+    "      \"src/MaterialTypography.bundle/Roboto-Italic.ttf\",\n"
+    "      \"src/MaterialTypography.bundle/Roboto-Regular.ttf\",\n"
+    "      \"src/MaterialTypography.bundle/Roboto-Thin.ttf\",\n"
+    "    ]\n"
+    "    outputs = [\n"
+    "      \"{{bundle_resources_dir}}/MaterialTypography.bundle/\"\n"
+    "          \"{{source_file_part}}\"\n"
+    "    ]\n"
+    "  }\n";
 
 Value RunBundleData(Scope* scope,
                     const FunctionCallNode* function,
@@ -264,6 +308,109 @@
                               block, err);
 }
 
+// create_bundle ---------------------------------------------------------------
+
+const char kCreateBundle[] = "create_bundle";
+const char kCreateBundle_HelpShort[] =
+    "create_bundle: [iOS/OS X] Build an OS X / iOS bundle.";
+const char kCreateBundle_Help[] =
+    "create_bundle: [iOS/OS X] Build an OS X / iOS bundle.\n"
+    "\n"
+    "  This target generates an iOS/OS X bundle (which is a directory with a\n"
+    "  well-know structure). This target does not define any sources, instead\n"
+    "  they are computed from all \"bundle_data\" target this one depends on\n"
+    "  transitively (the recursion stops at \"create_bundle\" targets).\n"
+    "\n"
+    "  The \"bundle_*_dir\" properties must be defined. They will be used for\n"
+    "  the expansion of {{bundle_*_dir}} rules in \"bundle_data\" outputs.\n"
+    "\n"
+    "  This target can be used on all platforms though it is designed only to\n"
+    "  generate iOS/OS X bundle. In cross-platform projects, it is advised to\n"
+    "  put it behind iOS/Mac conditionals.\n"
+    "\n"
+    "Variables\n"
+    "\n"
+    "  bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*,\n"
+    "  bundle_plugins_dir*, deps, data_deps, public_deps, visibility\n"
+    "  * = required\n"
+    "\n"
+    "Example\n"
+    "\n"
+    "  # Defines a template to create an application. On most platform, this\n"
+    "  # is just an alias for an \"executable\" target, but on iOS/OS X, it\n"
+    "  # builds an application bundle.\n"
+    "  template(\"app\") {\n"
+    "    if (!is_ios && !is_mac) {\n"
+    "      executable(target_name) {\n"
+    "        forward_variables_from(invoker, \"*\")\n"
+    "      }\n"
+    "    } else {\n"
+    "      app_name = target_name\n"
+    "      gen_path = target_gen_dir\n"
+    "\n"
+    "      action(\"${app_name}_generate_info_plist\") {\n"
+    "        script = [ \"//build/ios/ios_gen_plist.py\" ]\n"
+    "        sources = [ \"templates/Info.plist\" ]\n"
+    "        outputs = [ \"$gen_path/Info.plist\" ]\n"
+    "        args = rebase_path(sources, root_build_dir) +\n"
+    "               rebase_path(outputs, root_build_dir)\n"
+    "      }\n"
+    "\n"
+    "      bundle_data(\"${app_name}_bundle_info_plist\") {\n"
+    "        deps = [ \":${app_name}_generate_info_plist\" ]\n"
+    "        sources = [ \"$gen_path/Info.plist\" ]\n"
+    "        outputs = [ \"{{bundle_root_dir}}/Info.plist\" ]\n"
+    "      }\n"
+    "\n"
+    "      executable(\"${app_name}_generate_executable\") {\n"
+    "        forward_variables_from(invoker, \"*\", [\n"
+    "                                                \"output_name\",\n"
+    "                                                \"visibility\",\n"
+    "                                               ])\n"
+    "        output_name =\n"
+    "            rebase_path(\"$gen_path/$app_name\", root_build_dir)\n"
+    "      }\n"
+    "\n"
+    "      bundle_data(\"${app_name}_bundle_executable\") {\n"
+    "        deps = [ \":${app_name}_generate_executable\" ]\n"
+    "        sources = [ \"$gen_path/$app_name\" ]\n"
+    "        outputs = [ \"{{bundle_executable_dir}}/$app_name\" ]\n"
+    "      }\n"
+    "\n"
+    "      create_bundle(\"${app_name}.app\") {\n"
+    "        deps = [\n"
+    "          \":${app_name}_bundle_executable\",\n"
+    "          \":${app_name}_bundle_info_plist\",\n"
+    "        ]\n"
+    "        if (is_ios) {\n"
+    "          bundle_root_dir = \"${root_build_dir}/$target_name\"\n"
+    "          bundle_resources_dir = bundle_root_dir\n"
+    "          bundle_executable_dir = bundle_root_dir\n"
+    "          bundle_plugins_dir = bundle_root_dir + \"/Plugins\"\n"
+    "        } else {\n"
+    "          bundle_root_dir = \"${root_build_dir}/target_name/Contents\"\n"
+    "          bundle_resources_dir = bundle_root_dir + \"/Resources\"\n"
+    "          bundle_executable_dir = bundle_root_dir + \"/MacOS\"\n"
+    "          bundle_plugins_dir = bundle_root_dir + \"/Plugins\"\n"
+    "        }\n"
+    "      }\n"
+    "\n"
+    "      group(target_name) {\n"
+    "        forward_variables_from(invoker, [\"visibility\"])\n"
+    "        deps = [ \":${app_name}.app\" ]\n"
+    "      }\n"
+    "    }\n"
+    "  }\n";
+
+Value RunCreateBundle(Scope* scope,
+                      const FunctionCallNode* function,
+                      const std::vector<Value>& args,
+                      BlockNode* block,
+                      Err* err) {
+  return ExecuteGenericTarget(functions::kCreateBundle, scope, function, args,
+                              block, err);
+}
+
 // copy ------------------------------------------------------------------------
 
 const char kCopy[] = "copy";
diff --git a/tools/gn/gn.gyp b/tools/gn/gn.gyp
index 3cd81e3..79f83a7 100644
--- a/tools/gn/gn.gyp
+++ b/tools/gn/gn.gyp
@@ -24,8 +24,12 @@
         'builder.h',
         'builder_record.cc',
         'builder_record.h',
+        'bundle_data.cc',
+        'bundle_data.h',
         'bundle_data_target_generator.cc',
         'bundle_data_target_generator.h',
+        'bundle_file_rule.cc',
+        'bundle_file_rule.h',
         'c_include_iterator.cc',
         'c_include_iterator.h',
         'command_args.cc',
@@ -50,6 +54,8 @@
         'config_values_generator.h',
         'copy_target_generator.cc',
         'copy_target_generator.h',
+        'create_bundle_target_generator.cc',
+        'create_bundle_target_generator.h',
         'deps_iterator.cc',
         'deps_iterator.h',
         'eclipse_writer.cc',
@@ -116,6 +122,8 @@
         'ninja_bundle_data_target_writer.h',
         'ninja_copy_target_writer.cc',
         'ninja_copy_target_writer.h',
+        'ninja_create_bundle_target_writer.cc',
+        'ninja_create_bundle_target_writer.h',
         'ninja_group_target_writer.cc',
         'ninja_group_target_writer.h',
         'ninja_target_writer.cc',
@@ -247,6 +255,7 @@
         'ninja_action_target_writer_unittest.cc',
         'ninja_binary_target_writer_unittest.cc',
         'ninja_copy_target_writer_unittest.cc',
+        'ninja_create_bundle_target_writer_unittest.cc',
         'ninja_group_target_writer_unittest.cc',
         'ninja_target_writer_unittest.cc',
         'ninja_toolchain_writer_unittest.cc',
diff --git a/tools/gn/ninja_create_bundle_target_writer.cc b/tools/gn/ninja_create_bundle_target_writer.cc
new file mode 100644
index 0000000..b92001d6
--- /dev/null
+++ b/tools/gn/ninja_create_bundle_target_writer.cc
@@ -0,0 +1,115 @@
+// 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 "tools/gn/ninja_create_bundle_target_writer.h"
+
+#include "tools/gn/filesystem_utils.h"
+#include "tools/gn/ninja_utils.h"
+#include "tools/gn/output_file.h"
+#include "tools/gn/scheduler.h"
+#include "tools/gn/substitution_writer.h"
+#include "tools/gn/target.h"
+#include "tools/gn/toolchain.h"
+
+namespace {
+
+void FailWithMissingToolError(Toolchain::ToolType tool, const Target* target) {
+  const std::string& tool_name = Toolchain::ToolTypeToName(tool);
+  g_scheduler->FailWithError(Err(
+      nullptr, tool_name + " tool not defined",
+      "The toolchain " +
+          target->toolchain()->label().GetUserVisibleName(false) + "\n"
+          "used by target " + target->label().GetUserVisibleName(false) + "\n"
+          "doesn't define a \"" + tool_name + "\" tool."));
+}
+
+}  // namespace
+
+NinjaCreateBundleTargetWriter::NinjaCreateBundleTargetWriter(
+    const Target* target,
+    std::ostream& out)
+    : NinjaTargetWriter(target, out) {}
+
+NinjaCreateBundleTargetWriter::~NinjaCreateBundleTargetWriter() {}
+
+void NinjaCreateBundleTargetWriter::Run() {
+  if (!target_->toolchain()->GetTool(Toolchain::TYPE_COPY_BUNDLE_DATA)) {
+    FailWithMissingToolError(Toolchain::TYPE_COPY_BUNDLE_DATA, target_);
+    return;
+  }
+
+  if (!target_->toolchain()->GetTool(Toolchain::TYPE_COMPILE_XCASSETS)) {
+    FailWithMissingToolError(Toolchain::TYPE_COMPILE_XCASSETS, target_);
+    return;
+  }
+
+  if (!target_->toolchain()->GetTool(Toolchain::TYPE_STAMP)) {
+    FailWithMissingToolError(Toolchain::TYPE_STAMP, target_);
+    return;
+  }
+
+  std::vector<OutputFile> output_files;
+  OutputFile input_dep =
+      WriteInputDepsStampAndGetDep(std::vector<const Target*>());
+
+  for (const BundleFileRule& file_rule : target_->bundle_data().file_rules()) {
+    for (const SourceFile& source_file : file_rule.sources()) {
+      OutputFile output_file = file_rule.ApplyPatternToSourceAsOutputFile(
+          settings_, target_->bundle_data(), source_file);
+      output_files.push_back(output_file);
+
+      out_ << "build ";
+      path_output_.WriteFile(out_, output_file);
+      out_ << ": "
+           << GetNinjaRulePrefixForToolchain(settings_)
+           << Toolchain::ToolTypeToName(Toolchain::TYPE_COPY_BUNDLE_DATA)
+           << " ";
+      path_output_.WriteFile(out_, source_file);
+      if (!input_dep.value().empty()) {
+        out_ << " || ";
+        path_output_.WriteFile(out_, input_dep);
+      }
+      out_ << std::endl;
+    }
+  }
+
+  if (!target_->bundle_data().asset_catalog_sources().empty()) {
+    OutputFile output_file(
+        settings_->build_settings(),
+        target_->bundle_data().GetCompiledAssetCatalogPath());
+    output_files.push_back(output_file);
+
+    out_ << "build ";
+    path_output_.WriteFile(out_, output_file);
+    out_ << ": "
+         << GetNinjaRulePrefixForToolchain(settings_)
+         << Toolchain::ToolTypeToName(Toolchain::TYPE_COMPILE_XCASSETS);
+
+    std::set<SourceFile> asset_catalog_bundles;
+    for (const auto& source : target_->bundle_data().asset_catalog_sources()) {
+      SourceFile asset_catalog_bundle;
+      CHECK(IsSourceFileFromAssetCatalog(source, &asset_catalog_bundle));
+      if (asset_catalog_bundles.find(asset_catalog_bundle) !=
+          asset_catalog_bundles.end())
+        continue;
+      out_ << " ";
+      path_output_.WriteFile(out_, asset_catalog_bundle);
+      asset_catalog_bundles.insert(asset_catalog_bundle);
+    }
+
+    out_ << " |";
+    for (const auto& source : target_->bundle_data().asset_catalog_sources()) {
+      out_ << " ";
+      path_output_.WriteFile(out_, source);
+    }
+    if (!input_dep.value().empty()) {
+      out_ << " || ";
+      path_output_.WriteFile(out_, input_dep);
+    }
+    out_ << std::endl;
+  }
+
+  out_ << std::endl;
+  WriteStampForTarget(output_files, std::vector<OutputFile>());
+}
diff --git a/tools/gn/ninja_create_bundle_target_writer.h b/tools/gn/ninja_create_bundle_target_writer.h
new file mode 100644
index 0000000..42b900f
--- /dev/null
+++ b/tools/gn/ninja_create_bundle_target_writer.h
@@ -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.
+
+#ifndef TOOLS_GN_NINJA_CREATE_BUNDLE_TARGET_WRITER_H_
+#define TOOLS_GN_NINJA_CREATE_BUNDLE_TARGET_WRITER_H_
+
+#include "base/macros.h"
+#include "tools/gn/ninja_target_writer.h"
+
+// Writes a .ninja file for a bundle_data target type.
+class NinjaCreateBundleTargetWriter : public NinjaTargetWriter {
+ public:
+  NinjaCreateBundleTargetWriter(const Target* target, std::ostream& out);
+  ~NinjaCreateBundleTargetWriter() override;
+
+  void Run() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NinjaCreateBundleTargetWriter);
+};
+
+#endif  // TOOLS_GN_NINJA_CREATE_BUNDLE_TARGET_WRITER_H_
diff --git a/tools/gn/ninja_create_bundle_target_writer_unittest.cc b/tools/gn/ninja_create_bundle_target_writer_unittest.cc
new file mode 100644
index 0000000..88e6fbab
--- /dev/null
+++ b/tools/gn/ninja_create_bundle_target_writer_unittest.cc
@@ -0,0 +1,173 @@
+// 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 "tools/gn/ninja_create_bundle_target_writer.h"
+
+#include <algorithm>
+#include <sstream>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "tools/gn/target.h"
+#include "tools/gn/test_with_scope.h"
+
+namespace {
+
+void SetupBundleDataDir(BundleData* bundle_data, const std::string& root_dir) {
+  bundle_data->root_dir().assign(root_dir + "/bar.bundle");
+  bundle_data->resources_dir().assign(bundle_data->root_dir() + "/Resources");
+  bundle_data->executable_dir().assign(bundle_data->root_dir() + "/Executable");
+  bundle_data->plugins_dir().assign(bundle_data->root_dir() + "/PlugIns");
+}
+
+}  // namespace
+
+// Tests multiple files with an output pattern.
+TEST(NinjaCreateBundleTargetWriter, Run) {
+  TestWithScope setup;
+  Err err;
+
+  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
+  Target target(setup.settings(), Label(SourceDir("//baz/"), "bar"));
+  target.set_output_type(Target::CREATE_BUNDLE);
+
+  SetupBundleDataDir(&target.bundle_data(), "//out/Debug");
+
+  std::vector<SourceFile> sources;
+  sources.push_back(SourceFile("//foo/input1.txt"));
+  sources.push_back(SourceFile("//foo/input2.txt"));
+  target.bundle_data().file_rules().push_back(BundleFileRule(
+      sources, SubstitutionPattern::MakeForTest(
+                   "{{bundle_resources_dir}}/{{source_file_part}}")));
+
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCreateBundleTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected[] =
+      "build bar.bundle/Resources/input1.txt: copy_bundle_data "
+          "../../foo/input1.txt\n"
+      "build bar.bundle/Resources/input2.txt: copy_bundle_data "
+          "../../foo/input2.txt\n"
+      "\n"
+      "build obj/baz/bar.stamp: stamp "
+          "bar.bundle/Resources/input1.txt "
+          "bar.bundle/Resources/input2.txt\n";
+  std::string out_str = out.str();
+  EXPECT_EQ(expected, out_str);
+}
+
+// Tests multiple files from asset catalog.
+TEST(NinjaCreateBundleTargetWriter, AssetCatalog) {
+  TestWithScope setup;
+  Err err;
+
+  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
+  Target target(setup.settings(), Label(SourceDir("//baz/"), "bar"));
+  target.set_output_type(Target::CREATE_BUNDLE);
+
+  SetupBundleDataDir(&target.bundle_data(), "//out/Debug");
+
+  std::vector<SourceFile>& asset_catalog_sources =
+      target.bundle_data().asset_catalog_sources();
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/Contents.json"));
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooIcon-29.png"));
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooIcon-29@2x.png"));
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooIcon-29@3x.png"));
+
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCreateBundleTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected[] =
+      "build bar.bundle/Resources/Assets.car: compile_xcassets "
+          "../../foo/Foo.xcassets | "
+          "../../foo/Foo.xcassets/foo.imageset/Contents.json "
+          "../../foo/Foo.xcassets/foo.imageset/FooIcon-29.png "
+          "../../foo/Foo.xcassets/foo.imageset/FooIcon-29@2x.png "
+          "../../foo/Foo.xcassets/foo.imageset/FooIcon-29@3x.png\n"
+      "\n"
+      "build obj/baz/bar.stamp: stamp bar.bundle/Resources/Assets.car\n";
+  std::string out_str = out.str();
+  EXPECT_EQ(expected, out_str);
+}
+
+// Tests complex target with multiple bundle_data sources, including
+// some asset catalog.
+TEST(NinjaCreateBundleTargetWriter, OrderOnlyDeps) {
+  TestWithScope setup;
+  Err err;
+
+  setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/"));
+  Target target(setup.settings(), Label(SourceDir("//baz/"), "bar"));
+  target.set_output_type(Target::CREATE_BUNDLE);
+
+  SetupBundleDataDir(&target.bundle_data(), "//out/Debug");
+
+  std::vector<SourceFile> sources1;
+  sources1.push_back(SourceFile("//foo/input1.txt"));
+  sources1.push_back(SourceFile("//foo/input2.txt"));
+  target.bundle_data().file_rules().push_back(BundleFileRule(
+      sources1, SubstitutionPattern::MakeForTest(
+                    "{{bundle_resources_dir}}/{{source_file_part}}")));
+
+  std::vector<SourceFile> sources2;
+  sources2.push_back(SourceFile("//qux/Info.plist"));
+  target.bundle_data().file_rules().push_back(BundleFileRule(
+      sources2,
+      SubstitutionPattern::MakeForTest("{{bundle_root_dir}}/Info.plist")));
+
+  std::vector<SourceFile> empty_source;
+  target.bundle_data().file_rules().push_back(BundleFileRule(
+      empty_source, SubstitutionPattern::MakeForTest(
+                        "{{bundle_plugins_dir}}/{{source_file_part}}")));
+
+  std::vector<SourceFile>& asset_catalog_sources =
+      target.bundle_data().asset_catalog_sources();
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/Contents.json"));
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooIcon-29.png"));
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooIcon-29@2x.png"));
+  asset_catalog_sources.push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooIcon-29@3x.png"));
+
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCreateBundleTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected[] =
+      "build bar.bundle/Resources/input1.txt: copy_bundle_data "
+          "../../foo/input1.txt\n"
+      "build bar.bundle/Resources/input2.txt: copy_bundle_data "
+          "../../foo/input2.txt\n"
+      "build bar.bundle/Info.plist: copy_bundle_data ../../qux/Info.plist\n"
+      "build bar.bundle/Resources/Assets.car: compile_xcassets "
+          "../../foo/Foo.xcassets | "
+          "../../foo/Foo.xcassets/foo.imageset/Contents.json "
+          "../../foo/Foo.xcassets/foo.imageset/FooIcon-29.png "
+          "../../foo/Foo.xcassets/foo.imageset/FooIcon-29@2x.png "
+          "../../foo/Foo.xcassets/foo.imageset/FooIcon-29@3x.png\n"
+      "\n"
+      "build obj/baz/bar.stamp: stamp "
+          "bar.bundle/Resources/input1.txt "
+          "bar.bundle/Resources/input2.txt "
+          "bar.bundle/Info.plist "
+          "bar.bundle/Resources/Assets.car\n";
+  std::string out_str = out.str();
+  EXPECT_EQ(expected, out_str);
+}
diff --git a/tools/gn/ninja_target_writer.cc b/tools/gn/ninja_target_writer.cc
index f4de7f2..486930b 100644
--- a/tools/gn/ninja_target_writer.cc
+++ b/tools/gn/ninja_target_writer.cc
@@ -15,6 +15,7 @@
 #include "tools/gn/ninja_binary_target_writer.h"
 #include "tools/gn/ninja_bundle_data_target_writer.h"
 #include "tools/gn/ninja_copy_target_writer.h"
+#include "tools/gn/ninja_create_bundle_target_writer.h"
 #include "tools/gn/ninja_group_target_writer.h"
 #include "tools/gn/ninja_utils.h"
 #include "tools/gn/output_file.h"
@@ -61,6 +62,9 @@
   if (target->output_type() == Target::BUNDLE_DATA) {
     NinjaBundleDataTargetWriter writer(target, file);
     writer.Run();
+  } else if (target->output_type() == Target::CREATE_BUNDLE) {
+    NinjaCreateBundleTargetWriter writer(target, file);
+    writer.Run();
   } else if (target->output_type() == Target::COPY_FILES) {
     NinjaCopyTargetWriter writer(target, file);
     writer.Run();
diff --git a/tools/gn/substitution_type.cc b/tools/gn/substitution_type.cc
index 93a32bd..e1ea14de 100644
--- a/tools/gn/substitution_type.cc
+++ b/tools/gn/substitution_type.cc
@@ -208,6 +208,11 @@
          type == SUBSTITUTION_SOURCE;
 }
 
+bool IsValidCompileXCassetsSubstitution(SubstitutionType type) {
+  return IsValidToolSubstitution(type) ||
+         type == SUBSTITUTION_LINKER_INPUTS;
+}
+
 bool EnsureValidSourcesSubstitutions(
     const std::vector<SubstitutionType>& types,
     const ParseNode* origin,
diff --git a/tools/gn/substitution_type.h b/tools/gn/substitution_type.h
index 96ae33a..3f7ec971 100644
--- a/tools/gn/substitution_type.h
+++ b/tools/gn/substitution_type.h
@@ -32,7 +32,7 @@
   SUBSTITUTION_SOURCE_OUT_DIR,  // {{source_out_dir}}
 
   // Valid for all compiler and linker tools. These depend on the target and
-  // no not vary on a per-file basis.
+  // do not vary on a per-file basis.
   SUBSTITUTION_LABEL,  // {{label}}
   SUBSTITUTION_LABEL_NAME,  // {{label_name}}
   SUBSTITUTION_ROOT_GEN_DIR,  // {{root_gen_dir}}
@@ -117,6 +117,7 @@
 bool IsValidLinkerSubstitution(SubstitutionType type);
 bool IsValidLinkerOutputsSubstitution(SubstitutionType type);
 bool IsValidCopySubstitution(SubstitutionType type);
+bool IsValidCompileXCassetsSubstitution(SubstitutionType type);
 
 // Like the "IsValid..." version above but checks a list of types and sets a
 // an error blaming the given source if the test fails.
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index 9435d47..714fd911 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -224,6 +224,8 @@
       return "ActionForEach";
     case BUNDLE_DATA:
       return "Bundle data";
+    case CREATE_BUNDLE:
+      return "Create bundle";
     default:
       return "";
   }
@@ -277,6 +279,7 @@
     all_libs_.append(cur.libs().begin(), cur.libs().end());
   }
 
+  PullRecursiveBundleData();
   PullDependentTargetLibs();
   PullRecursiveHardDeps();
   if (!ResolvePrecompiledHeaders(err))
@@ -318,6 +321,7 @@
          output_type_ == ACTION ||
          output_type_ == ACTION_FOREACH ||
          output_type_ == COPY_FILES ||
+         output_type_ == CREATE_BUNDLE ||
          (output_type_ == STATIC_LIBRARY && complete_static_lib_);
 }
 
@@ -476,12 +480,48 @@
   }
 }
 
+void Target::PullRecursiveBundleData() {
+  if (output_type_ != CREATE_BUNDLE)
+    return;
+
+  std::set<const Target*> visited;
+  std::vector<const Target*> deps;
+  deps.push_back(this);
+
+  while (!deps.empty()) {
+    const Target* current = deps.back();
+    deps.pop_back();
+
+    if (visited.find(current) != visited.end())
+      continue;
+    visited.insert(current);
+
+    if (current->output_type_ == BUNDLE_DATA)
+      bundle_data_.AddFileRuleFromTarget(current);
+
+    for (const LabelTargetPair& pair : current->GetDeps(DEPS_ALL)) {
+      DCHECK(pair.ptr);
+      DCHECK(pair.ptr->toolchain_);
+      if (visited.find(pair.ptr) != visited.end())
+        continue;
+
+      if (pair.ptr->output_type() == CREATE_BUNDLE)
+        continue;
+
+      deps.push_back(pair.ptr);
+    }
+  }
+
+  bundle_data_.GetSourceFiles(&sources_);
+}
+
 void Target::FillOutputFiles() {
   const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
   bool check_tool_outputs = false;
   switch (output_type_) {
     case GROUP:
     case BUNDLE_DATA:
+    case CREATE_BUNDLE:
     case SOURCE_SET:
     case COPY_FILES:
     case ACTION:
@@ -547,6 +587,10 @@
       NOTREACHED();
   }
 
+  // Count anything generated from bundle_data dependencies.
+  if (output_type_ == CREATE_BUNDLE)
+    bundle_data_.GetOutputFiles(settings(), &computed_outputs_);
+
   // Count all outputs from this tool as something generated by this target.
   if (check_tool_outputs) {
     SubstitutionWriter::ApplyListToLinkerAsOutputFile(
diff --git a/tools/gn/target.h b/tools/gn/target.h
index 9afd0fa..95e682f 100644
--- a/tools/gn/target.h
+++ b/tools/gn/target.h
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "tools/gn/action_values.h"
+#include "tools/gn/bundle_data.h"
 #include "tools/gn/config_values.h"
 #include "tools/gn/inherited_libraries.h"
 #include "tools/gn/item.h"
@@ -45,6 +46,7 @@
     ACTION,
     ACTION_FOREACH,
     BUNDLE_DATA,
+    CREATE_BUNDLE,
   };
 
   enum DepsIterationType {
@@ -136,12 +138,18 @@
   const std::vector<std::string>& data() const { return data_; }
   std::vector<std::string>& data() { return data_; }
 
+  // Information about the bundle. Only valid for CREATE_BUNDLE target after
+  // they have been resolved.
+  const BundleData& bundle_data() const { return bundle_data_; }
+  BundleData& bundle_data() { return bundle_data_; }
+
   // Returns true if targets depending on this one should have an order
   // dependency.
   bool hard_dep() const {
     return output_type_ == ACTION ||
            output_type_ == ACTION_FOREACH ||
-           output_type_ == COPY_FILES;
+           output_type_ == COPY_FILES ||
+           output_type_ == CREATE_BUNDLE;
   }
 
   // Returns the iterator range which can be used in range-based for loops
@@ -284,6 +292,7 @@
   void PullDependentTargetLibsFrom(const Target* dep, bool is_public);
   void PullDependentTargetLibs();
   void PullRecursiveHardDeps();
+  void PullRecursiveBundleData();
 
   // Fills the link and dependency output files when a target is resolved.
   void FillOutputFiles();
@@ -312,6 +321,7 @@
   bool testonly_;
   FileList inputs_;
   std::vector<std::string> data_;
+  BundleData bundle_data_;
 
   LabelTargetVector private_deps_;
   LabelTargetVector public_deps_;
diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc
index 0a833a0..f5b4ec812 100644
--- a/tools/gn/target_generator.cc
+++ b/tools/gn/target_generator.cc
@@ -12,6 +12,7 @@
 #include "tools/gn/bundle_data_target_generator.h"
 #include "tools/gn/config.h"
 #include "tools/gn/copy_target_generator.h"
+#include "tools/gn/create_bundle_target_generator.h"
 #include "tools/gn/err.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/functions.h"
@@ -92,6 +93,10 @@
     BundleDataTargetGenerator generator(
         target.get(), scope, function_call, err);
     generator.Run();
+  } else if (output_type == functions::kCreateBundle) {
+    CreateBundleTargetGenerator generator(target.get(), scope, function_call,
+                                          err);
+    generator.Run();
   } else if (output_type == functions::kCopy) {
     CopyTargetGenerator generator(target.get(), scope, function_call, err);
     generator.Run();
diff --git a/tools/gn/target_unittest.cc b/tools/gn/target_unittest.cc
index 8376fff..8f6684f 100644
--- a/tools/gn/target_unittest.cc
+++ b/tools/gn/target_unittest.cc
@@ -763,3 +763,66 @@
   a2.assert_no_deps().push_back(disallow_a);
   ASSERT_TRUE(a2.OnResolved(&err));
 }
+
+TEST(Target, PullRecursiveBundleData) {
+  TestWithScope setup;
+  Err err;
+
+  // We have the following dependency graph:
+  // A (create_bundle) -> B (bundle_data)
+  //                  \-> C (create_bundle) -> D (bundle_data)
+  //                  \-> E (group) -> F (bundle_data)
+  //                               \-> B (bundle_data)
+  TestTarget a(setup, "//foo:a", Target::CREATE_BUNDLE);
+  TestTarget b(setup, "//foo:b", Target::BUNDLE_DATA);
+  TestTarget c(setup, "//foo:c", Target::CREATE_BUNDLE);
+  TestTarget d(setup, "//foo:d", Target::BUNDLE_DATA);
+  TestTarget e(setup, "//foo:e", Target::GROUP);
+  TestTarget f(setup, "//foo:f", Target::BUNDLE_DATA);
+  a.public_deps().push_back(LabelTargetPair(&b));
+  a.public_deps().push_back(LabelTargetPair(&c));
+  a.public_deps().push_back(LabelTargetPair(&e));
+  c.public_deps().push_back(LabelTargetPair(&d));
+  e.public_deps().push_back(LabelTargetPair(&f));
+  e.public_deps().push_back(LabelTargetPair(&b));
+
+  b.sources().push_back(SourceFile("//foo/b1.txt"));
+  b.sources().push_back(SourceFile("//foo/b2.txt"));
+  b.action_values().outputs() = SubstitutionList::MakeForTest(
+      "{{bundle_resources_dir}}/{{source_file_part}}");
+  ASSERT_TRUE(b.OnResolved(&err));
+
+  d.sources().push_back(SourceFile("//foo/d.txt"));
+  d.action_values().outputs() = SubstitutionList::MakeForTest(
+      "{{bundle_resources_dir}}/{{source_file_part}}");
+  ASSERT_TRUE(d.OnResolved(&err));
+
+  f.sources().push_back(SourceFile("//foo/f1.txt"));
+  f.sources().push_back(SourceFile("//foo/f2.txt"));
+  f.sources().push_back(SourceFile("//foo/f3.txt"));
+  f.sources().push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/Contents.json"));
+  f.sources().push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooEmpty-29.png"));
+  f.sources().push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooEmpty-29@2x.png"));
+  f.sources().push_back(
+      SourceFile("//foo/Foo.xcassets/foo.imageset/FooEmpty-29@3x.png"));
+  f.action_values().outputs() = SubstitutionList::MakeForTest(
+      "{{bundle_resources_dir}}/{{source_file_part}}");
+  ASSERT_TRUE(f.OnResolved(&err));
+
+  ASSERT_TRUE(e.OnResolved(&err));
+  ASSERT_TRUE(c.OnResolved(&err));
+  ASSERT_TRUE(a.OnResolved(&err));
+
+  // A gets its data from B and F.
+  ASSERT_EQ(a.bundle_data().file_rules().size(), 2u);
+  ASSERT_EQ(a.bundle_data().file_rules()[0].sources().size(), 2u);
+  ASSERT_EQ(a.bundle_data().file_rules()[1].sources().size(), 3u);
+  ASSERT_EQ(a.bundle_data().asset_catalog_sources().size(), 4u);
+
+  // C gets its data from D.
+  ASSERT_EQ(c.bundle_data().file_rules().size(), 1u);
+  ASSERT_EQ(c.bundle_data().file_rules()[0].sources().size(), 1u);
+}
diff --git a/tools/gn/test_with_scope.cc b/tools/gn/test_with_scope.cc
index 8890338..2be27fa 100644
--- a/tools/gn/test_with_scope.cc
+++ b/tools/gn/test_with_scope.cc
@@ -138,6 +138,18 @@
   SetCommandForTool("cp {{source}} {{output}}", copy_tool.get());
   toolchain->SetTool(Toolchain::TYPE_COPY, std::move(copy_tool));
 
+  // COPY_BUNDLE_DATA
+  scoped_ptr<Tool> copy_bundle_data_tool(new Tool);
+  SetCommandForTool("cp {{source}} {{output}}", copy_bundle_data_tool.get());
+  toolchain->SetTool(Toolchain::TYPE_COPY_BUNDLE_DATA,
+                     std::move(copy_bundle_data_tool));
+
+  // COMPILE_XCASSETS
+  scoped_ptr<Tool> compile_xcassets_tool(new Tool);
+  SetCommandForTool("touch {{output}}", compile_xcassets_tool.get());
+  toolchain->SetTool(Toolchain::TYPE_COMPILE_XCASSETS,
+                     std::move(compile_xcassets_tool));
+
   toolchain->ToolchainSetupComplete();
 }
 
diff --git a/tools/gn/toolchain.cc b/tools/gn/toolchain.cc
index ee8e7e8..280fb12 100644
--- a/tools/gn/toolchain.cc
+++ b/tools/gn/toolchain.cc
@@ -24,6 +24,8 @@
 const char* Toolchain::kToolLink = "link";
 const char* Toolchain::kToolStamp = "stamp";
 const char* Toolchain::kToolCopy = "copy";
+const char* Toolchain::kToolCopyBundleData = "copy_bundle_data";
+const char* Toolchain::kToolCompileXCAssets = "compile_xcassets";
 
 Toolchain::Toolchain(const Settings* settings, const Label& label)
     : Item(settings, label),
@@ -56,6 +58,8 @@
   if (str == kToolLink) return TYPE_LINK;
   if (str == kToolStamp) return TYPE_STAMP;
   if (str == kToolCopy) return TYPE_COPY;
+  if (str == kToolCopyBundleData) return TYPE_COPY_BUNDLE_DATA;
+  if (str == kToolCompileXCAssets) return TYPE_COMPILE_XCASSETS;
   return TYPE_NONE;
 }
 
@@ -74,6 +78,8 @@
     case TYPE_LINK: return kToolLink;
     case TYPE_STAMP: return kToolStamp;
     case TYPE_COPY: return kToolCopy;
+    case TYPE_COPY_BUNDLE_DATA: return kToolCopyBundleData;
+    case TYPE_COMPILE_XCASSETS: return kToolCompileXCAssets;
     default:
       NOTREACHED();
       return std::string();
@@ -154,6 +160,7 @@
     case Target::ACTION:
     case Target::ACTION_FOREACH:
     case Target::BUNDLE_DATA:
+    case Target::CREATE_BUNDLE:
     case Target::COPY_FILES:
       return TYPE_STAMP;
     default:
diff --git a/tools/gn/toolchain.h b/tools/gn/toolchain.h
index bcc70c06..47a3a44 100644
--- a/tools/gn/toolchain.h
+++ b/tools/gn/toolchain.h
@@ -44,6 +44,8 @@
     TYPE_LINK,
     TYPE_STAMP,
     TYPE_COPY,
+    TYPE_COPY_BUNDLE_DATA,
+    TYPE_COMPILE_XCASSETS,
 
     TYPE_NUMTYPES  // Must be last.
   };
@@ -60,6 +62,8 @@
   static const char* kToolLink;
   static const char* kToolStamp;
   static const char* kToolCopy;
+  static const char* kToolCopyBundleData;
+  static const char* kToolCompileXCAssets;
 
   Toolchain(const Settings* settings, const Label& label);
   ~Toolchain() override;
diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc
index 0242904..fd7800f8 100644
--- a/tools/gn/variables.cc
+++ b/tools/gn/variables.cc
@@ -434,6 +434,81 @@
     "    ]\n"
     "  }\n";
 
+const char kBundleRootDir[] = "bundle_root_dir";
+const char kBundleRootDir_HelpShort[] =
+    "bundle_root_dir: Expansion of {{bundle_root_dir}} in create_bundle.";
+const char kBundleRootDir_Help[] =
+    "bundle_root_dir: Expansion of {{bundle_root_dir}} in create_bundle.\n"
+    "\n"
+    "  A string corresponding to a path in root_build_dir.\n"
+    "\n"
+    "  This string is used by the \"create_bundle\" target to expand the\n"
+    "  {{bundle_root_dir}} of the \"bundle_data\" target it depends on.\n"
+    "  This must correspond to a path under root_build_dir.\n"
+    "\n"
+    "Example\n"
+    "\n"
+    "  bundle_data(\"info_plist\") {\n"
+    "    sources = [ \"Info.plist\" ]\n"
+    "    outputs = [ \"{{bundle_root_dir}}/Info.plist\" ]\n"
+    "  }\n"
+    "\n"
+    "  create_bundle(\"doom_melon.app\") {\n"
+    "    deps = [ \":info_plist\" ]\n"
+    "    bundle_root_dir = root_build_dir + \"/doom_melon.app/Contents\"\n"
+    "    bundle_resources_dir = bundle_root_dir + \"/Resources\"\n"
+    "    bundle_executable_dir = bundle_root_dir + \"/MacOS\"\n"
+    "    bundle_plugins_dir = bundle_root_dir + \"/PlugIns\"\n"
+    "  }\n";
+
+const char kBundleResourcesDir[] = "bundle_resources_dir";
+const char kBundleResourcesDir_HelpShort[] =
+    "bundle_resources_dir: "
+        "Expansion of {{bundle_resources_dir}} in create_bundle.";
+const char kBundleResourcesDir_Help[] =
+    "bundle_resources_dir: "
+        "Expansion of {{bundle_resources_dir}} in create_bundle.\n"
+    "\n"
+    "  A string corresponding to a path in $root_build_dir.\n"
+    "\n"
+    "  This string is used by the \"create_bundle\" target to expand the\n"
+    "  {{bundle_resources_dir}} of the \"bundle_data\" target it depends on.\n"
+    "  This must correspond to a path under \"bundle_root_dir\".\n"
+    "\n"
+    "  See \"gn help bundle_root_dir\" for examples.\n";
+
+const char kBundleExecutableDir[] = "bundle_executable_dir";
+const char kBundleExecutableDir_HelpShort[] =
+    "bundle_executable_dir: "
+        "Expansion of {{bundle_executable_dir}} in create_bundle.";
+const char kBundleExecutableDir_Help[] =
+    "bundle_executable_dir: "
+        "Expansion of {{bundle_executable_dir}} in create_bundle.\n"
+    "\n"
+    "  A string corresponding to a path in $root_build_dir.\n"
+    "\n"
+    "  This string is used by the \"create_bundle\" target to expand the\n"
+    "  {{bundle_executable_dir}} of the \"bundle_data\" target it depends on.\n"
+    "  This must correspond to a path under \"bundle_root_dir\".\n"
+    "\n"
+    "  See \"gn help bundle_root_dir\" for examples.\n";
+
+const char kBundlePlugInsDir[] = "bundle_plugins_dir";
+const char kBundlePlugInsDir_HelpShort[] =
+    "bundle_plugins_dir: "
+        "Expansion of {{bundle_plugins_dir}} in create_bundle.";
+const char kBundlePlugInsDir_Help[] =
+    "bundle_plugins_dir: "
+        "Expansion of {{bundle_plugins_dir}} in create_bundle.\n"
+    "\n"
+    "  A string corresponding to a path in $root_build_dir.\n"
+    "\n"
+    "  This string is used by the \"create_bundle\" target to expand the\n"
+    "  {{bundle_plugins_dir}} of the \"bundle_data\" target it depends on.\n"
+    "  This must correspond to a path under \"bundle_root_dir\".\n"
+    "\n"
+    "  See \"gn help bundle_root_dir\" for examples.\n";
+
 const char kCflags[] = "cflags";
 const char kCflags_HelpShort[] =
     "cflags: [string list] Flags passed to all C compiler variants.";
@@ -1457,6 +1532,10 @@
     INSERT_VARIABLE(Args)
     INSERT_VARIABLE(Asmflags)
     INSERT_VARIABLE(AssertNoDeps)
+    INSERT_VARIABLE(BundleRootDir)
+    INSERT_VARIABLE(BundleResourcesDir)
+    INSERT_VARIABLE(BundleExecutableDir)
+    INSERT_VARIABLE(BundlePlugInsDir)
     INSERT_VARIABLE(Cflags)
     INSERT_VARIABLE(CflagsC)
     INSERT_VARIABLE(CflagsCC)
diff --git a/tools/gn/variables.h b/tools/gn/variables.h
index ee68bd52..45fa0eb 100644
--- a/tools/gn/variables.h
+++ b/tools/gn/variables.h
@@ -91,6 +91,22 @@
 extern const char kAssertNoDeps_HelpShort[];
 extern const char kAssertNoDeps_Help[];
 
+extern const char kBundleRootDir[];
+extern const char kBundleRootDir_HelpShort[];
+extern const char kBundleRootDir_Help[];
+
+extern const char kBundleResourcesDir[];
+extern const char kBundleResourcesDir_HelpShort[];
+extern const char kBundleResourcesDir_Help[];
+
+extern const char kBundleExecutableDir[];
+extern const char kBundleExecutableDir_HelpShort[];
+extern const char kBundleExecutableDir_Help[];
+
+extern const char kBundlePlugInsDir[];
+extern const char kBundlePlugInsDir_HelpShort[];
+extern const char kBundlePlugInsDir_Help[];
+
 extern const char kCflags[];
 extern const char kCflags_HelpShort[];
 extern const char* kCflags_Help;
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids
index fe95f0d7..c8dc083a 100644
--- a/tools/gritsettings/resource_ids
+++ b/tools/gritsettings/resource_ids
@@ -203,6 +203,9 @@
   "ios/chrome/app/theme/ios_theme_resources.grd": {
     "structures": [25870],
   },
+  "ios/chrome/share_extension/strings/ios_share_extension_strings.grd": {
+    "messages": [26325],
+  },
   "ios/chrome/today_extension/strings/ios_today_extension_strings.grd": {
     "messages": [26335],
   },
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 7e192cd..0f3b752 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -22047,12 +22047,12 @@
   </summary>
 </histogram>
 
-<histogram name="Mojo.Shell.RenderProcessInitializationTime" units="ms">
+<histogram name="Mojo.Shell.ChildConnectionTime" units="ms">
   <owner>rockot@chromium.org</owner>
   <summary>
-    Measures the time it takes for a new render process to receive an
+    Measures the time it takes for a new child process to receive an
     initialization request from the Mojo shell. This is precisely the duration
-    of the MojoShellConnectionImpl::Create() call in RendererMain.
+    of the MojoShellConnectionImpl::BindToMessagePipe() call in ChildThreadImpl.
   </summary>
 </histogram>
 
@@ -27037,6 +27037,16 @@
   </summary>
 </histogram>
 
+<histogram name="Net.QuicSession.GoAwayReceivedForConnectionMigration"
+    enum="BooleanReceived">
+  <owner>zhongyi@chromium.org</owner>
+  <summary>
+    Whether QuicGoAwayFrame is received from server for connection migration due
+    to client's port change. Logged when a QuicGoAwayFrame with error code
+    QUIC_ERROR_MIGRATING_PORT is received.
+  </summary>
+</histogram>
+
 <histogram name="Net.QuicSession.HandshakeConfirmedTime" units="Milliseconds">
   <owner>rch@chromium.org</owner>
   <summary>
@@ -64452,6 +64462,7 @@
              ChromeOS version"/>
   <int value="320" label="Control use of the Web Bluetooth API"/>
   <int value="321" label="Configure the login authentication behavior"/>
+  <int value="322" label="Whitelist of USB detachable devices"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations" type="int">
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py
index 68e11c8..57cc73a 100644
--- a/tools/perf/benchmarks/v8.py
+++ b/tools/perf/benchmarks/v8.py
@@ -60,15 +60,9 @@
     return 'v8.detached_context_age_in_gc'
 
 
-# Disabled on reference builds because they don't support the new
-# Tracing.requestMemoryDump DevTools API. See http://crbug.com/540022.
-@benchmark.Disabled('reference', 'android')  # crbug.com/579546
-@benchmark.Disabled('win')  # https://crbug.com/590747
-class V8InfiniteScroll(perf_benchmark.PerfBenchmark):
-  """Measures V8 GC metrics and memory usage while scrolling the top web pages.
-  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
-
-  page_set = page_sets.InfiniteScrollPageSet
+class _InfiniteScrollBenchmark(perf_benchmark.PerfBenchmark):
+  """ Base class for infinite scroll benchmarks.
+  """
 
   def SetExtraBrowserOptions(self, options):
     existing_js_flags = []
@@ -79,6 +73,8 @@
         # TODO(perezju): Temporary workaround to disable periodic memory dumps.
         # See: http://crbug.com/513692
         '--enable-memory-benchmarking',
+        # Disable push notifications for Facebook.
+        '--disable-notifications',
         # This overrides any existing --js-flags, hence we have to include the
         # previous flags as well.
         '--js-flags="--heap-growing-percent=10 %s"' %
@@ -104,11 +100,7 @@
     return options
 
   @classmethod
-  def Name(cls):
-    return 'v8.infinite_scroll'
-
-  @classmethod
-  def ValueCanBeAddedPredicate(cls, value, is_first_result):
+  def ValueCanBeAddedPredicate(cls, value, _):
     if value.tir_label in ['Load', 'Wait']:
       return (value.name.startswith('v8_') and not
               value.name.startswith('v8_gc'))
@@ -142,3 +134,31 @@
   @classmethod
   def ShouldTearDownStateAfterEachStoryRun(cls):
     return True
+
+
+# Disabled on reference builds because they don't support the new
+# Tracing.requestMemoryDump DevTools API. See http://crbug.com/540022.
+@benchmark.Disabled('reference', 'android')  # crbug.com/579546
+@benchmark.Disabled('win')  # https://crbug.com/590747
+class V8InfiniteScroll(_InfiniteScrollBenchmark):
+  """Measures V8 GC metrics and memory usage while scrolling the top web pages.
+  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
+
+  page_set = page_sets.InfiniteScrollPageSet
+
+  @classmethod
+  def Name(cls):
+    return 'v8.infinite_scroll'
+
+
+@benchmark.Enabled('android')
+class V8MobileInfiniteScroll(_InfiniteScrollBenchmark):
+  """Measures V8 GC metrics and memory usage while scrolling the top mobile
+  web pages.
+  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
+
+  page_set = page_sets.MobileInfiniteScrollPageSet
+
+  @classmethod
+  def Name(cls):
+    return 'v8.mobile_infinite_scroll'
diff --git a/tools/perf/page_sets/data/credentials.json.sha1 b/tools/perf/page_sets/data/credentials.json.sha1
index 41077589..e370b674 100644
--- a/tools/perf/page_sets/data/credentials.json.sha1
+++ b/tools/perf/page_sets/data/credentials.json.sha1
@@ -1 +1 @@
-bf4de6267c1908c2a3ac7ec30a12545a46b23e24
\ No newline at end of file
+907441a3a665af8de6fead6472d0fb5e214ed97f
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/mobile_infinite_scroll.json b/tools/perf/page_sets/data/mobile_infinite_scroll.json
new file mode 100644
index 0000000..68f3f4c
--- /dev/null
+++ b/tools/perf/page_sets/data/mobile_infinite_scroll.json
@@ -0,0 +1,12 @@
+{
+    "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.", 
+    "archives": {
+        "mobile_infinite_scroll_000.wpr": [
+            "facebook", 
+            "flickr", 
+            "tumblr", 
+            "discourse", 
+            "twitter"
+        ]
+    }
+}
\ No newline at end of file
diff --git a/tools/perf/page_sets/data/mobile_infinite_scroll_000.wpr.sha1 b/tools/perf/page_sets/data/mobile_infinite_scroll_000.wpr.sha1
new file mode 100644
index 0000000..55d18b8b
--- /dev/null
+++ b/tools/perf/page_sets/data/mobile_infinite_scroll_000.wpr.sha1
@@ -0,0 +1 @@
+36df7ee7e6088363f3743ad28b467cba4c54b328
\ No newline at end of file
diff --git a/tools/perf/page_sets/login_helpers/login_utils.py b/tools/perf/page_sets/login_helpers/login_utils.py
index a58a64c..5e9bbe07 100644
--- a/tools/perf/page_sets/login_helpers/login_utils.py
+++ b/tools/perf/page_sets/login_helpers/login_utils.py
@@ -27,6 +27,27 @@
   c = credentials.get(credential)
   return c['username'], c['password']
 
+def InputWithSelector(action_runner, input_text, input_selector):
+  """Sets the text value of an input field in a form on the page.
+
+  Waits until the input element exists on the page. Then executes JS to populate
+  the value property of the element with |input_text|.
+
+  Args:
+    action_runner: ActionRunner instance to execute JS to populate form fields.
+    input_text: Text string to populate the input field with.
+    input_selector: The selector of the input element.
+
+
+  Raises:
+    exceptions.TimeoutException: If waiting to find the element times out.
+    exceptions.Error: See ExecuteJavaScript() for a detailed list of
+      possible exceptions.
+  """
+  action_runner.WaitForElement(selector=input_selector)
+  action_runner.ExecuteJavaScript(
+      'document.querySelector("%s").value = "%s";' %
+      (input_selector, input_text))
 
 def InputForm(action_runner, input_text, input_id, form_id=None):
   """Sets the text value of an input field in a form on the page.
@@ -51,7 +72,5 @@
     element_selector = '#%s' % (input_id)
   else:
     raise ValueError("Input ID can not be None or empty.")
-  action_runner.WaitForElement(selector=element_selector)
-  action_runner.ExecuteJavaScript(
-      'document.querySelector("%s").value = "%s";' %
-      (element_selector, input_text))
+  InputWithSelector(action_runner, input_text, element_selector)
+
diff --git a/tools/perf/page_sets/login_helpers/mobile_facebook_login.py b/tools/perf/page_sets/login_helpers/mobile_facebook_login.py
new file mode 100644
index 0000000..d8d20734
--- /dev/null
+++ b/tools/perf/page_sets/login_helpers/mobile_facebook_login.py
@@ -0,0 +1,35 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+from page_sets.login_helpers import login_utils
+
+
+def LoginAccount(
+    action_runner, credential,
+    credentials_path=login_utils.DEFAULT_CREDENTIAL_PATH):
+  """Logs in into mobile Facebook account.
+
+  This function navigates the tab into Facebook's login page and logs in a user
+  using credentials in |credential| part of the |credentials_path| file.
+
+  Args:
+    action_runner: Action runner responsible for running actions on the page.
+    credential: The credential to retrieve from the credentials file
+        (type string).
+    credentials_path: The string that specifies the path to credential file.
+
+  Raises:
+    exceptions.Error: See ExecuteJavaScript()
+    for a detailed list of possible exceptions.
+  """
+  account_name, password = login_utils.GetAccountNameAndPassword(
+      credential, credentials_path=credentials_path)
+
+  action_runner.Navigate(
+       'https://m.facebook.com/login?continue=https%3A%2F%2Fm.facebook.com')
+  login_utils.InputWithSelector(action_runner, account_name, '[name=email]')
+  login_utils.InputWithSelector(action_runner, password, '[name=pass]')
+  action_runner.ClickElement(selector='[name=login]')
+  action_runner.WaitForElement(text='OK')
+  action_runner.ClickElement(text='OK')
+  action_runner.WaitForNavigate()
diff --git a/tools/perf/page_sets/mobile_facebook_page.py b/tools/perf/page_sets/mobile_facebook_page.py
new file mode 100644
index 0000000..edd93a04
--- /dev/null
+++ b/tools/perf/page_sets/mobile_facebook_page.py
@@ -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.
+
+from page_sets.login_helpers import mobile_facebook_login
+
+from telemetry.page import page as page_module
+
+class MobileFacebookPage(page_module.Page):
+  def __init__(self, url, page_set, shared_page_state_class, name='facebook'):
+    super(MobileFacebookPage, self).__init__(
+        url=url, page_set=page_set, name=name,
+        credentials_path='data/credentials.json',
+        shared_page_state_class=shared_page_state_class)
+  def RunNavigateSteps(self, action_runner):
+    mobile_facebook_login.LoginAccount(action_runner, 'facebook3',
+                                       self.credentials_path)
+    super(MobileFacebookPage, self).RunNavigateSteps(action_runner)
diff --git a/tools/perf/page_sets/mobile_infinite_scroll_cases.py b/tools/perf/page_sets/mobile_infinite_scroll_cases.py
new file mode 100644
index 0000000..0f626fe1
--- /dev/null
+++ b/tools/perf/page_sets/mobile_infinite_scroll_cases.py
@@ -0,0 +1,98 @@
+# 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.
+from page_sets import mobile_facebook_page
+from telemetry.page import page as page_module
+from telemetry.page import shared_page_state
+from telemetry import story
+
+TIME_TO_WAIT_BEFORE_STARTING_IN_SECONDS = 5
+SCROLL_TIMEOUT_IN_SECONDS = 120
+
+# TODO(ulan): Remove this once crbug.com/541508 is fixed.
+STARTUP_SCRIPT = '''
+    window.WebSocket = undefined;
+    window.Worker = undefined;
+    window.performance = undefined;'''
+
+def _ScrollAction(action_runner, scroll_amount, delay, repeat):
+  with action_runner.CreateInteraction('Begin'):
+    action_runner.tab.browser.DumpMemory()
+  with action_runner.CreateInteraction('Scrolling'):
+    action_runner.RepeatableBrowserDrivenScroll(
+      y_scroll_distance_ratio=scroll_amount,
+      repeat_delay_ms=delay,
+      repeat_count=repeat,
+      timeout=SCROLL_TIMEOUT_IN_SECONDS)
+  with action_runner.CreateInteraction('End'):
+    action_runner.tab.browser.DumpMemory()
+
+def _WaitAction(action_runner):
+  with action_runner.CreateInteraction('Load'):
+    action_runner.WaitForJavaScriptCondition(
+      'document.body != null && '
+      'document.body.scrollHeight > window.innerHeight && '
+      '!document.body.addEventListener("touchstart", function() {})')
+  with action_runner.CreateInteraction('Wait'):
+    action_runner.Wait(TIME_TO_WAIT_BEFORE_STARTING_IN_SECONDS)
+  with action_runner.CreateInteraction('GC'):
+    action_runner.ForceGarbageCollection()
+
+class MobileInfiniteScrollPage(page_module.Page):
+  def __init__(self, url, page_set, name, scroll_amount, delay, repeat,
+               credentials=None):
+    super(MobileInfiniteScrollPage, self).__init__(
+        url=url, page_set=page_set, name=name,
+        shared_page_state_class=shared_page_state.SharedPageState,
+       credentials_path='data/credentials.json')
+    self.credentials = credentials
+    self.script_to_evaluate_on_commit = STARTUP_SCRIPT
+    self.scroll_amount = scroll_amount
+    self.delay = delay
+    self.repeat = repeat
+
+  def RunPageInteractions(self, action_runner):
+    _WaitAction(action_runner)
+    _ScrollAction(action_runner, self.scroll_amount, self.delay,
+                       self.repeat)
+
+class MobileInfiniteScrollFacebookPage(mobile_facebook_page.MobileFacebookPage):
+  def __init__(self, url, page_set, name, scroll_amount, delay, repeat):
+    super(MobileInfiniteScrollFacebookPage, self).__init__(
+        url=url, page_set=page_set,
+        shared_page_state_class=shared_page_state.SharedPageState,
+        name=name)
+    self.script_to_evaluate_on_commit = STARTUP_SCRIPT
+    self.scroll_amount = scroll_amount
+    self.delay = delay
+    self.repeat = repeat
+
+  def RunPageInteractions(self, action_runner):
+    _WaitAction(action_runner)
+    _ScrollAction(action_runner, self.scroll_amount, self.delay,
+                       self.repeat)
+
+class MobileInfiniteScrollPageSet(story.StorySet):
+  """ Top mobile pages that can be scrolled for many pages. """
+  def __init__(self):
+    super(MobileInfiniteScrollPageSet, self).__init__(
+        archive_data_file='data/mobile_infinite_scroll.json',
+        cloud_storage_bucket=story.PARTNER_BUCKET)
+    # The scroll distance is chosen such that the page can be scrolled
+    # continuously through the test without hitting the end of the page.
+    SCROLL_FAR = 60
+    SCROLL_PAGE = 1
+    pages = [
+        ('https://m.facebook.com/shakira', 'facebook', SCROLL_FAR, 0, 0),
+        ('https://mobile.twitter.com/taylorswift13', 'twitter', SCROLL_PAGE, 10, 30),
+        ('http://techcrunch.tumblr.com/', 'tumblr', SCROLL_FAR, 0, 0),
+        ('https://www.flickr.com/explore', 'flickr', SCROLL_FAR, 0, 0),
+        ('https://meta.discourse.org/t/the-official-discourse-tags-plugin-discourse-tagging/26482',
+         'discourse', SCROLL_PAGE, 10, 30)
+    ]
+    self.AddStory(
+      MobileInfiniteScrollFacebookPage(pages[0][0], self, pages[0][1],
+                                       pages[0][2], pages[0][3], pages[0][4]))
+    for (url, name, scroll_amount, delay, repeat) in pages[1:]:
+      self.AddStory(
+        MobileInfiniteScrollPage(url, self, name, scroll_amount, delay, repeat))
diff --git a/tools/valgrind/chrome_tests.py b/tools/valgrind/chrome_tests.py
index c3f3e585..841eaf7 100755
--- a/tools/valgrind/chrome_tests.py
+++ b/tools/valgrind/chrome_tests.py
@@ -418,10 +418,6 @@
     return self.SimpleTest("mojo_public_sysperf",
                            "mojo_public_system_perftests")
 
-  def TestMojoPublicUtility(self):
-    return self.SimpleTest("mojo_public_utility",
-                           "mojo_public_utility_unittests")
-
   def TestMojoSystem(self):
     return self.SimpleTest("mojo_system", "mojo_system_unittests")
 
@@ -699,8 +695,6 @@
     "mojo_system_unittests": TestMojoSystem,
     "mojo_public_system": TestMojoPublicSystem,
     "mojo_public_system_unittests": TestMojoPublicSystem,
-    "mojo_public_utility": TestMojoPublicUtility,
-    "mojo_public_utility_unittests": TestMojoPublicUtility,
     "mojo_public_bindings": TestMojoPublicBindings,
     "mojo_public_bindings_unittests": TestMojoPublicBindings,
     "mojo_public_sysperf": TestMojoPublicSysPerf,
diff --git a/tools/valgrind/drmemory/suppressions_full.txt b/tools/valgrind/drmemory/suppressions_full.txt
index 64072da..6cf75d5 100644
--- a/tools/valgrind/drmemory/suppressions_full.txt
+++ b/tools/valgrind/drmemory/suppressions_full.txt
@@ -2128,3 +2128,10 @@
 ...
 webcore_shared.dll!blink::Document::updateStyle
 webcore_shared.dll!blink::Document::updateLayoutTree
+
+UNINITIALIZED READ
+name=bug_593594
+blink_platform.dll!qcms_transform_data_rgba_out_lut_sse2
+blink_platform.dll!qcms_transform_data_type
+blink_platform.dll!blink::JPEGImageDecoder::outputScanlines
+blink_platform.dll!blink::JPEGImageReader::decode
diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt
index 5d45b4e..a6206db5 100644
--- a/tools/valgrind/memcheck/suppressions.txt
+++ b/tools/valgrind/memcheck/suppressions.txt
@@ -3442,3 +3442,11 @@
    ...
    fun:_ZN4base4BindIMN7content21ChromeAppCacheServiceEFvRKNS_8FilePathEPNS1_15ResourceContextEPN3net23URLRequestContextGetterE13scoped_refptrIN7storage20SpecialStoragePolicyEEEJPS2_S3_S7_SB_IS9_ESE_EEENS_8CallbackINS_8internal22MakeUnboundRunTypeImplIT_JDpT0_EE4TypeEEESM_DpOSN_
 }
+{
+   bug_593913
+   Memcheck:Leak
+   fun:_Znw*
+   fun:_ZN14TestingProfile20CreateRequestContextEPSt3mapISs10linked_ptrIN3net20URLRequestJobFactory15ProtocolHandlerEESt4lessISsESaISt4pairIKSsS5_EEE12ScopedVectorINS2_21URLRequestInterceptorEE
+   fun:_ZN26ChromeContentBrowserClient20CreateRequestContextEPN7content14BrowserContextEPSt3mapISs10linked_ptrIN3net20URLRequestJobFactory15ProtocolHandlerEESt4lessISsESaISt4pairIKSsS8_EEE12ScopedVectorINS5_21URLRequestInterceptorEE
+   fun:_ZN7content23StoragePartitionImplMap3GetERKSsS2_b
+}
diff --git a/ui/OWNERS b/ui/OWNERS
index b86b2df..05a964d 100644
--- a/ui/OWNERS
+++ b/ui/OWNERS
@@ -1,9 +1,9 @@
 sadrul@chromium.org
 sky@chromium.org
+thakis@chromium.org
 
 # Mac stuff
 avi@chromium.org
-thakis@chromium.org
 
 per-file *.isolate=maruel@chromium.org
 per-file *.isolate=tandrii@chromium.org
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index 8e197e8..14a08b7 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -34,7 +34,6 @@
     "view_android.h",
     "window_android.cc",
     "window_android.h",
-    "window_android_compositor.cc",
     "window_android_compositor.h",
     "window_android_observer.h",
   ]
diff --git a/ui/android/edge_effect.cc b/ui/android/edge_effect.cc
index 5796c023..362d8fdf 100644
--- a/ui/android/edge_effect.cc
+++ b/ui/android/edge_effect.cc
@@ -6,6 +6,7 @@
 
 #include "base/macros.h"
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "ui/android/animation_utils.h"
 #include "ui/android/resources/resource_manager.h"
@@ -65,8 +66,7 @@
  public:
   EffectLayer(ui::SystemUIResourceType resource_type,
               ui::ResourceManager* resource_manager)
-      : ui_resource_layer_(cc::UIResourceLayer::Create(
-            WindowAndroidCompositor::LayerSettings())),
+      : ui_resource_layer_(cc::UIResourceLayer::Create(cc::LayerSettings())),
         resource_type_(resource_type),
         resource_manager_(resource_manager) {}
 
diff --git a/ui/android/edge_effect_l.cc b/ui/android/edge_effect_l.cc
index 3a19775..e182200 100644
--- a/ui/android/edge_effect_l.cc
+++ b/ui/android/edge_effect_l.cc
@@ -4,6 +4,7 @@
 
 #include "ui/android/edge_effect_l.h"
 
+#include "cc/layers/layer_settings.h"
 #include "cc/layers/ui_resource_layer.h"
 #include "ui/android/animation_utils.h"
 #include "ui/android/resources/resource_manager.h"
@@ -51,8 +52,7 @@
 
 EdgeEffectL::EdgeEffectL(ui::ResourceManager* resource_manager)
     : resource_manager_(resource_manager),
-      glow_(cc::UIResourceLayer::Create(
-          WindowAndroidCompositor::LayerSettings())),
+      glow_(cc::UIResourceLayer::Create(cc::LayerSettings())),
       glow_alpha_(0),
       glow_scale_y_(0),
       glow_alpha_start_(0),
diff --git a/ui/android/overscroll_glow.cc b/ui/android/overscroll_glow.cc
index 3f9fb02..be3b924 100644
--- a/ui/android/overscroll_glow.cc
+++ b/ui/android/overscroll_glow.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include "cc/layers/layer.h"
+#include "cc/layers/layer_settings.h"
 #include "ui/android/edge_effect_base.h"
 #include "ui/android/window_android_compositor.h"
 
@@ -194,7 +195,7 @@
     return true;
 
   DCHECK(!root_layer_.get());
-  root_layer_ = cc::Layer::Create(WindowAndroidCompositor::LayerSettings());
+  root_layer_ = cc::Layer::Create(cc::LayerSettings());
   for (size_t i = 0; i < EDGE_COUNT; ++i) {
     edge_effects_[i] = client_->CreateEdgeEffect();
     DCHECK(edge_effects_[i]);
diff --git a/ui/android/ui_android.gyp b/ui/android/ui_android.gyp
index d98f1d2..c818edb 100644
--- a/ui/android/ui_android.gyp
+++ b/ui/android/ui_android.gyp
@@ -47,7 +47,6 @@
         'view_android.h',
         'window_android.cc',
         'window_android.h',
-        'window_android_compositor.cc',
         'window_android_compositor.h',
         'window_android_observer.h',
       ],
diff --git a/ui/android/window_android_compositor.cc b/ui/android/window_android_compositor.cc
deleted file mode 100644
index 3fb53ea..0000000
--- a/ui/android/window_android_compositor.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 "ui/android/window_android_compositor.h"
-
-#include "base/lazy_instance.h"
-#include "cc/layers/layer_settings.h"
-
-namespace ui {
-
-namespace {
-base::LazyInstance<cc::LayerSettings> g_layer_settings =
-    LAZY_INSTANCE_INITIALIZER;
-} // anonymous namespace
-
-// static
-const cc::LayerSettings& WindowAndroidCompositor::LayerSettings() {
-  return g_layer_settings.Get();
-}
-
-// static
-void WindowAndroidCompositor::SetLayerSettings(
-    const cc::LayerSettings& settings) {
-  g_layer_settings.Get() = settings;
-}
-
-}  // namespace ui
diff --git a/ui/android/window_android_compositor.h b/ui/android/window_android_compositor.h
index 3cc333d..a6ffb33 100644
--- a/ui/android/window_android_compositor.h
+++ b/ui/android/window_android_compositor.h
@@ -10,7 +10,6 @@
 
 namespace cc {
 class Layer;
-class LayerSettings;
 }
 
 namespace ui {
@@ -20,9 +19,6 @@
 // Android interface for compositor-related tasks.
 class UI_ANDROID_EXPORT WindowAndroidCompositor {
  public:
-  static const cc::LayerSettings& LayerSettings();
-  static void SetLayerSettings(const cc::LayerSettings& settings);
-
   virtual ~WindowAndroidCompositor() {}
 
   virtual void RequestCopyOfOutputOnRootLayer(
diff --git a/ui/base/ime/input_method_auralinux.cc b/ui/base/ime/input_method_auralinux.cc
index 6e26c942..c5c0d5ef 100644
--- a/ui/base/ime/input_method_auralinux.cc
+++ b/ui/base/ime/input_method_auralinux.cc
@@ -259,6 +259,10 @@
 void InputMethodAuraLinux::CancelComposition(const TextInputClient* client) {
   if (!IsTextInputClientFocused(client))
     return;
+
+  if (GetEngine())
+    GetEngine()->Reset();
+
   ResetContext();
 }
 
diff --git a/ui/base/ime/input_method_win.cc b/ui/base/ime/input_method_win.cc
index 80a68056..0bc90529 100644
--- a/ui/base/ime/input_method_win.cc
+++ b/ui/base/ime/input_method_win.cc
@@ -242,8 +242,12 @@
 }
 
 void InputMethodWin::CancelComposition(const TextInputClient* client) {
-  if (enabled_ && IsTextInputClientFocused(client))
+  if (enabled_ && IsTextInputClientFocused(client)) {
     imm32_manager_.CancelIME(toplevel_window_handle_);
+
+    if (GetEngine())
+      GetEngine()->Reset();
+  }
 }
 
 void InputMethodWin::OnInputLocaleChanged() {
diff --git a/ui/file_manager/file_manager/common/js/file_type.js b/ui/file_manager/file_manager/common/js/file_type.js
index 95fc35d6..e6770e29 100644
--- a/ui/file_manager/file_manager/common/js/file_type.js
+++ b/ui/file_manager/file_manager/common/js/file_type.js
@@ -48,6 +48,11 @@
     pattern: /\.tiff?$/i,
     mimePattern: /image\/tiff/i
   },
+  {
+    type: 'image', name: 'IMAGE_FILE_TYPE', subtype: 'SVG',
+    pattern: /\.svg$/i,
+    mimePattern: /image\/svg\+xml/i
+  },
 
   // Raw
   {
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css
index f83f14f..c05be9d 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -127,11 +127,13 @@
 /* Details pane */
 .details-container {
   background-color: rgb(250, 250, 250);
+  display: flex;
   flex: none;
   max-width: 30%;
   min-width: 100px;
   overflow: hidden;
   position: relative;
+  width: 240px;
 }
 
 #list-details-splitter:not([activated]) {
@@ -142,6 +144,22 @@
   display: none;
 }
 
+.details-container > div:not([activated]) {
+  display: none !important;
+}
+
+.details-container > #single-file-details {
+  display: flex;
+  flex: auto;
+  flex-direction: row;
+  width: 100%;
+}
+
+#single-file-details > .details-list {
+  flex: auto;
+  width: 100%;
+}
+
 /* Directory tree at the left. */
 .dialog-navigation-list {
   -webkit-border-end: 1px solid rgba(0, 0, 0, 0.15);
diff --git a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
index 9b9a5da..e000c3d 100644
--- a/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
+++ b/ui/file_manager/file_manager/foreground/js/compiled_resources.gyp
@@ -147,6 +147,7 @@
           './ui/scrollbar.js',
           './ui/search_box.js',
           './ui/share_dialog.js',
+          './ui/single_file_details.js',
           './ui/suggest_apps_dialog.js',
           './main_window_component.js',
           './volume_manager_wrapper.js',
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 811a998..e808134 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -833,12 +833,17 @@
         this.metadataModel_,
         this.volumeManager_,
         this.historyLoader_);
+    var singlePanel = queryRequiredElement('#single-file-details', dom);
+    SingleFileDetailsPanel.decorate(
+        assertInstanceof(singlePanel, HTMLDivElement),
+        this.metadataModel_);
 
     this.addHistoryObserver_();
 
     this.ui_.initAdditionalUI(
         assertInstanceof(table, FileTable),
         assertInstanceof(grid, FileGrid),
+        assertInstanceof(singlePanel, SingleFileDetailsPanel),
         new LocationLine(
             queryRequiredElement('#location-breadcrumbs', dom),
             this.volumeManager_));
diff --git a/ui/file_manager/file_manager/foreground/js/main_scripts.js b/ui/file_manager/file_manager/foreground/js/main_scripts.js
index c7c905ac..7a053ab 100644
--- a/ui/file_manager/file_manager/foreground/js/main_scripts.js
+++ b/ui/file_manager/file_manager/foreground/js/main_scripts.js
@@ -163,6 +163,7 @@
 //<include src="ui/scrollbar.js">
 //<include src="ui/search_box.js">
 //<include src="ui/share_dialog.js">
+//<include src="ui/single_file_details.js">
 //<include src="ui/suggest_apps_dialog.js">
 //<include src="main_window_component.js">
 //<include src="volume_manager_wrapper.js">
diff --git a/ui/file_manager/file_manager/foreground/js/ui/details_container.js b/ui/file_manager/file_manager/foreground/js/ui/details_container.js
index 1d54bad..298f607a 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/details_container.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/details_container.js
@@ -4,13 +4,15 @@
 
 /**
  * @param {!HTMLElement} element
+ * @param {!SingleFileDetailsPanel} singlePanel
  * @param {!Element} splitter
  * @param {!Element} button
  * @param {!FilesToggleRipple} toggleRipple
  * @constructor
  * @struct
  */
-function DetailsContainer(element, splitter, button, toggleRipple) {
+function DetailsContainer(element, singlePanel, splitter, button,
+    toggleRipple) {
   /**
    * Container element.
    * @private {!HTMLElement}
@@ -36,6 +38,12 @@
    */
   this.toggleRipple_ = toggleRipple;
   /**
+   * Details panel for a single file.
+   * @private {!SingleFileDetailsPanel}
+   * @const
+   */
+  this.singlePanel_ = singlePanel;
+  /**
    * @type {boolean}
    */
   this.visible = false;
@@ -43,7 +51,17 @@
 }
 
 DetailsContainer.prototype.onFileSelectionChanged = function(event) {
-  var selection = event.target.selection;
+  var entries = event.target.selection.entries;
+  if (entries.length === 0) {
+    this.singlePanel_.removeAttribute('activated');
+    this.singlePanel_.classList.toggle('activated', false);
+    // TODO(ryoh): make a panel for empty selection
+  } else if (entries.length === 1) {
+    this.singlePanel_.setAttribute('activated', '');
+    this.singlePanel_.onFileSelectionChanged(entries[0]);
+  } else {
+    // TODO(ryoh): make a panel for multiple selection
+  }
 };
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
index 4c04632..4459932a 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -338,10 +338,11 @@
  *
  * @param {!FileTable} table
  * @param {!FileGrid} grid
+ * @param {!SingleFileDetailsPanel} singlePanel
  * @param {!LocationLine} locationLine
  */
 FileManagerUI.prototype.initAdditionalUI = function(
-    table, grid, locationLine) {
+    table, grid, singlePanel, locationLine) {
   // List container.
   this.listContainer = new ListContainer(
       queryRequiredElement('#list-container', this.element), table, grid);
@@ -357,9 +358,10 @@
       this.detailsButton.style.display = 'block';
       var listDetailsSplitter =
           queryRequiredElement('#list-details-splitter', this.element);
-      this.decorateSplitter_(listDetailsSplitter);
+      this.decorateSplitter_(listDetailsSplitter, true);
       this.detailsContainer = new DetailsContainer(
           queryRequiredElement('#details-container', this.element),
+          singlePanel,
           listDetailsSplitter,
           this.detailsButton,
           this.detailsButtonToggleRipple_);
@@ -515,9 +517,11 @@
 /**
  * Decorates the given splitter element.
  * @param {!HTMLElement} splitterElement
+ * @param {boolean=} opt_resizeNextElement
  * @private
  */
-FileManagerUI.prototype.decorateSplitter_ = function(splitterElement) {
+FileManagerUI.prototype.decorateSplitter_ = function(splitterElement,
+    opt_resizeNextElement) {
   var self = this;
   var Splitter = cr.ui.Splitter;
   var customSplitter = cr.ui.define('div');
@@ -542,4 +546,5 @@
   };
 
   customSplitter.decorate(splitterElement);
+  splitterElement.resizeNextElement = !!opt_resizeNextElement;
 };
diff --git a/ui/file_manager/file_manager/foreground/js/ui/single_file_details.js b/ui/file_manager/file_manager/foreground/js/ui/single_file_details.js
new file mode 100644
index 0000000..5329e1c3
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/ui/single_file_details.js
@@ -0,0 +1,130 @@
+// 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.
+
+
+/**
+ * SingleFileDetailsPanel constructor.
+ *
+ * Represents grid for the details panel for a single file in Files app.
+ * @constructor
+ * @extends {HTMLDivElement}
+ */
+function SingleFileDetailsPanel() {
+  throw new Error('Use SingleFileDetailsList.decorate');
+}
+
+/**
+ * Inherits from cr.ui.List.
+ */
+SingleFileDetailsPanel.prototype = {
+  __proto__: HTMLDivElement.prototype,
+  onFileSelectionChanged: function(entry) {
+    this.filename_.textContent = entry.name;
+  }
+};
+
+/**
+ * Decorates an HTML element to be a SingleFileDetailsList.
+ * @param {!HTMLDivElement} self The grid to decorate.
+ * @param {!MetadataModel} metadataModel File system metadata.
+ */
+SingleFileDetailsPanel.decorate = function(self, metadataModel) {
+  self.__proto__ = SingleFileDetailsPanel.prototype;
+  self.metadataModel = metadataModel;
+  /**
+   * Data model of detail infos.
+   * @private {!SingleFileDetailsDataModel}
+   * @const
+   */
+  self.model_ = new SingleFileDetailsDataModel();
+  self.filename_ = assertInstanceof(queryRequiredElement('.filename', self),
+      HTMLDivElement);
+  var list = queryRequiredElement('.details-list', self);
+  SingleFileDetailsList.decorate(list, metadataModel);
+  self.list_ = assertInstanceof(list, SingleFileDetailsList);
+  self.list_.dataModel = self.model_;
+  self.list_.autoExpands = true;
+};
+
+/**
+ * SingleFileDetailsList constructor.
+ *
+ * Represents grid for the details list for a single file in Files app.
+ * @constructor
+ * @extends {cr.ui.List}
+ */
+function SingleFileDetailsList() {
+  throw new Error('Use SingleFileDetailsList.decorate');
+}
+
+/**
+ * Inherits from cr.ui.List.
+ */
+SingleFileDetailsList.prototype = {
+  __proto__: cr.ui.List.prototype,
+  onFileSelectionChanged: function(entry) {
+    console.log(entry);
+  }
+};
+
+/**
+ * Decorates an HTML element to be a SingleFileDetailsList.
+ * @param {!Element} self The grid to decorate.
+ * @param {!MetadataModel} metadataModel File system metadata.
+ */
+SingleFileDetailsList.decorate = function(self, metadataModel) {
+  cr.ui.Grid.decorate(self);
+  self.__proto__ = SingleFileDetailsList.prototype;
+  self.metadataModel_ = metadataModel;
+
+  self.scrollBar_ = new ScrollBar();
+  self.scrollBar_.initialize(self.parentElement, self);
+
+  self.itemConstructor = function(entry) {
+    var item = self.ownerDocument.createElement('li');
+    SingleFileDetailsList.Item.decorate(
+        item,
+        entry,
+        /** @type {FileGrid} */ (self));
+    return item;
+  };
+};
+
+/**
+ * Item for the Grid View.
+ * @constructor
+ * @extends {cr.ui.ListItem}
+ */
+SingleFileDetailsList.Item = function() {
+  throw new Error();
+};
+
+/**
+ * Inherits from cr.ui.DetailsItem.
+ */
+SingleFileDetailsList.Item.prototype.__proto__ = cr.ui.ListItem.prototype;
+
+/**
+ * @param {Element} li List item element.
+ * @param {!Entry} entry File entry.
+ * @param {FileGrid} grid Owner.
+ */
+SingleFileDetailsList.Item.decorate = function(li, entry, grid) {
+  li.__proto__ = SingleFileDetailsList.Item.prototype;
+};
+
+/**
+ * Data model for details panel.
+ *
+ * @constructor
+ * @extends {cr.ui.ArrayDataModel}
+ */
+function SingleFileDetailsDataModel() {
+  cr.ui.ArrayDataModel.call(this, []);
+}
+
+SingleFileDetailsDataModel.prototype = {
+  __proto__: cr.ui.ArrayDataModel.prototype,
+
+};
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index 3639d5a..bc66610 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -411,6 +411,10 @@
       </div>
       <div class="splitter" id="list-details-splitter"></div>
       <div id="details-container" class="details-container">
+        <div id="single-file-details">
+          <div class="filename"></div>
+          <ul class="details-list"></ul>
+        </div>
       </div>
     </div>
     <div class="dialog-footer progressable" tabindex="-1"
diff --git a/ui/file_manager/integration_tests/file_manager/details_panel.js b/ui/file_manager/integration_tests/file_manager/details_panel.js
new file mode 100644
index 0000000..f5fd6f8
--- /dev/null
+++ b/ui/file_manager/integration_tests/file_manager/details_panel.js
@@ -0,0 +1,59 @@
+// 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.
+
+'use strict';
+
+testcase.openDetailsPanel = function() {
+  var appId;
+  StepsRunner.run([
+    function() {
+      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
+    },
+    function(results) {
+      appId = results.windowId;
+      remoteCall.callRemoteTestUtil('fakeEvent',
+                                    appId,
+                                    ['#details-button', 'click'],
+                                    this.next);
+    },
+    function(result) {
+      remoteCall.waitForElement(appId, "#details-container").then(this.next);
+    },
+    function(result) {
+      chrome.test.assertFalse(result.hidden);
+      checkIfNoErrorsOccured(this.next);
+    }
+  ]);
+};
+
+testcase.openDetailsPanelForSingleFile = function() {
+  var appId;
+  StepsRunner.run([
+    function() {
+      setupAndWaitUntilReady(null, RootPath.DOWNLOADS, this.next);
+    },
+    function(results) {
+      appId = results.windowId;
+      remoteCall.callRemoteTestUtil('fakeEvent',
+                                    appId,
+                                    ['#details-button', 'click'],
+                                    this.next);
+    },
+    function(result) {
+      remoteCall.waitForElement(appId, "#details-container").then(this.next);
+    },
+    function(result) {
+      chrome.test.assertFalse(result.hidden);
+      remoteCall.waitForAFile('downloads',
+          'hello.txt').then(this.next);
+    },
+    function(result) {
+      remoteCall.waitForElement(appId, "#single-file-details").then(this.next);
+    },
+    function(result) {
+      chrome.test.assertFalse(result.hidden);
+      checkIfNoErrorsOccured(this.next);
+    }
+  ]);
+};
diff --git a/ui/file_manager/integration_tests/file_manager_test_manifest.json b/ui/file_manager/integration_tests/file_manager_test_manifest.json
index 69ec689..3395de6d 100644
--- a/ui/file_manager/integration_tests/file_manager_test_manifest.json
+++ b/ui/file_manager/integration_tests/file_manager_test_manifest.json
@@ -15,6 +15,7 @@
       "file_manager/copy_between_windows.js",
       "file_manager/create_new_folder.js",
       "file_manager/delete.js",
+      "file_manager/details_panel.js",
       "file_manager/directory_tree_context_menu.js",
       "file_manager/drive_specific.js",
       "file_manager/file_dialog.js",
diff --git a/ui/ozone/platform/cast/OWNERS b/ui/ozone/platform/cast/OWNERS
index 7513d88f..80a937b 100644
--- a/ui/ozone/platform/cast/OWNERS
+++ b/ui/ozone/platform/cast/OWNERS
@@ -1,3 +1,3 @@
-gunsch@chromium.org
+alokp@chromium.org
 halliwell@chromium.org
 lcwu@chromium.org
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index 4d34154f..1d8e611 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -14,6 +14,8 @@
     "wayland_display.h",
     "wayland_object.cc",
     "wayland_object.h",
+    "wayland_pointer.cc",
+    "wayland_pointer.h",
     "wayland_surface_factory.cc",
     "wayland_surface_factory.h",
     "wayland_window.cc",
@@ -25,6 +27,7 @@
     "//skia",
     "//third_party/wayland:wayland_client",
     "//third_party/wayland-protocols:xdg_shell_protocol",
+    "//ui/events",
     "//ui/events/platform",
     "//ui/gfx",
     "//ui/gfx/geometry",
@@ -44,6 +47,7 @@
     "fake_server.h",
     "mock_platform_window_delegate.cc",
     "wayland_display_unittest.cc",
+    "wayland_pointer_unittest.cc",
     "wayland_surface_factory_unittest.cc",
     "wayland_test.cc",
     "wayland_test.h",
@@ -59,4 +63,6 @@
     "//ui/gfx:test_support",
     "//ui/ozone:platform",
   ]
+
+  defines = [ "WL_HIDE_DEPRECATED" ]
 }
diff --git a/ui/ozone/platform/wayland/fake_server.cc b/ui/ozone/platform/wayland/fake_server.cc
index be40689..0465728 100644
--- a/ui/ozone/platform/wayland/fake_server.cc
+++ b/ui/ozone/platform/wayland/fake_server.cc
@@ -17,6 +17,7 @@
 namespace {
 
 const uint32_t kCompositorVersion = 4;
+const uint32_t kSeatVersion = 4;
 const uint32_t kXdgShellVersion = 1;
 
 void DestroyResource(wl_client* client, wl_resource* resource) {
@@ -121,6 +122,33 @@
     &Pong,                // pong
 };
 
+// wl_seat
+
+void GetPointer(wl_client* client, wl_resource* resource, uint32_t id) {
+  auto seat = static_cast<MockSeat*>(wl_resource_get_user_data(resource));
+  wl_resource* pointer_resource = wl_resource_create(
+      client, &wl_pointer_interface, wl_resource_get_version(resource), id);
+  if (!pointer_resource) {
+    wl_client_post_no_memory(client);
+    return;
+  }
+  seat->pointer.reset(new MockPointer(pointer_resource));
+}
+
+const struct wl_seat_interface seat_impl = {
+    &GetPointer,       // get_pointer
+    nullptr,           // get_keyboard
+    nullptr,           // get_touch,
+    &DestroyResource,  // release
+};
+
+// wl_pointer
+
+const struct wl_pointer_interface pointer_impl = {
+    nullptr,           // set_cursor
+    &DestroyResource,  // release
+};
+
 // xdg_surface
 
 void SetTitle(wl_client* client, wl_resource* resource, const char* title) {
@@ -208,6 +236,13 @@
   return static_cast<MockSurface*>(wl_resource_get_user_data(resource));
 }
 
+MockPointer::MockPointer(wl_resource* resource) : ServerObject(resource) {
+  wl_resource_set_implementation(resource, &pointer_impl, this,
+                                 &ServerObject::OnResourceDestroyed);
+}
+
+MockPointer::~MockPointer() {}
+
 void GlobalDeleter::operator()(wl_global* global) {
   wl_global_destroy(global);
 }
@@ -223,7 +258,7 @@
 
 bool Global::Initialize(wl_display* display) {
   global_.reset(wl_global_create(display, interface_, version_, this, &Bind));
-  return global_;
+  return global_ != nullptr;
 }
 
 // static
@@ -260,6 +295,10 @@
   surfaces_.push_back(std::move(surface));
 }
 
+MockSeat::MockSeat() : Global(&wl_seat_interface, &seat_impl, kSeatVersion) {}
+
+MockSeat::~MockSeat() {}
+
 MockXdgShell::MockXdgShell()
     : Global(&xdg_shell_interface, &xdg_shell_impl, kXdgShellVersion) {}
 
@@ -295,6 +334,8 @@
     return false;
   if (!compositor_.Initialize(display_.get()))
     return false;
+  if (!seat_.Initialize(display_.get()))
+    return false;
   if (!xdg_shell_.Initialize(display_.get()))
     return false;
 
diff --git a/ui/ozone/platform/wayland/fake_server.h b/ui/ozone/platform/wayland/fake_server.h
index 5c5b471..a47c8752a 100644
--- a/ui/ozone/platform/wayland/fake_server.h
+++ b/ui/ozone/platform/wayland/fake_server.h
@@ -71,6 +71,15 @@
   DISALLOW_COPY_AND_ASSIGN(MockSurface);
 };
 
+class MockPointer : public ServerObject {
+ public:
+  MockPointer(wl_resource* resource);
+  ~MockPointer() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockPointer);
+};
+
 struct GlobalDeleter {
   void operator()(wl_global* global);
 };
@@ -118,6 +127,17 @@
   DISALLOW_COPY_AND_ASSIGN(MockCompositor);
 };
 
+class MockSeat : public Global {
+ public:
+  MockSeat();
+  ~MockSeat() override;
+
+  scoped_ptr<MockPointer> pointer;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockSeat);
+};
+
 class MockXdgShell : public Global {
  public:
   MockXdgShell();
@@ -158,6 +178,7 @@
     return resource ? T::FromResource(resource) : nullptr;
   }
 
+  MockSeat* seat() { return &seat_; }
   MockXdgShell* xdg_shell() { return &xdg_shell_; }
 
  private:
@@ -178,6 +199,7 @@
   bool paused_ = false;
 
   MockCompositor compositor_;
+  MockSeat seat_;
   MockXdgShell xdg_shell_;
 
   base::MessagePumpLibevent::FileDescriptorWatcher controller_;
diff --git a/ui/ozone/platform/wayland/wayland.gypi b/ui/ozone/platform/wayland/wayland.gypi
index f69b9945..c71b634 100644
--- a/ui/ozone/platform/wayland/wayland.gypi
+++ b/ui/ozone/platform/wayland/wayland.gypi
@@ -28,6 +28,7 @@
         '../../skia/skia.gyp:skia',
         '../../third_party/wayland-protocols/wayland-protocols.gyp:xdg_shell_protocol',
         '../../third_party/wayland/wayland.gyp:wayland_client',
+        '../events/events.gyp:events',
         '../events/platform/events_platform.gyp:events_platform',
       ],
       'sources': [
@@ -39,6 +40,8 @@
         'wayland_display.h',
         'wayland_object.cc',
         'wayland_object.h',
+        'wayland_pointer.cc',
+        'wayland_pointer.h',
         'wayland_surface_factory.cc',
         'wayland_surface_factory.h',
         'wayland_window.cc',
@@ -64,11 +67,15 @@
         '../gfx/gfx.gyp:gfx_test_support',
       ],
       'direct_dependent_settings': {
+        'defines': [
+          'WL_HIDE_DEPRECATED',
+        ],
         'sources': [
           'fake_server.cc',
           'fake_server.h',
           'mock_platform_window_delegate.cc',
           'wayland_display_unittest.cc',
+          'wayland_pointer_unittest.cc',
           'wayland_surface_factory_unittest.cc',
           'wayland_test.cc',
           'wayland_test.h',
diff --git a/ui/ozone/platform/wayland/wayland_display.cc b/ui/ozone/platform/wayland/wayland_display.cc
index fcd841f..a34abe2 100644
--- a/ui/ozone/platform/wayland/wayland_display.cc
+++ b/ui/ozone/platform/wayland/wayland_display.cc
@@ -17,6 +17,7 @@
 namespace ui {
 namespace {
 const uint32_t kMaxCompositorVersion = 4;
+const uint32_t kMaxSeatVersion = 4;
 const uint32_t kMaxShmVersion = 1;
 const uint32_t kMaxXdgShellVersion = 1;
 }  // namespace
@@ -53,6 +54,10 @@
     LOG(ERROR) << "No wl_shm object";
     return false;
   }
+  if (!seat_) {
+    LOG(ERROR) << "No wl_seat object";
+    return false;
+  }
   if (!shell_) {
     LOG(ERROR) << "No xdg_shell object";
     return false;
@@ -109,6 +114,10 @@
   scheduled_flush_ = false;
 }
 
+void WaylandDisplay::DispatchUiEvent(Event* event) {
+  PlatformEventSource::DispatchEvent(event);
+}
+
 void WaylandDisplay::OnFileCanReadWithoutBlocking(int fd) {
   wl_display_dispatch(display_.get());
   for (const auto& window : window_map_)
@@ -123,6 +132,9 @@
                             uint32_t name,
                             const char* interface,
                             uint32_t version) {
+  static const wl_seat_listener seat_listener = {
+      &WaylandDisplay::Capabilities, &WaylandDisplay::Name,
+  };
   static const xdg_shell_listener shell_listener = {
       &WaylandDisplay::Ping,
   };
@@ -138,6 +150,14 @@
         wl::Bind<wl_shm>(registry, name, std::min(version, kMaxShmVersion));
     if (!display->shm_)
       LOG(ERROR) << "Failed to bind to wl_shm global";
+  } else if (!display->seat_ && strcmp(interface, "wl_seat") == 0) {
+    display->seat_ =
+        wl::Bind<wl_seat>(registry, name, std::min(version, kMaxSeatVersion));
+    if (!display->seat_) {
+      LOG(ERROR) << "Failed to bind to wl_seat global";
+      return;
+    }
+    wl_seat_add_listener(display->seat_.get(), &seat_listener, display);
   } else if (!display->shell_ && strcmp(interface, "xdg_shell") == 0) {
     display->shell_ = wl::Bind<xdg_shell>(
         registry, name, std::min(version, kMaxXdgShellVersion));
@@ -161,6 +181,31 @@
 }
 
 // static
+void WaylandDisplay::Capabilities(void* data,
+                                  wl_seat* seat,
+                                  uint32_t capabilities) {
+  WaylandDisplay* display = static_cast<WaylandDisplay*>(data);
+  if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
+    if (!display->pointer_) {
+      wl_pointer* pointer = wl_seat_get_pointer(display->seat_.get());
+      if (!pointer) {
+        LOG(ERROR) << "Failed to get wl_pointer from seat";
+        return;
+      }
+      display->pointer_ = make_scoped_ptr(new WaylandPointer(
+          pointer, base::Bind(&WaylandDisplay::DispatchUiEvent,
+                              base::Unretained(display))));
+    }
+  } else if (display->pointer_) {
+    display->pointer_.reset();
+  }
+  display->ScheduleFlush();
+}
+
+// static
+void WaylandDisplay::Name(void* data, wl_seat* seat, const char* name) {}
+
+// static
 void WaylandDisplay::Ping(void* data, xdg_shell* shell, uint32_t serial) {
   WaylandDisplay* display = static_cast<WaylandDisplay*>(data);
   xdg_shell_pong(shell, serial);
diff --git a/ui/ozone/platform/wayland/wayland_display.h b/ui/ozone/platform/wayland/wayland_display.h
index bfdf5d1..eb72c9cc 100644
--- a/ui/ozone/platform/wayland/wayland_display.h
+++ b/ui/ozone/platform/wayland/wayland_display.h
@@ -11,6 +11,7 @@
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/platform/wayland/wayland_object.h"
+#include "ui/ozone/platform/wayland/wayland_pointer.h"
 
 namespace ui {
 
@@ -39,6 +40,7 @@
 
  private:
   void Flush();
+  void DispatchUiEvent(Event* event);
 
   // PlatformEventSource
   void OnDispatcherListChanged() override;
@@ -55,6 +57,10 @@
                      uint32_t version);
   static void GlobalRemove(void* data, wl_registry* registry, uint32_t name);
 
+  // wl_seat_listener
+  static void Capabilities(void* data, wl_seat* seat, uint32_t capabilities);
+  static void Name(void* data, wl_seat* seat, const char* name);
+
   // xdg_shell_listener
   static void Ping(void* data, xdg_shell* shell, uint32_t serial);
 
@@ -63,9 +69,12 @@
   wl::Object<wl_display> display_;
   wl::Object<wl_registry> registry_;
   wl::Object<wl_compositor> compositor_;
+  wl::Object<wl_seat> seat_;
   wl::Object<wl_shm> shm_;
   wl::Object<xdg_shell> shell_;
 
+  scoped_ptr<WaylandPointer> pointer_;
+
   bool scheduled_flush_ = false;
   bool watching_ = false;
   base::MessagePumpLibevent::FileDescriptorWatcher controller_;
diff --git a/ui/ozone/platform/wayland/wayland_object.cc b/ui/ozone/platform/wayland/wayland_object.cc
index 27a40955..6b7f1e1 100644
--- a/ui/ozone/platform/wayland/wayland_object.cc
+++ b/ui/ozone/platform/wayland/wayland_object.cc
@@ -8,6 +8,23 @@
 #include <xdg-shell-unstable-v5-client-protocol.h>
 
 namespace wl {
+namespace {
+
+void delete_pointer(wl_pointer* pointer) {
+  if (wl_pointer_get_version(pointer) >= WL_POINTER_RELEASE_SINCE_VERSION)
+    wl_pointer_release(pointer);
+  else
+    wl_pointer_destroy(pointer);
+}
+
+void delete_seat(wl_seat* seat) {
+  if (wl_seat_get_version(seat) >= WL_SEAT_RELEASE_SINCE_VERSION)
+    wl_seat_release(seat);
+  else
+    wl_seat_destroy(seat);
+}
+
+}  // namespace
 
 const wl_interface* ObjectTraits<wl_buffer>::interface = &wl_buffer_interface;
 void (*ObjectTraits<wl_buffer>::deleter)(wl_buffer*) = &wl_buffer_destroy;
@@ -20,10 +37,16 @@
 const wl_interface* ObjectTraits<wl_display>::interface = &wl_display_interface;
 void (*ObjectTraits<wl_display>::deleter)(wl_display*) = &wl_display_disconnect;
 
+const wl_interface* ObjectTraits<wl_pointer>::interface = &wl_pointer_interface;
+void (*ObjectTraits<wl_pointer>::deleter)(wl_pointer*) = &delete_pointer;
+
 const wl_interface* ObjectTraits<wl_registry>::interface =
     &wl_registry_interface;
 void (*ObjectTraits<wl_registry>::deleter)(wl_registry*) = &wl_registry_destroy;
 
+const wl_interface* ObjectTraits<wl_seat>::interface = &wl_seat_interface;
+void (*ObjectTraits<wl_seat>::deleter)(wl_seat*) = &delete_seat;
+
 const wl_interface* ObjectTraits<wl_shm>::interface = &wl_shm_interface;
 void (*ObjectTraits<wl_shm>::deleter)(wl_shm*) = &wl_shm_destroy;
 
diff --git a/ui/ozone/platform/wayland/wayland_object.h b/ui/ozone/platform/wayland/wayland_object.h
index f0850aac..f5324f9 100644
--- a/ui/ozone/platform/wayland/wayland_object.h
+++ b/ui/ozone/platform/wayland/wayland_object.h
@@ -11,7 +11,9 @@
 
 struct wl_buffer;
 struct wl_compositor;
+struct wl_pointer;
 struct wl_registry;
+struct wl_seat;
 struct wl_shm;
 struct wl_shm_pool;
 struct wl_surface;
@@ -42,12 +44,24 @@
 };
 
 template <>
+struct ObjectTraits<wl_pointer> {
+  static const wl_interface* interface;
+  static void (*deleter)(wl_pointer*);
+};
+
+template <>
 struct ObjectTraits<wl_registry> {
   static const wl_interface* interface;
   static void (*deleter)(wl_registry*);
 };
 
 template <>
+struct ObjectTraits<wl_seat> {
+  static const wl_interface* interface;
+  static void (*deleter)(wl_seat*);
+};
+
+template <>
 struct ObjectTraits<wl_shm> {
   static const wl_interface* interface;
   static void (*deleter)(wl_shm*);
diff --git a/ui/ozone/platform/wayland/wayland_pointer.cc b/ui/ozone/platform/wayland/wayland_pointer.cc
new file mode 100644
index 0000000..7cdb4fbb
--- /dev/null
+++ b/ui/ozone/platform/wayland/wayland_pointer.cc
@@ -0,0 +1,143 @@
+// 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 "ui/ozone/platform/wayland/wayland_pointer.h"
+
+#include <linux/input.h>
+#include <wayland-client.h>
+
+#include "ui/events/event.h"
+#include "ui/ozone/platform/wayland/wayland_window.h"
+
+// TODO(forney): Handle version 5 of wl_pointer.
+
+namespace ui {
+
+WaylandPointer::WaylandPointer(wl_pointer* pointer,
+                               const EventDispatchCallback& callback)
+    : obj_(pointer), callback_(callback) {
+  static const wl_pointer_listener listener = {
+      &WaylandPointer::Enter,  &WaylandPointer::Leave, &WaylandPointer::Motion,
+      &WaylandPointer::Button, &WaylandPointer::Axis,
+  };
+
+  wl_pointer_add_listener(obj_.get(), &listener, this);
+}
+
+WaylandPointer::~WaylandPointer() {}
+
+// static
+void WaylandPointer::Enter(void* data,
+                           wl_pointer* obj,
+                           uint32_t serial,
+                           wl_surface* surface,
+                           wl_fixed_t surface_x,
+                           wl_fixed_t surface_y) {
+  WaylandPointer* pointer = static_cast<WaylandPointer*>(data);
+  pointer->location_.SetPoint(wl_fixed_to_double(surface_x),
+                              wl_fixed_to_double(surface_y));
+  if (surface)
+    WaylandWindow::FromSurface(surface)->set_pointer_focus(true);
+}
+
+// static
+void WaylandPointer::Leave(void* data,
+                           wl_pointer* obj,
+                           uint32_t serial,
+                           wl_surface* surface) {
+  if (surface)
+    WaylandWindow::FromSurface(surface)->set_pointer_focus(false);
+}
+
+// static
+void WaylandPointer::Motion(void* data,
+                            wl_pointer* obj,
+                            uint32_t time,
+                            wl_fixed_t surface_x,
+                            wl_fixed_t surface_y) {
+  WaylandPointer* pointer = static_cast<WaylandPointer*>(data);
+  pointer->location_.SetPoint(wl_fixed_to_double(surface_x),
+                              wl_fixed_to_double(surface_y));
+  MouseEvent event(ET_MOUSE_MOVED, gfx::Point(), gfx::Point(),
+                   base::TimeDelta::FromMilliseconds(time), pointer->flags_, 0);
+  event.set_location_f(pointer->location_);
+  event.set_root_location_f(pointer->location_);
+  pointer->callback_.Run(&event);
+}
+
+// static
+void WaylandPointer::Button(void* data,
+                            wl_pointer* obj,
+                            uint32_t serial,
+                            uint32_t time,
+                            uint32_t button,
+                            uint32_t state) {
+  WaylandPointer* pointer = static_cast<WaylandPointer*>(data);
+  int flag;
+  switch (button) {
+    case BTN_LEFT:
+      flag = EF_LEFT_MOUSE_BUTTON;
+      break;
+    case BTN_MIDDLE:
+      flag = EF_MIDDLE_MOUSE_BUTTON;
+      break;
+    case BTN_RIGHT:
+      flag = EF_RIGHT_MOUSE_BUTTON;
+      break;
+    case BTN_BACK:
+      flag = EF_BACK_MOUSE_BUTTON;
+      break;
+    case BTN_FORWARD:
+      flag = EF_FORWARD_MOUSE_BUTTON;
+      break;
+    default:
+      return;
+  }
+  int flags = pointer->flags_ | flag;
+  EventType type;
+  if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
+    type = ET_MOUSE_PRESSED;
+    pointer->flags_ |= flag;
+  } else {
+    type = ET_MOUSE_RELEASED;
+    pointer->flags_ &= ~flag;
+  }
+  MouseEvent event(type, gfx::Point(), gfx::Point(),
+                   base::TimeDelta::FromMilliseconds(time), flags, flag);
+  event.set_location_f(pointer->location_);
+  event.set_root_location_f(pointer->location_);
+  pointer->callback_.Run(&event);
+}
+
+// static
+void WaylandPointer::Axis(void* data,
+                          wl_pointer* obj,
+                          uint32_t time,
+                          uint32_t axis,
+                          wl_fixed_t value) {
+  static const double kAxisValueScale = 10.0;
+  WaylandPointer* pointer = static_cast<WaylandPointer*>(data);
+  gfx::Vector2d offset;
+  // Wayland compositors send axis events with values in the surface coordinate
+  // space. They send a value of 10 per mouse wheel click by convention, so
+  // clients (e.g. GTK+) typically scale down by this amount to convert to
+  // discrete step coordinates. wl_pointer version 5 improves the situation by
+  // adding axis sources and discrete axis events.
+  if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
+    offset.set_y(-wl_fixed_to_double(value) / kAxisValueScale *
+                 MouseWheelEvent::kWheelDelta);
+  else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
+    offset.set_x(wl_fixed_to_double(value) / kAxisValueScale *
+                 MouseWheelEvent::kWheelDelta);
+  else
+    return;
+  MouseWheelEvent event(offset, gfx::Point(), gfx::Point(),
+                        base::TimeDelta::FromMilliseconds(time),
+                        pointer->flags_, 0);
+  event.set_location_f(pointer->location_);
+  event.set_root_location_f(pointer->location_);
+  pointer->callback_.Run(&event);
+}
+
+}  // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_pointer.h b/ui/ozone/platform/wayland/wayland_pointer.h
new file mode 100644
index 0000000..bee75a9
--- /dev/null
+++ b/ui/ozone/platform/wayland/wayland_pointer.h
@@ -0,0 +1,56 @@
+// 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_OZONE_PLATFORM_WAYLAND_WAYLAND_POINTER_H_
+#define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_POINTER_H_
+
+#include "ui/events/ozone/evdev/event_dispatch_callback.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/ozone/platform/wayland/wayland_object.h"
+
+namespace ui {
+
+class WaylandPointer {
+ public:
+  WaylandPointer(wl_pointer* pointer, const EventDispatchCallback& callback);
+  virtual ~WaylandPointer();
+
+ private:
+  // wl_pointer_listener
+  static void Enter(void* data,
+                    wl_pointer* obj,
+                    uint32_t serial,
+                    wl_surface* surface,
+                    wl_fixed_t surface_x,
+                    wl_fixed_t surface_y);
+  static void Leave(void* data,
+                    wl_pointer* obj,
+                    uint32_t serial,
+                    wl_surface* surface);
+  static void Motion(void* data,
+                     wl_pointer* obj,
+                     uint32_t time,
+                     wl_fixed_t surface_x,
+                     wl_fixed_t surface_y);
+  static void Button(void* data,
+                     wl_pointer* obj,
+                     uint32_t serial,
+                     uint32_t time,
+                     uint32_t button,
+                     uint32_t state);
+  static void Axis(void* data,
+                   wl_pointer* obj,
+                   uint32_t time,
+                   uint32_t axis,
+                   wl_fixed_t value);
+
+  wl::Object<wl_pointer> obj_;
+  EventDispatchCallback callback_;
+  gfx::PointF location_;
+  int flags_ = 0;
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_WAYLAND_WAYLAND_POINTER_H_
diff --git a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc
new file mode 100644
index 0000000..71e28be
--- /dev/null
+++ b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc
@@ -0,0 +1,232 @@
+// 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 <linux/input.h>
+#include <wayland-server.h>
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/event.h"
+#include "ui/ozone/platform/wayland/fake_server.h"
+#include "ui/ozone/platform/wayland/mock_platform_window_delegate.h"
+#include "ui/ozone/platform/wayland/wayland_test.h"
+#include "ui/ozone/platform/wayland/wayland_window.h"
+
+using ::testing::SaveArg;
+using ::testing::_;
+
+namespace ui {
+
+class WaylandPointerTest : public WaylandTest {
+ public:
+  WaylandPointerTest() {}
+
+  void SetUp() override {
+    WaylandTest::SetUp();
+
+    wl_seat_send_capabilities(server.seat()->resource(),
+                              WL_SEAT_CAPABILITY_POINTER);
+
+    Sync();
+
+    pointer = server.seat()->pointer.get();
+    ASSERT_TRUE(pointer);
+  }
+
+ protected:
+  wl::MockPointer* pointer;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WaylandPointerTest);
+};
+
+TEST_F(WaylandPointerTest, Leave) {
+  MockPlatformWindowDelegate other_delegate;
+  WaylandWindow other_window(&other_delegate, &display,
+                             gfx::Rect(0, 0, 10, 10));
+  gfx::AcceleratedWidget other_widget = gfx::kNullAcceleratedWidget;
+  EXPECT_CALL(other_delegate, OnAcceleratedWidgetAvailable(_, _))
+      .WillOnce(SaveArg<0>(&other_widget));
+  ASSERT_TRUE(other_window.Initialize());
+  ASSERT_NE(other_widget, gfx::kNullAcceleratedWidget);
+
+  Sync();
+
+  wl::MockSurface* other_surface =
+      server.GetObject<wl::MockSurface>(other_widget);
+  ASSERT_TRUE(other_surface);
+
+  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(), 0, 0);
+  wl_pointer_send_leave(pointer->resource(), 2, surface->resource());
+  wl_pointer_send_enter(pointer->resource(), 3, other_surface->resource(), 0,
+                        0);
+  wl_pointer_send_button(pointer->resource(), 4, 1004, BTN_LEFT,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+  EXPECT_CALL(delegate, DispatchEvent(_)).Times(0);
+
+  // Do an extra Sync() here so that we process the second enter event before we
+  // destroy |other_window|.
+  Sync();
+}
+
+ACTION_P(CloneEvent, ptr) {
+  *ptr = Event::Clone(*arg0);
+}
+
+TEST_F(WaylandPointerTest, Motion) {
+  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(), 0, 0);
+  wl_pointer_send_motion(pointer->resource(), 1002, wl_fixed_from_double(10.75),
+                         wl_fixed_from_double(20.375));
+
+  scoped_ptr<Event> event;
+  EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+
+  Sync();
+
+  ASSERT_TRUE(event);
+  ASSERT_TRUE(event->IsMouseEvent());
+  auto mouse_event = static_cast<MouseEvent*>(event.get());
+  EXPECT_EQ(ET_MOUSE_MOVED, mouse_event->type());
+  EXPECT_EQ(0, mouse_event->button_flags());
+  EXPECT_EQ(0, mouse_event->changed_button_flags());
+  // TODO(forney): Once crbug.com/337827 is solved, compare with the fractional
+  // coordinates sent above.
+  EXPECT_EQ(gfx::PointF(10, 20), mouse_event->location_f());
+  EXPECT_EQ(gfx::PointF(10, 20), mouse_event->root_location_f());
+}
+
+TEST_F(WaylandPointerTest, MotionDragged) {
+  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(), 0, 0);
+  wl_pointer_send_button(pointer->resource(), 2, 1002, BTN_MIDDLE,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+
+  Sync();
+
+  scoped_ptr<Event> event;
+  EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+  wl_pointer_send_motion(pointer->resource(), 1003, wl_fixed_from_int(400),
+                         wl_fixed_from_int(500));
+
+  Sync();
+
+  ASSERT_TRUE(event);
+  ASSERT_TRUE(event->IsMouseEvent());
+  auto mouse_event = static_cast<MouseEvent*>(event.get());
+  EXPECT_EQ(ET_MOUSE_DRAGGED, mouse_event->type());
+  EXPECT_EQ(EF_MIDDLE_MOUSE_BUTTON, mouse_event->button_flags());
+  EXPECT_EQ(0, mouse_event->changed_button_flags());
+  EXPECT_EQ(gfx::PointF(400, 500), mouse_event->location_f());
+  EXPECT_EQ(gfx::PointF(400, 500), mouse_event->root_location_f());
+}
+
+TEST_F(WaylandPointerTest, ButtonPress) {
+  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(),
+                        wl_fixed_from_int(200), wl_fixed_from_int(150));
+  wl_pointer_send_button(pointer->resource(), 2, 1002, BTN_RIGHT,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+
+  Sync();
+
+  scoped_ptr<Event> event;
+  EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+  wl_pointer_send_button(pointer->resource(), 3, 1003, BTN_LEFT,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+
+  Sync();
+
+  ASSERT_TRUE(event);
+  ASSERT_TRUE(event->IsMouseEvent());
+  auto mouse_event = static_cast<MouseEvent*>(event.get());
+  EXPECT_EQ(ET_MOUSE_PRESSED, mouse_event->type());
+  EXPECT_EQ(EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON,
+            mouse_event->button_flags());
+  EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, mouse_event->changed_button_flags());
+  EXPECT_EQ(gfx::PointF(200, 150), mouse_event->location_f());
+  EXPECT_EQ(gfx::PointF(200, 150), mouse_event->root_location_f());
+}
+
+TEST_F(WaylandPointerTest, ButtonRelease) {
+  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(),
+                        wl_fixed_from_int(50), wl_fixed_from_int(50));
+  wl_pointer_send_button(pointer->resource(), 2, 1002, BTN_BACK,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+  wl_pointer_send_button(pointer->resource(), 3, 1003, BTN_LEFT,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+
+  Sync();
+
+  scoped_ptr<Event> event;
+  EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+  wl_pointer_send_button(pointer->resource(), 4, 1004, BTN_LEFT,
+                         WL_POINTER_BUTTON_STATE_RELEASED);
+
+  Sync();
+
+  ASSERT_TRUE(event);
+  ASSERT_TRUE(event->IsMouseEvent());
+  auto mouse_event = static_cast<MouseEvent*>(event.get());
+  EXPECT_EQ(ET_MOUSE_RELEASED, mouse_event->type());
+  EXPECT_EQ(EF_LEFT_MOUSE_BUTTON | EF_BACK_MOUSE_BUTTON,
+            mouse_event->button_flags());
+  EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, mouse_event->changed_button_flags());
+  EXPECT_EQ(gfx::PointF(50, 50), mouse_event->location_f());
+  EXPECT_EQ(gfx::PointF(50, 50), mouse_event->root_location_f());
+}
+
+TEST_F(WaylandPointerTest, AxisVertical) {
+  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(),
+                        wl_fixed_from_int(0), wl_fixed_from_int(0));
+  wl_pointer_send_button(pointer->resource(), 2, 1002, BTN_RIGHT,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+
+  Sync();
+
+  scoped_ptr<Event> event;
+  EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+  // Wayland servers typically send a value of 10 per mouse wheel click.
+  wl_pointer_send_axis(pointer->resource(), 1003,
+                       WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(20));
+
+  Sync();
+
+  ASSERT_TRUE(event);
+  ASSERT_TRUE(event->IsMouseWheelEvent());
+  auto mouse_wheel_event = static_cast<MouseWheelEvent*>(event.get());
+  EXPECT_EQ(gfx::Vector2d(0, -2 * MouseWheelEvent::kWheelDelta),
+            mouse_wheel_event->offset());
+  EXPECT_EQ(EF_RIGHT_MOUSE_BUTTON, mouse_wheel_event->button_flags());
+  EXPECT_EQ(0, mouse_wheel_event->changed_button_flags());
+  EXPECT_EQ(gfx::PointF(), mouse_wheel_event->location_f());
+  EXPECT_EQ(gfx::PointF(), mouse_wheel_event->root_location_f());
+}
+
+TEST_F(WaylandPointerTest, AxisHorizontal) {
+  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(),
+                        wl_fixed_from_int(50), wl_fixed_from_int(75));
+  wl_pointer_send_button(pointer->resource(), 2, 1002, BTN_LEFT,
+                         WL_POINTER_BUTTON_STATE_PRESSED);
+
+  Sync();
+
+  scoped_ptr<Event> event;
+  EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+  // Wayland servers typically send a value of 10 per mouse wheel click.
+  wl_pointer_send_axis(pointer->resource(), 1003,
+                       WL_POINTER_AXIS_HORIZONTAL_SCROLL,
+                       wl_fixed_from_int(10));
+
+  Sync();
+
+  ASSERT_TRUE(event);
+  ASSERT_TRUE(event->IsMouseWheelEvent());
+  auto mouse_wheel_event = static_cast<MouseWheelEvent*>(event.get());
+  EXPECT_EQ(gfx::Vector2d(MouseWheelEvent::kWheelDelta, 0),
+            mouse_wheel_event->offset());
+  EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, mouse_wheel_event->button_flags());
+  EXPECT_EQ(0, mouse_wheel_event->changed_button_flags());
+  EXPECT_EQ(gfx::PointF(50, 75), mouse_wheel_event->location_f());
+  EXPECT_EQ(gfx::PointF(50, 75), mouse_wheel_event->root_location_f());
+}
+
+}  // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_test.cc b/ui/ozone/platform/wayland/wayland_test.cc
index 3d3fec7b..b5aea4d 100644
--- a/ui/ozone/platform/wayland/wayland_test.cc
+++ b/ui/ozone/platform/wayland/wayland_test.cc
@@ -19,7 +19,6 @@
 void WaylandTest::SetUp() {
   ASSERT_TRUE(server.Start());
   ASSERT_TRUE(display.Initialize());
-  display.StartProcessingEvents();
   EXPECT_CALL(delegate, OnAcceleratedWidgetAvailable(_, _))
       .WillOnce(SaveArg<0>(&widget));
   ASSERT_TRUE(window.Initialize());
diff --git a/ui/ozone/platform/wayland/wayland_test.h b/ui/ozone/platform/wayland/wayland_test.h
index 59a56a9..9a124129 100644
--- a/ui/ozone/platform/wayland/wayland_test.h
+++ b/ui/ozone/platform/wayland/wayland_test.h
@@ -27,10 +27,10 @@
 
  private:
   bool initialized = false;
-  wl::FakeServer server;
   base::MessageLoopForUI message_loop;
 
  protected:
+  wl::FakeServer server;
   wl::MockSurface* surface;
 
   WaylandDisplay display;
diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc
index b64f0bc..46c639a 100644
--- a/ui/ozone/platform/wayland/wayland_window.cc
+++ b/ui/ozone/platform/wayland/wayland_window.cc
@@ -7,6 +7,8 @@
 #include <xdg-shell-unstable-v5-client-protocol.h>
 
 #include "base/strings/utf_string_conversions.h"
+#include "ui/events/event.h"
+#include "ui/events/ozone/events_ozone.h"
 #include "ui/ozone/platform/wayland/wayland_display.h"
 #include "ui/platform_window/platform_window_delegate.h"
 
@@ -19,10 +21,17 @@
 
 WaylandWindow::~WaylandWindow() {
   if (xdg_surface_) {
+    PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
     display_->RemoveWindow(surface_.id());
   }
 }
 
+// static
+WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) {
+  return static_cast<WaylandWindow*>(
+      wl_proxy_get_user_data(reinterpret_cast<wl_proxy*>(surface)));
+}
+
 bool WaylandWindow::Initialize() {
   static const xdg_surface_listener xdg_surface_listener = {
       &WaylandWindow::Configure, &WaylandWindow::Close,
@@ -44,6 +53,7 @@
   display_->ScheduleFlush();
 
   display_->AddWindow(surface_.id(), this);
+  PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
   delegate_->OnAcceleratedWidgetAvailable(surface_.id(), 1.f);
 
   return true;
@@ -134,6 +144,21 @@
   return nullptr;
 }
 
+bool WaylandWindow::CanDispatchEvent(const PlatformEvent& native_event) {
+  Event* event = static_cast<Event*>(native_event);
+  if (event->IsMouseEvent())
+    return has_pointer_focus_;
+  return false;
+}
+
+uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
+  DispatchEventFromNativeUiEvent(
+      native_event, base::Bind(&PlatformWindowDelegate::DispatchEvent,
+                               base::Unretained(delegate_)));
+  return POST_DISPATCH_STOP_PROPAGATION;
+}
+
+// static
 void WaylandWindow::Configure(void* data,
                               xdg_surface* obj,
                               int32_t width,
@@ -150,6 +175,7 @@
   window->pending_configure_serial_ = serial;
 }
 
+// static
 void WaylandWindow::Close(void* data, xdg_surface* obj) {
   NOTIMPLEMENTED();
 }
diff --git a/ui/ozone/platform/wayland/wayland_window.h b/ui/ozone/platform/wayland/wayland_window.h
index 05dba79..450df55d 100644
--- a/ui/ozone/platform/wayland/wayland_window.h
+++ b/ui/ozone/platform/wayland/wayland_window.h
@@ -5,6 +5,7 @@
 #ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_WINDOW_H_
 #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_WINDOW_H_
 
+#include "ui/events/platform/platform_event_dispatcher.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/platform/wayland/wayland_object.h"
@@ -14,13 +15,15 @@
 
 class WaylandDisplay;
 
-class WaylandWindow : public PlatformWindow {
+class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
  public:
   WaylandWindow(PlatformWindowDelegate* delegate,
                 WaylandDisplay* display,
                 const gfx::Rect& bounds);
   ~WaylandWindow() override;
 
+  static WaylandWindow* FromSurface(wl_surface* surface);
+
   bool Initialize();
 
   wl_surface* surface() { return surface_.get(); }
@@ -29,6 +32,9 @@
   // be called after processing all pending events in the wayland connection.
   void ApplyPendingBounds();
 
+  // Set whether this window has pointer focus and should dispatch mouse events.
+  void set_pointer_focus(bool focus) { has_pointer_focus_ = focus; }
+
   // PlatformWindow
   void Show() override;
   void Hide() override;
@@ -47,6 +53,10 @@
   void ConfineCursorToBounds(const gfx::Rect& bounds) override;
   PlatformImeController* GetPlatformImeController() override;
 
+  // PlatformEventDispatcher
+  bool CanDispatchEvent(const PlatformEvent& event) override;
+  uint32_t DispatchEvent(const PlatformEvent& event) override;
+
   // xdg_surface_listener
   static void Configure(void* data,
                         xdg_surface* obj,
@@ -66,6 +76,7 @@
   gfx::Rect bounds_;
   gfx::Rect pending_bounds_;
   uint32_t pending_configure_serial_;
+  bool has_pointer_focus_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(WaylandWindow);
 };
diff --git a/ui/ozone/platform/wayland/wayland_window_unittest.cc b/ui/ozone/platform/wayland/wayland_window_unittest.cc
index 1b1cad7..5fd1dc337 100644
--- a/ui/ozone/platform/wayland/wayland_window_unittest.cc
+++ b/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/event.h"
 #include "ui/ozone/platform/wayland/fake_server.h"
 #include "ui/ozone/platform/wayland/mock_platform_window_delegate.h"
 #include "ui/ozone/platform/wayland/wayland_test.h"
@@ -24,7 +25,13 @@
 
 class WaylandWindowTest : public WaylandTest {
  public:
-  WaylandWindowTest() {}
+  WaylandWindowTest()
+      : test_mouse_event(ET_MOUSE_PRESSED,
+                         gfx::Point(10, 15),
+                         gfx::Point(10, 15),
+                         base::TimeDelta::FromSeconds(123456),
+                         EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON,
+                         EF_LEFT_MOUSE_BUTTON) {}
 
   void SetUp() override {
     WaylandTest::SetUp();
@@ -36,6 +43,8 @@
  protected:
   wl::MockXdgSurface* xdg_surface;
 
+  MouseEvent test_mouse_event;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(WaylandWindowTest);
 };
@@ -60,6 +69,39 @@
   window.Restore();
 }
 
+TEST_F(WaylandWindowTest, CanDispatchMouseEventDefault) {
+  EXPECT_FALSE(window.CanDispatchEvent(&test_mouse_event));
+}
+
+TEST_F(WaylandWindowTest, CanDispatchMouseEventFocus) {
+  window.set_pointer_focus(true);
+  EXPECT_TRUE(window.CanDispatchEvent(&test_mouse_event));
+}
+
+TEST_F(WaylandWindowTest, CanDispatchMouseEventUnfocus) {
+  window.set_pointer_focus(false);
+  EXPECT_FALSE(window.CanDispatchEvent(&test_mouse_event));
+}
+
+ACTION_P(CloneEvent, ptr) {
+  *ptr = Event::Clone(*arg0);
+}
+
+TEST_F(WaylandWindowTest, DispatchEvent) {
+  scoped_ptr<Event> event;
+  EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+  window.DispatchEvent(&test_mouse_event);
+  ASSERT_TRUE(event);
+  ASSERT_TRUE(event->IsMouseEvent());
+  auto mouse_event = static_cast<MouseEvent*>(event.get());
+  EXPECT_EQ(mouse_event->location_f(), test_mouse_event.location_f());
+  EXPECT_EQ(mouse_event->root_location_f(), test_mouse_event.root_location_f());
+  EXPECT_EQ(mouse_event->time_stamp(), test_mouse_event.time_stamp());
+  EXPECT_EQ(mouse_event->button_flags(), test_mouse_event.button_flags());
+  EXPECT_EQ(mouse_event->changed_button_flags(),
+            test_mouse_event.changed_button_flags());
+}
+
 TEST_F(WaylandWindowTest, ConfigureEvent) {
   wl_array states;
   wl_array_init(&states);
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc
index cdd53c2..90d58d9 100644
--- a/ui/views/controls/menu/menu_controller_unittest.cc
+++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -22,6 +22,7 @@
 #include "ui/views/controls/menu/menu_delegate.h"
 #include "ui/views/controls/menu/menu_item_view.h"
 #include "ui/views/controls/menu/menu_message_loop.h"
+#include "ui/views/controls/menu/menu_scroll_view_container.h"
 #include "ui/views/controls/menu/submenu_view.h"
 #include "ui/views/test/views_test_base.h"
 
@@ -407,8 +408,9 @@
     menu_controller_->SetSelectionOnPointerDown(source, event);
   }
 
-  void ProcessMouseMoved(SubmenuView* source,
-                         const ui::MouseEvent& event) {
+  // Note that coordinates of events passed to MenuController must be in that of
+  // the MenuScrollViewContainer.
+  void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) {
     menu_controller_->OnMouseMoved(source, event);
   }
 
@@ -764,10 +766,11 @@
   EXPECT_TRUE(button3->IsHotTracked());
 
   // Move a mouse to hot track the |button1|.
+  SubmenuView* sub_menu = menu_item()->GetSubmenu();
   gfx::Point location(button1->GetBoundsInScreen().CenterPoint());
+  View::ConvertPointFromScreen(sub_menu->GetScrollViewContainer(), &location);
   ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location,
                        ui::EventTimeForNow(), 0, 0);
-  SubmenuView* sub_menu = menu_item()->GetSubmenu();
   ProcessMouseMoved(sub_menu, event);
 
   // Incrementing selection should move hot tracking to the second button (next